aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/emersion/go-imap/responses/fetch.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/emersion/go-imap/responses/fetch.go')
-rw-r--r--vendor/github.com/emersion/go-imap/responses/fetch.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/vendor/github.com/emersion/go-imap/responses/fetch.go b/vendor/github.com/emersion/go-imap/responses/fetch.go
new file mode 100644
index 0000000..691ebcb
--- /dev/null
+++ b/vendor/github.com/emersion/go-imap/responses/fetch.go
@@ -0,0 +1,70 @@
+package responses
+
+import (
+ "github.com/emersion/go-imap"
+)
+
+const fetchName = "FETCH"
+
+// A FETCH response.
+// See RFC 3501 section 7.4.2
+type Fetch struct {
+ Messages chan *imap.Message
+ SeqSet *imap.SeqSet
+ Uid bool
+}
+
+func (r *Fetch) Handle(resp imap.Resp) error {
+ name, fields, ok := imap.ParseNamedResp(resp)
+ if !ok || name != fetchName {
+ return ErrUnhandled
+ } else if len(fields) < 1 {
+ return errNotEnoughFields
+ }
+
+ seqNum, err := imap.ParseNumber(fields[0])
+ if err != nil {
+ return err
+ }
+
+ msgFields, _ := fields[1].([]interface{})
+ msg := &imap.Message{SeqNum: seqNum}
+ if err := msg.Parse(msgFields); err != nil {
+ return err
+ }
+
+ if r.Uid && msg.Uid == 0 {
+ // we requested UIDs and got a message without one --> unilateral update --> ignore
+ return ErrUnhandled
+ }
+
+ var num uint32
+ if r.Uid {
+ num = msg.Uid
+ } else {
+ num = seqNum
+ }
+
+ // Check whether we obtained a result we requested with our SeqSet
+ // If the result is not contained in our SeqSet we have to handle an additional special case:
+ // In case we requested UIDs with a dynamic sequence (i.e. * or n:*) and the maximum UID of the mailbox
+ // is less then our n, the server will supply us with the max UID (cf. RFC 3501 §6.4.8 and §9 `seq-range`).
+ // Thus, such a result is correct and has to be returned by us.
+ if !r.SeqSet.Contains(num) && (!r.Uid || !r.SeqSet.Dynamic()) {
+ return ErrUnhandled
+ }
+
+ r.Messages <- msg
+ return nil
+}
+
+func (r *Fetch) WriteTo(w *imap.Writer) error {
+ var err error
+ for msg := range r.Messages {
+ resp := imap.NewUntaggedResp([]interface{}{msg.SeqNum, imap.RawString(fetchName), msg.Format()})
+ if err == nil {
+ err = resp.WriteTo(w)
+ }
+ }
+ return err
+}