// TestSMTP tests if can connect with the server and send some commands. func TestSMTP(addr string, a smtp.Auth, hello string, timeout time.Duration, insecureSkipVerify bool) error { serverName := addr port := "" s := strings.SplitN(addr, ":", 2) if len(s) >= 2 { serverName = s[0] port = s[1] } if serverName == "" || port == "" { return e.New("addrs is invalid") } hosts, err := dns.LookupHostCache(serverName) if err != nil { return e.Forward(err) } if len(hosts) == 0 { return e.New("can't resolve the addr") } conn, err := net.DialTimeout("tcp", hosts[0]+":"+port, timeout) if err != nil { return e.Forward(err) } defer conn.Close() command := &Command{ Timeout: timeout, Conn: conn, } var c *smtp.Client r := command.Exec(smtp.NewClient, conn, serverName) r(&c, &err) if err != nil { return e.Forward(err) } defer c.Close() if hello != "" { r = command.Exec(c.Hello, hello) r(&err) if err != nil { return e.Forward(err) } } if ok, _ := c.Extension("STARTTLS"); ok { r = command.Exec(c.StartTLS, &tls.Config{ ServerName: serverName, InsecureSkipVerify: insecureSkipVerify, }) r(&err) if err != nil { return e.Forward(err) } } if a != nil { found, _ := c.Extension("AUTH") if found { r = command.Exec(c.Auth, a) r(&err) if err != nil { return e.Forward(err) } } } r = command.Exec(c.Reset) r(&err) if err != nil { return e.New(err) } r = command.Exec(c.Quit) r(&err) if err != nil { return e.New(err) } return nil }
// SendMail send a message to specific destination (to) using smtp server in addrs // and a auth. func SendMail(addr string, a smtp.Auth, from string, to []string, hello string, msg []byte, timeout time.Duration, insecureSkipVerify bool) error { serverName := addr port := "" serverName, port, err := net.SplitHostPort(addr) if err != nil { return e.Push(err, "invalid adderess") } if serverName == "" || port == "" { return e.New("addrs is invalid") } hosts, err := dns.LookupHostCache(serverName) if err != nil { return e.Forward(err) } if len(hosts) == 0 { return e.New("can't resolve the addr") } var conn net.Conn for _, host := range hosts { addr, err = utilNet.IpPort(host, port) if err != nil { err = e.Forward(err) continue } conn, err = net.DialTimeout("tcp", addr, timeout) if err != nil { err = e.Forward(err) continue } } if conn == nil { return err } command := &Command{ Timeout: timeout, Conn: conn, } var c *smtp.Client r := command.Exec(smtp.NewClient, conn, serverName) r(&c, &err) if err != nil { return e.Forward(err) } defer c.Close() if hello != "" { r = command.Exec(c.Hello, hello) r(&err) if err != nil { return e.Forward(err) } } if ok, _ := c.Extension("STARTTLS"); ok { r = command.Exec(c.StartTLS, &tls.Config{ ServerName: serverName, InsecureSkipVerify: insecureSkipVerify, }) r(&err) if err != nil { return e.Forward(err) } } if a != nil { found, _ := c.Extension("AUTH") if found { r = command.Exec(c.Auth, a) r(&err) if err != nil { return e.Forward(err) } } } r = command.Exec(c.Mail, from) r(&err) if err != nil { return e.Forward(err) } for _, addr := range to { r = command.Exec(c.Rcpt, addr) r(&err) if err != nil { return e.New(err) } } var w io.WriteCloser r = command.ExecTimeout(0, c.Data) r(&w, &err) if err != nil { return e.New(err) } _, err = w.Write(msg) if err != nil { return e.New(err) } err = w.Close() if err != nil { return e.New(err) } r = command.Exec(c.Quit) r(&err) if err != nil { return e.New(err) } return nil }