【问题标题】:golang net/smtp getting smtp server response DSNgolang net/smtp 获取 smtp 服务器响应 DSN
【发布时间】:2022-01-31 20:02:55
【问题描述】:

我正在使用 golang net/smtp 发送邮件

每当我发送到我的 smtp 服务器时,我都需要捕获来自服务器的响应 特别是DSN

例如,我的本地 smtp 服务器在邮件末尾给出“ok queued as”

我需要捕获它并在日志中打印

我该怎么做

package main

import (
    "log"
    "net/smtp"
)

func sendEmail(msg []byte) {
    c, err := smtp.Dial("localhost:25")
    if err != nil {
        log.Fatal(err)
    }
    if err := c.Mail("sender@example.org"); err != nil {
        log.Fatal(err)
    }

    if err := c.Rcpt("recipient@example.net"); err != nil {
        log.Fatal(err)
    }
    wc, err := c.Data()
    if err != nil {
        log.Fatal(err)
    }

    _, err = wc.Write(msg)
    if err != nil {
        log.Fatal(err)
    }

    //How do I get the response here ??
    err = wc.Close()
    if err != nil {
        log.Fatal(err)
    }

    err = c.Quit()
    if err != nil {
        log.Fatal(err)
    }
}

【问题讨论】:

  • 有趣。我找不到任何关于它的信息。但是我想知道底层的conn是否可以被消费。
  • 我有一个建议。如果您仔细观察,Client 有一个名为 Text 的导出字段。 Text 类型包含一个重要的embedded 类型名称Reader,您实际上可以使用it 读取响应。

标签: email go smtp


【解决方案1】:

如 cmets 中所述,您可以使用 c.Text.ReadResponse():

package main

import (
    "net/smtp"
)

func sendEmail(msg []byte) (code int, message string, err error) {
    c, err := smtp.Dial("localhost:25")
    if err != nil {
        return
    }
    defer c.Quit() // make sure to quit the Client

    if err = c.Mail("sender@example.org"); err != nil {
        return
    }

    if err = c.Rcpt("recipient@example.net"); err != nil {
        return
    }

    wc, err := c.Data()
    if err != nil {
        return
    }
    defer wc.Close() // make sure WriterCloser gets closed

    _, err = wc.Write(msg)
    if err != nil {
        return
    }

    code, message, err = c.Text.ReadResponse(0)
    return
}

codemessage 和任何err 现在都传递给调用方,不要在整个代码中使用log.Fatal,在调用方处理错误。

【讨论】:

  • 不,这确实有效 这是我尝试过的 _, message, err := c.Text.ReadResponse(0) fmt.Printf("Response = %s\n", message) // 挂起永远
  • 经过图书馆后我意识到。底层的 net/smtp 模块实现了关闭丢弃 DSN 有没有其他库我可以使用
  • @Ram - 如果它挂起,您已经阅读了响应并等待更多数据。
【解决方案2】:
package main

import (
    "net/smtp"
)

func sendEmail(msg []byte) (code int, message string, err error) {
    c, err := smtp.Dial("localhost:25")
    if err != nil {
        return
    }
    defer c.Quit() // make sure to quit the Client

    if err = c.Mail("sender@example.org"); err != nil {
        return
    }

    if err = c.Rcpt("recipient@example.net"); err != nil {
        return
    }

    wc, err := c.Data()
    if err != nil {
        return
    }

    _, err = wc.Write(msg)
    if err != nil {
        return
    }

    code, message, err = closeData(c) 
    if err != nil {
        return 0, "", err
    }
    
    return code, message, err
}


func closeData(client *smtp.Client) error {
    d := &dataCloser{
        c:           client,
        WriteCloser: client.Text.DotWriter(),
    }

    return d.Close()
}

type dataCloser struct {
    c *smtp.Client
    io.WriteCloser
}

func (d *dataCloser) Close() (int, string, error) {
    d.WriteCloser.Close() // make sure WriterCloser gets closed
    code, message, err := d.c.Text.ReadResponse(250)

    fmt.Printf("Message %v, Error %v\n", message, err)
    return code, message, err
} 

【讨论】:

    猜你喜欢
    • 2012-01-09
    • 2011-09-16
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2020-10-01
    • 2017-09-13
    • 2019-09-02
    • 2013-06-25
    相关资源
    最近更新 更多