代码拉取完成,页面将自动刷新
package email
import (
"context"
"errors"
"io"
"log"
"net/mail"
"net/smtp"
"net/url"
"time"
"gitee.com/go-better/dev/algo/pool"
)
type Client struct {
pool *pool.Pool
from string
fromAddr string
}
// NewClient make a Client from a url config.
// urlString example: smtp://stmp.exmail.qq.com:465/?user=张三<zhangsan@example.com>&pass=password
// urlString have 3 optional query params:
// 1. maxOpen: Max number of connections can open at a time. Default value is 10.
// 2. maxIdle: Max number of idle connections to keep. Default value is 1.
// 3. safeIdleTime: A time.Duration string. If a connection has been idle greater than the safe time,
// it will be checked by a noop operation to ensure it's not closed by the server side. Default value is 30s.
func NewClient(urlString string) (*Client, error) {
uri, err := url.Parse(urlString)
if err != nil {
return nil, err
}
query := uri.Query()
open, fromAddress, err := getOpenFunc(uri, query)
if err != nil {
return nil, err
}
usable, err := getUsableFunc(query)
if err != nil {
return nil, err
}
pool, err := pool.New2(open, usable, query)
if err != nil {
return nil, err
}
return &Client{pool: pool, from: query.Get("user"), fromAddr: fromAddress}, nil
}
func (c *Client) Send(ctx context.Context, msg *Message) (err error) {
if c == nil || msg == nil {
return nil
}
recipients, err := getRecipients(msg.Headers)
if len(recipients) == 0 || err != nil {
return err
}
if findHeader(msg.Headers, From).isEmpty() {
msg.Headers = append(msg.Headers, Header{Name: From, Values: []string{c.from}})
}
content, err := msg.Bytes()
if err != nil {
return err
}
resource, err := c.pool.Get(ctx)
if err != nil {
return err
}
conn := resource.Resource().(*Conn)
err = conn.Send(ctx, c.fromAddr, recipients, content)
switch err {
case nil:
if err2 := c.pool.Put(resource); err2 != nil {
log.Println("email: pool.Put:", err2)
}
default:
if err2 := c.pool.Close(resource); err2 != nil {
log.Println("email: pool.Close:", err2)
}
}
return err
}
func getOpenFunc(uri *url.URL, query url.Values) (pool.OpenFunc, string, error) {
user, err := mail.ParseAddress(query.Get(`user`))
if err != nil {
return nil, "", err
}
auth := smtp.PlainAuth(``, user.Address, query.Get(`pass`), uri.Hostname())
return func(ctx context.Context) (io.Closer, error) {
// distinguish nil pointer and nil interface
if conn, err := Dial(ctx, uri.Host, auth); conn != nil && err == nil {
return conn, nil
} else {
return nil, err
}
}, user.Address, nil
}
func getUsableFunc(query url.Values) (pool.UsableFunc, error) {
var safeIdleTime = 30 * time.Second
if s := query.Get(`safeIdleTime`); s != "" {
if v, err := time.ParseDuration(s); err != nil {
return nil, errors.New("invalid safeIdleTime: " + s)
} else {
safeIdleTime = v
}
}
return func(ctx context.Context, r *pool.Resource) bool {
if safeIdleTime > 0 && time.Since(r.IdleAt) <= safeIdleTime {
return true
}
return r.Resource().(*Conn).Noop() == nil
}, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。