-
Notifications
You must be signed in to change notification settings - Fork 10
/
response.go
98 lines (83 loc) · 2.28 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package imapsrv
import (
"bufio"
"net/textproto"
)
// response represents an IMAP response
type response struct {
// The tag of the command that this is the response for
tag string
// The machine readable condition
condition string
// A human readable message
message string
// Untagged output lines
untagged []string
// Should the connection be closed after the response has been sent?
closeConnection bool
// bufInReplacement is not-null if all incoming traffic should be read from this instead
bufReplacement *textproto.Conn
}
// createResponse creates a response
func createResponse(tag string, condition string, message string) *response {
return &response{
tag: tag,
condition: condition,
message: message,
untagged: make([]string, 0, 4),
}
}
// ok creatse a OK response
func ok(tag string, message string) *response {
return createResponse(tag, "OK", message)
}
// bad creates a BAD response
func bad(tag string, message string) *response {
return createResponse(tag, "BAD", message)
}
// no creates a NO response
func no(tag string, message string) *response {
return createResponse(tag, "NO", message)
}
// empty creates an empty response
func empty() *response {
return &response{}
}
// fatalResponse writes an untagged fatal response (BYE)
func fatalResponse(w *bufio.Writer, err error) {
resp := createResponse("*", "BYE", err.Error())
resp.closeConnection = true
resp.write(w)
}
// extra adds an untagged line to a response
func (r *response) extra(line string) *response {
r.untagged = append(r.untagged, line)
return r
}
// shouldClose marks that a response should close the connection
func (r *response) shouldClose() *response {
r.closeConnection = true
return r
}
// replaceBuffers sets two possible buffers that need replacement
func (r *response) replaceBuffers(replacement *textproto.Conn) *response {
r.bufReplacement = replacement
return r
}
// write will write a response to the given writer
func (r *response) write(w *bufio.Writer) error {
// Write untagged lines
for _, line := range r.untagged {
_, err := w.WriteString("* " + line + "\r\n")
if err != nil {
return err
}
}
_, err := w.WriteString(r.tag + " " + r.condition + " " + r.message + "\r\n")
if err != nil {
return err
}
// Flush the response
w.Flush()
return nil
}