[Go] Package SMTP

SMTP

Simple Mail Transfer Protocol 의 약자

SMTP 의 자세한 내용은 Network/SMTP 에서 확인

net/smtp
Package SMTP는 RFC 5321 의 SMTP, RFC 1652 의 8BITMIME, RFC 2554 의 AUTH, RFC 3207 의 STARTTLS 를 구현해 놓은 내장 패키지다.

이메일 발송을 위해 사용한다.

### Table of Contents

smtp 코드 열어보기

type Client

SMTP 서버와 연결된 클라이언트.

type Client struct {
  Text        *textproto.Conn
  conn        net.Conn
  tls         bool
  serverName  string
  ext         map[string]string
  auth        []string
  localName   string 
  didHello    bool   
  helloError  error  
}

↑ return to TOC

smtp.Close

연결 끊기

func (c *Client) Close() error {
  return c.Text.Close()
}

↑ return to TOC

smtp.Extension

서버가 지원하는 extension인지 보고해준다.

↑ return to TOC

smtp.Hello

func (c *Client) Hello(localName string) error {
  if err := validateLine(localName); err != nil {
     return err
  }
  if c.didHello {
     return errors.New("smtp: Hello called after other methods")
  }
  c.localName = localName
  return c.hello()
}

↑ return to TOC

smtp.Reset

RSET 명령어를 서버에 보냄으로써 현재 진행중인 메일 transaction 을 중단시킨다.

func (c *Client) Reset() error {
  if err := c.hello(); err != nil {
     return err
  }
  _, _, err := c.cmd(250, "RSET")
  return err
}

↑ return to TOC

smtp.Noop

NOOP 명령어를 서버에 보낸다.
이를 통해 서버가 연결이 문제 없는지, 클라이언트와 통신가능한지 확인한다.

func (c *Client) Noop() error {
  if err := c.hello(); err != nil {
     return err
  }
  _, _, err := c.cmd(250, "NOOP")
  return err
}

↑ return to TOC

smtp.Quit

QUIT 명령어를 서버에 보낸다.

func (c *Client) Quit() error {
  if err := c.hello(); err != nil {
     return err
  }
  _, _, err := c.cmd(221, "QUIT")
  if err != nil {
     return err
  }
  return c.Text.Close()
}

↑ return to TOC

smtp.ValidateLine

SMTP의 라인 규격을 맞추었는지 확인한다.

func validateLine(line string) error {
  if strings.ContainsAny(line, "\n\r") {
     return errors.New("smtp: A line must not contain CR or LF")
  }
  return nil
}

↑ return to TOC

smtp.SendMail

메일 전송

func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
  if err := validateLine(from); err != nil {
     return err
  }
  for _, recp := range to {
     if err := validateLine(recp); err != nil {
        return err
     }
  }
  c, err := Dial(addr)
  if err != nil {
     return err
  }
  defer c.Close()
  if err = c.hello(); err != nil {
     return err
  }
  if ok, _ := c.Extension("STARTTLS"); ok {
     config := &tls.Config{ServerName: c.serverName}
     if testHookStartTLS != nil {
        testHookStartTLS(config)
     }
     if err = c.StartTLS(config); err != nil {
        return err
     }
  }
  if a != nil && c.ext != nil {
     if _, ok := c.ext["AUTH"]; !ok {
        return errors.New("smtp: server doesn't support AUTH")
     }
     if err = c.Auth(a); err != nil {
        return err
     }
  }
  if err = c.Mail(from); err != nil {
     return err
  }
  for _, addr := range to {
     if err = c.Rcpt(addr); err != nil {
        return err
     }
  }
  w, err := c.Data()
  if err != nil {
     return err
  }
  _, err = w.Write(msg)
  if err != nil {
     return err
  }
  err = w.Close()
  if err != nil {
     return err
  }
  return c.Quit()
}

↑ return to TOC