Git Product home page Git Product logo

go-imap's Introduction

go-imap

builds.sr.ht status Go Reference

An IMAP4rev2 library for Go.

Note This is the README for go-imap v2. This new major version is still in development. For go-imap v1, see the v1 branch.

Usage

To add go-imap to your project, run:

go get github.com/emersion/go-imap/v2

Documentation and examples for the module are available here:

License

MIT

go-imap's People

Contributors

adregner avatar bitfehler avatar emersion avatar kaz-as avatar mariwilliam avatar qjebbs avatar rakoo avatar rikkuru avatar rockorager avatar shugyousha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-imap's Issues

Add a write lock

Currently sending two responses at the same time will lead to undefined behavior on the server. Att a write lock to prevent bad things to happen. Beware of deadlocks.

Do not panic when parsing

If the IMAP server is sending bad data, do not panic when parsing. Change str := val.(string) to str, _ := val.(string).

Fetching a partial BODY returns an error

When fetching BODY.PEEK[]<0.8>, the client fails when parsing the server's BODY[]<0> {8} response.

server.go:

package main

import (
    "github.com/emersion/go-imap/backend/memory"
    "github.com/emersion/go-imap/server"
    "log"
)

func main() {
    bkd := memory.New()
    s := server.New(bkd)
    s.Addr = ":3000"
    s.AllowInsecureAuth = true
    log.Println("Starting IMAP server at localhost:3000")
    if err := s.ListenAndServe(); err != nil {
        log.Fatal(err)
    }
}

client.go:

package main

import (
    "github.com/emersion/go-imap"
    "github.com/emersion/go-imap/client"
    "log"
    "os"
)

func main() {
    c, _ := client.Dial("localhost:3000")
    c.SetDebug(os.Stderr)
    c.Login("username", "password")
    c.Select("INBOX", false)
    seqset, _ := imap.NewSeqSet("1:*")
    messages := make(chan *imap.Message)
    done := make(chan error, 1)
    go func() {
        done <- c.Fetch(seqset, []string{"BODY.PEEK[]<0.8>"}, messages)
    }()
    for msg := range messages {
        log.Println("MESSAGE: %v", msg) // expected: a message
    }
    if err := <-done; err != nil {
        log.Fatal(err) // got: Invalid body section name: partial must have two fields
    }
}

stderr:

Kj3K0Q LOGIN username password
5SektA SELECT INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 1 EXISTS
* 0 RECENT
* OK [UNSEEN 0] 
* OK [UIDNEXT 7] Predicted next UID
* OK [UIDVALIDITY 1] UIDs valid
5SektA OK [READ-WRITE] SELECT completed
SwWRDQ FETCH 1:* (BODY.PEEK[]<0.8>)
* 1 FETCH (BODY[]<0> {8}
From: co)
<0>
SwWRDQ OK FETCH completed
2016/09/23 21:44:08 Invalid body section name: partial must have two fields
exit status 1

Add an extension interface

Add a Server.Enable(extension Extension) method.

type Extension interface {
    Capabilities(state common.ConnState) []string
    Commands() map[string]HandlerFactory
}

how to parse msg.body

err = c.Fetch(seqset, []string{"ENVELOPE", "RFC822.HEADER", "RFC822.TEXT"}, messages)
    if err != nil {
        log.Fatal(err)
    }

for msg := range messages {
        log.Println(msg.Envelope.Subject)
        //log.Println(msg.Body) 
    }

msg.body return text how to parse email body get struct

thk

Handle all unilateral responses

  • Info: * OK [ALERT] System shutdown in 10 minutes
  • Warning: * NO Disk is 98% full, please delete unnecessary data
  • Protocol-level error/internal server failure: * BAD Disk crash, attempting salvage to a new disk!
  • Server closing connection: * BYE Autologout; idle for too long
  • Number of messages: * 23 EXISTS
  • Number of \Recent: * 5 RECENT
  • Message deleted: * 44 EXPUNGE
  • Message update (e.g. flags): * 23 FETCH (FLAGS (\Seen)) (#5)

Use net/textproto

Make use of textproto.Reader, textproto.Writer and textproto.Pipeline.

Replace Id, SeqId by SeqNum

In several parts of the code, Id or SeqId is used. This is confusing since the RFC only uses the term sequence number. Replace those with SeqNum.

How to authenticate with this capabilities?

CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS LOGINDISABLED

I can't use Login function. And I don't understand how to use Authenticate

Thunderbird connects to server by STARTTLS using login and password w/o encryption.

Please, help me to connect to my imap server.

Block caused when error chan is not empty

I have this code:

func RetrieveFolders(c *client.Client, folder string) []string {
    var folders []string
    mailboxes := make(chan *imap.MailboxInfo)

    go func() {
        c.List("", folder, mailboxes)
    }()

    for mailbox := range mailboxes {
        folders = append(folders, mailbox.Name)
    }

    return folders
}

func RetrieveMessages(c *client.Client, folder string, start, end uint32) ([]*imap.Message, error) {
    var emails []*imap.Message
    _, err := c.Select(folder, true)
    if err != nil {
        return nil, err
    }

    seqset, _ := imap.NewSeqSet("")
    seqset.AddRange(start, end)

    messages := make(chan *imap.Message, end - start)
    err = c.Fetch(seqset, []string{"ENVELOPE"}, messages)
    if err != nil {
        return nil, err
    }

    for msg := range messages {
        emails = append(emails, msg)
    }

    return emails, nil
}

This code returns these error when fetch folders:

imap/client: 2016/09/08 17:25:52 response has not been handled:  &{* OK HIGHESTMODSEQ [268] Highest}
imap/client: 2016/09/08 17:25:56 response has not been handled:  &{* OK CLOSED [] Previous mailbox closed.}
imap/client: 2016/09/08 17:25:56 response has not been handled:  &{* OK HIGHESTMODSEQ [1178] Highest}

When I fetch emails from IMAP folder, this code remains blocked because code in this point remain in waiting state. There is a way to solve the problem?

Panic when sending a FETCH

7.810 UID FETCH 72,79:82 (BODY.PEEK[] BODYSTRUCTURE)
^Cpanic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4150c7c]

goroutine 31 [running]:
panic(0x46026a0, 0xc8200120c0)
    /usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap.(*Envelope).Format(0x0, 0x0, 0x0, 0x0)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/message.go:513 +0x79c
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap.(*BodyStructure).Format(0xc820309b20, 0xc820297420, 0x7, 0x7)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/message.go:841 +0xc66
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap.(*BodyStructure).Format(0xc820309960, 0xc820365ec0, 0x1, 0x1)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/message.go:812 +0x106
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap.(*Message).Format(0xc8201d60e0, 0x0, 0x0, 0x0)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/message.go:144 +0x85e
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/responses.(*Fetch).WriteTo(0xc8200ec098, 0x5605428, 0xc820394580, 0x0, 0x0)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/responses/fetch.go:45 +0xc1
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server.(*conn).WriteResp(0xc820366c80, 0x545eb40, 0xc8200ec098, 0x0, 0x0)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server/conn.go:120 +0xe3
github.com/ProtonMail/secret-project/vendor/github.com/ProtonMail/go-imap-id.(*conn).WriteResp(0xc820394600, 0x545eb40, 0xc8200ec098, 0x0, 0x0)
    <autogenerated>:17 +0x6f
github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server.(*Fetch).handle.func1(0xc820422300, 0x56056e8, 0xc820394600, 0xc8200ec098)
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server/cmd_selected.go:161 +0x5c
created by github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server.(*Fetch).handle
    /Users/Yanfeng/.go/src/github.com/ProtonMail/secret-project/vendor/github.com/emersion/go-imap/server/cmd_selected.go:163 +0x14a
exit status 2

Fix STARTTLS

Make sure a tagged OK response is sent before negotiating TLS.

Do not send unilateral updates at anytime

Some email clients don't support unilateral updates sent at anytime. Instead, add a buffer of unilateral updates not yet sent and flush them when the client sends a NOOP.

Need to think how to support IDLE too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.