|
1 | 1 | package client |
2 | 2 |
|
3 | 3 | import ( |
| 4 | +"compress/flate" |
4 | 5 | "errors" |
| 6 | +"net" |
5 | 7 |
|
6 | 8 | "github.com/emersion/go-imap" |
7 | 9 | "github.com/emersion/go-imap/commands" |
| 10 | +"github.com/emersion/go-imap/internal" |
8 | 11 | ) |
9 | 12 |
|
10 | 13 | // ErrAlreadyLoggedOut is returned if Logout is called when the client is |
11 | 14 | // already logged out. |
12 | 15 | var ErrAlreadyLoggedOut = errors.New("Already logged out") |
13 | 16 |
|
| 17 | +// ErrAlreadyCompress is returned by Client.Compress when compression has |
| 18 | +// already been enabled on the client. |
| 19 | +var ErrAlreadyCompressed = errors.New("COMPRESS is already enabled") |
| 20 | + |
14 | 21 | // Capability requests a listing of capabilities that the server supports. |
15 | 22 | // Capabilities are often returned by the server with the greeting or with the |
16 | 23 | // STARTTLS and LOGIN responses, so usually explicitly requesting capabilities |
@@ -86,3 +93,35 @@ func (c *Client) Logout() error { |
86 | 93 | } |
87 | 94 | return nil |
88 | 95 | } |
| 96 | + |
| 97 | +// Compress instructs the server to use the named compression mechanism for all |
| 98 | +// commands and/or responses. |
| 99 | +func (c *Client) Compress(mech string) error { |
| 100 | +if c.isCompressed { |
| 101 | +return ErrAlreadyCompressed |
| 102 | +} |
| 103 | + |
| 104 | +if ok, err := c.Support("COMPRESS=" + mech); !ok || err != nil { |
| 105 | +return imap.CompressUnsupportedError{Mechanism: mech} |
| 106 | +} |
| 107 | +if mech != imap.CompressDeflate { |
| 108 | +return imap.CompressUnsupportedError{Mechanism: mech} |
| 109 | +} |
| 110 | + |
| 111 | +cmd := &commands.Compress{Mechanism: mech} |
| 112 | +err := c.Upgrade(func(conn net.Conn) (net.Conn, error) { |
| 113 | +if status, err := c.Execute(cmd, nil); err != nil { |
| 114 | +return nil, err |
| 115 | +} else if err := status.Err(); err != nil { |
| 116 | +return nil, err |
| 117 | +} |
| 118 | + |
| 119 | +return internal.CreateDeflateConn(conn, flate.DefaultCompression) |
| 120 | +}) |
| 121 | +if err != nil { |
| 122 | +return err |
| 123 | +} |
| 124 | + |
| 125 | +c.isCompressed = true |
| 126 | +return nil |
| 127 | +} |
0 commit comments