1package imapserver
2
3import (
4 "bufio"
5 "io"
6 "net"
7)
8
9// prefixConn is a net.Conn with a buffer from which the first reads are satisfied.
10// used for STARTTLS where already did a buffered read of initial TLS data.
11type prefixConn struct {
12 prefix []byte
13 net.Conn
14}
15
16func (c *prefixConn) Read(buf []byte) (int, error) {
17 if len(c.prefix) > 0 {
18 n := len(buf)
19 if n > len(c.prefix) {
20 n = len(c.prefix)
21 }
22 copy(buf[:n], c.prefix[:n])
23 c.prefix = c.prefix[n:]
24 if len(c.prefix) == 0 {
25 c.prefix = nil
26 }
27 return n, nil
28 }
29 return c.Conn.Read(buf)
30}
31
32// xprefixConn returns either the original net.Conn passed as parameter, or returns
33// a *prefixConn returning the buffered data available in br followed data from the
34// net.Conn passed in.
35func xprefixConn(c net.Conn, br *bufio.Reader) net.Conn {
36 n := br.Buffered()
37 if n == 0 {
38 return c
39 }
40
41 buf := make([]byte, n)
42 _, err := io.ReadFull(c, buf)
43 xcheckf(err, "get buffered data")
44 return &prefixConn{buf, c}
45}
46