Golang imap.DialTLS配置示例

4

我曾经可以像这样连接到邮件服务器的 143 端口:

c, err := imap.Dial(mailServer)

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

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

现在我不知道如何构建*tls.Config。我谷歌了一下,但没有找到任何真正有用的东西。有人可以给我展示一些如何构建*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个回答

5
首先,您应该使用项目的GitHub存储库,因为Google Code项目已经宣布由于Google Code关闭而转移到GitHub。它比Google Code repo领先几个提交,如果您不迁移到GitHub repo,则不会收到任何更新。
其次,从软件包演示来看,将nil传递给DialTLS作为TLS客户端似乎是连接默认TLS客户端的正确方式。
从您提供的信息来看,似乎可能是服务器接受该端口上的连接的问题。我会查看要连接的客户端是否打开了该端口,或者您的IMAP服务器是否接受TLS连接。
如果您在进一步调试后确信这不是服务器问题,我建议您在项目的GitHub问题跟踪器上报告问题,以获取来自熟悉该软件包的人的帮助,因为它是第三方软件包。

谢谢@AustinDizzy。我会改用Github版本并再次尝试。现在服务器正在为许多客户端提供服务,我非常确定端口993正常工作。我的上一个服务器开放了143端口,所以我使用了imap.Dial,它可以正确地获取邮件。现在唯一的变化是将imap.Dial替换为imap.DialTLS。它可以编译,并且运行时没有错误。但是没有邮件被获取。我总是从代码中得到一个空的邮件数组。我会继续尝试并回来更新我发现的内容。 - user1663023

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接