Golang imap.DialTLS配置示例

时间:2015-08-02 22:49:45

标签: ssl go imap

我曾经能够连接到邮件服务器的端口143,如下所示:

c, err := imap.Dial(mailServer)

上面的代码连接到mailServer的端口143。现在我有一个新的邮件服务器只接受端口993。查看Golang imap源代码,函数DialTLS将连接到端口993DialTLS的签名如下所示:

func DialTLS(addr string, config *tls.Config) (c *Client, err error)

现在我不知道如何构建*tls.Config。我用Google搜索,但没有找到任何真正有用的东西。有人能告诉我一些如何构建*tls.Config的例子吗?

我尝试传递nil作为第二个参数,它编译,我没有得到任何运行时错误。但似乎没有新的邮件被提取,即使我相信应该有。

我的抓取邮件代码如下所示:

// testimap
package main

import (
    "bytes"
    "code.google.com/p/go-imap/go1/imap"
    "fmt"
    "net/mail"
    "time"
)

type Mail struct {
    Subject string
    Body    string
    From    string
    Uid     uint32
}

func FetchMail(lastUid uint32) []*Mail {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()
    //
    // Note: most of error handling code is omitted for brevity
    //
    var (
        c   *imap.Client
        cmd *imap.Command
        rsp *imap.Response
    )

    // Connect to the server
    c, err := imap.DialTLS(mailServer, nil)
    if err != nil {
        fmt.Println(err)
    }

    // Remember to log out and close the connection when finished
    defer c.Logout(30 * time.Second)

    // Print server greeting (first response in the unilateral server data queue)
    //fmt.Println("Server says hello:", c.Data[0].Info)
    c.Data = nil

    // Enable encryption, if supported by the server
    if c.Caps["STARTTLS"] {
        c.StartTLS(nil)
    }

    // Authenticate
    if c.State() == imap.Login {
        c.Login(mailSupportUser, mailSupportPw)
    }

    //// List all top-level mailboxes, wait for the command to finish
    cmd, err = imap.Wait(c.List("", "%"))
    if err != nil {
        fmt.Println(err)
    }
    // Print mailbox information
    //fmt.Println("\nTop-level mailboxes:")
    //for _, rsp = range cmd.Data {
    //  fmt.Println("|--", rsp.MailboxInfo())
    //}

    // Check for new unilateral server data responses
    //for _, rsp = range c.Data {
    //  fmt.Println("Server data:", rsp)
    //}
    c.Data = nil

    // Open a mailbox (synchronous command - no need for imap.Wait)
    c.Select("INBOX", true)
    //fmt.Print("\nMailbox status:\n", c.Mailbox)

    // Fetch the headers of the 10 most recent messages
    set, err := imap.NewSeqSet(fmt.Sprint(lastUid, ":*"))
    if err != nil {
        fmt.Println(err)
    }
    //if c.Mailbox.Messages >= 10 {
    //  set.AddRange(c.Mailbox.Messages-9, c.Mailbox.Messages)
    //} else {
    //  set.Add("1:*")
    //}
    cmd, err = c.UIDFetch(set, "RFC822.HEADER", "RFC822.TEXT")
    if err != nil {
        fmt.Println(err)
    }

    // Process responses while the command is running
    //fmt.Println("\nMost recent messages:")
    mails := make([]*Mail, 0, 10)
    for cmd.InProgress() {
        // Wait for the next response (no timeout)
        c.Recv(-1)

        // Process command data
        for _, rsp = range cmd.Data {
            if err != nil {
                fmt.Println(err)
            }
            header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
            uid := imap.AsNumber((rsp.MessageInfo().Attrs["UID"]))
            body := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"])
            if msg, err := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
                if err != nil {
                    fmt.Println(err)
                }
                mail := &Mail{
                    Subject: msg.Header.Get("Subject"),
                    From:    msg.Header.Get("FROM"),
                    Body:    string(body),
                    Uid:     uid,
                }
                if mail.Uid < lastUid {
                    continue
                }
                mails = append(mails, mail)
            }
        }
        cmd.Data = nil
        c.Data = nil
    }

    // Check command completion status
    if rsp, err := cmd.Result(imap.OK); err != nil {
        if err == imap.ErrAborted {
            fmt.Println("Fetch command aborted")
        } else {
            fmt.Println("Fetch error:", rsp.Info)
        }
    }
    fmt.Println(mails)
    return mails
}

1 个答案:

答案 0 :(得分:5)

首先,您应该使用project's GitHub repo作为Google代码项目,由于Google代码关闭,开发工作正在转移到GitHub。它也是Google Code repo之前的一些提交,因此如果您不迁移到GitHub仓库,您将无法获得任何更新。

其次,查看package's demo,将nil传递给DialTLS作为TLS客户端似乎是连接默认TLS客户端的正确方法。

根据您提供的信息,您的服务器接受该端口上的连接似乎可能存在问题。我会查看端口是否对您尝试连接的客户端开放,或者您的IMAP服务器是否接受TLS连接。

如果您在进一步调试后确定它不是服务器问题,我会在project's GitHub issue tracker上提出问题,以便从更熟悉该软件包的人那里获得帮助,它是第三方包。