Merge branch 'issue-comment'
This commit is contained in:
56
pop3.go
56
pop3.go
@@ -9,27 +9,29 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessageInfoはメッセージ番号、メッセージサイズ、およびユニークIDを持つ型です。
|
// MessageInfo has Number, Size, and Uid fields,
|
||||||
// ListAllまたはUidlAllメソッドの戻り値として使用されます。
|
// and used as a return value of ListAll and UidlAll.
|
||||||
// ListAllメソッドにて取得した場合は、メッセージ番号とメッセージサイズ、
|
// When used as the return value of the method ListAll,
|
||||||
// UidlAllメソッドにて取得した場合は、メッセージ番号とユニークIDのみに値が入っています。
|
// MessageInfo contain only the Number and Size values.
|
||||||
|
// When used as the return value of the method UidlAll,
|
||||||
|
// MessageInfo contain only the Number and Uid values.
|
||||||
type MessageInfo struct {
|
type MessageInfo struct {
|
||||||
Number int
|
Number int
|
||||||
Size uint64
|
Size uint64
|
||||||
Uid string
|
Uid string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientはPOPサーバーへの接続を表すクライアントです。
|
// A Client represents a client connection to an POP server.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
// TextはClientによって使用されるmail2.Connです。
|
// Text is the pop3.Conn used by the Client.
|
||||||
Text *Conn
|
Text *Conn
|
||||||
// keep a reference to the connection so it can be used to create a TLS
|
// keep a reference to the connection so it can be used to create a TLS
|
||||||
// connection later
|
// connection later
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dialは指定されたアドレスのPOPサーバーに接続された新規Clientを返します。
|
//Dial returns a new Client connected to an POP server at addr.
|
||||||
// アドレスはポート番号を含まなくてはなりません。
|
// The addr must include a port number.
|
||||||
func Dial(addr string) (*Client, error) {
|
func Dial(addr string) (*Client, error) {
|
||||||
conn, err := net.Dial("tcp", addr)
|
conn, err := net.Dial("tcp", addr)
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ func Dial(addr string) (*Client, error) {
|
|||||||
return NewClient(conn)
|
return NewClient(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient既存のコネクションを使用した新規Clientを返します。
|
// NewClient returns a new Client using an existing connection.
|
||||||
func NewClient(conn net.Conn) (*Client, error) {
|
func NewClient(conn net.Conn) (*Client, error) {
|
||||||
text := NewConn(conn)
|
text := NewConn(conn)
|
||||||
|
|
||||||
@@ -53,24 +55,24 @@ func NewClient(conn net.Conn) (*Client, error) {
|
|||||||
return &Client{Text: text, conn: conn}, nil
|
return &Client{Text: text, conn: conn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Userは指定されたユーザを使用してサーバーに対してUSERコマンドを発行します。
|
// User issues a USER command to the server using the provided user name.
|
||||||
func (c *Client) User(user string) error {
|
func (c *Client) User(user string) error {
|
||||||
return c.cmdSimple("USER %s", user)
|
return c.cmdSimple("USER %s", user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passは指定されたパスワードを使用してサーバーに対してPASSコマンドを発行します。
|
// Pass issues a PASS command to the server using the provided password.
|
||||||
func (c *Client) Pass(pass string) error {
|
func (c *Client) Pass(pass string) error {
|
||||||
return c.cmdSimple("PASS %s", pass)
|
return c.cmdSimple("PASS %s", pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statはサーバーに対してSTARコマンドを発行します。
|
// Stat issues a STAT command to the server
|
||||||
// サーバーに保存されているメール数、合計メールサイズおよびエラーが返ります。
|
// and returns mail count and total size.
|
||||||
func (c *Client) Stat() (int, uint64, error) {
|
func (c *Client) Stat() (int, uint64, error) {
|
||||||
return c.cmdStatOrList("STAT", "STAT")
|
return c.cmdStatOrList("STAT", "STAT")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrは指定されたメール番号を使用してサーバーに対してRetrコマンドを発行します。
|
// Retr issues a RETR command to the server using the provided mail number
|
||||||
// サーバーに保存されているメール数、合計メールサイズが返ります。
|
// and returns mail data.
|
||||||
func (c *Client) Retr(number int) (string, error) {
|
func (c *Client) Retr(number int) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -89,14 +91,14 @@ func (c *Client) Retr(number int) (string, error) {
|
|||||||
return c.Text.ReadToPeriod()
|
return c.Text.ReadToPeriod()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listは指定されたメール番号を使用してサーバーに対してLISTコマンドを発行します。
|
// List issues a LIST command to the server using the provided mail number
|
||||||
// 指定されたメール番号が存在する場合は、メール番号とサイズが返ります。
|
// and returns mail number and size.
|
||||||
func (c *Client) List(number int) (int, uint64, error) {
|
func (c *Client) List(number int) (int, uint64, error) {
|
||||||
return c.cmdStatOrList("LIST", "LIST %d", number)
|
return c.cmdStatOrList("LIST", "LIST %d", number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAllはサーバーに対してLISTコマンドを発行します。
|
// List issues a LIST command to the server
|
||||||
// 存在するメール件数分のMessageInfoが返ります。
|
// and returns array of MessageInfo.
|
||||||
func (c *Client) ListAll() ([]MessageInfo, error) {
|
func (c *Client) ListAll() ([]MessageInfo, error) {
|
||||||
list := make([]MessageInfo, 0)
|
list := make([]MessageInfo, 0)
|
||||||
|
|
||||||
@@ -119,8 +121,8 @@ func (c *Client) ListAll() ([]MessageInfo, error) {
|
|||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uidlは指定されたメール番号を使用してサーバーに対してUIDLコマンドを発行します。
|
// Uidl issues a UIDL command to the server using the provided mail number
|
||||||
// 指定されたメール番号が存在する場合は、メール番号とユニークIDが返ります。
|
// and returns mail number and unique id.
|
||||||
func (c *Client) Uidl(number int) (int, string, error) {
|
func (c *Client) Uidl(number int) (int, string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -150,8 +152,8 @@ func (c *Client) Uidl(number int) (int, string, error) {
|
|||||||
return val, uid, nil
|
return val, uid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UidlAllはサーバーに対してUIDLコマンドを発行します。
|
// Uidl issues a UIDL command to the server
|
||||||
// 存在するメール件数分のMessageInfoが返ります。
|
// and returns array of MessageInfo.
|
||||||
func (c *Client) UidlAll() ([]MessageInfo, error) {
|
func (c *Client) UidlAll() ([]MessageInfo, error) {
|
||||||
list := make([]MessageInfo, 0)
|
list := make([]MessageInfo, 0)
|
||||||
|
|
||||||
@@ -174,22 +176,22 @@ func (c *Client) UidlAll() ([]MessageInfo, error) {
|
|||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deleは指定されたメール番号を使用してサーバーに対してDELEコマンドを発行します。
|
// Dele issues a DELE command to the server using the provided mail number.
|
||||||
func (c *Client) Dele(number int) error {
|
func (c *Client) Dele(number int) error {
|
||||||
return c.cmdSimple("DELE %d", number)
|
return c.cmdSimple("DELE %d", number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Noopはサーバーに対してNOOPコマンドを発行します。
|
// Noop issues a NOOP command to the server.
|
||||||
func (c *Client) Noop() error {
|
func (c *Client) Noop() error {
|
||||||
return c.cmdSimple("NOOP")
|
return c.cmdSimple("NOOP")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rsetはサーバーに対してRSETコマンドを発行します。
|
// Rset issues a RSET command to the server.
|
||||||
func (c *Client) Rset() error {
|
func (c *Client) Rset() error {
|
||||||
return c.cmdSimple("RSET")
|
return c.cmdSimple("RSET")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quitはサーバーに対してQUITコマンドを発行します。
|
// Quit issues a QUIT command to the server.
|
||||||
func (c *Client) Quit() error {
|
func (c *Client) Quit() error {
|
||||||
return c.cmdSimple("QUIT")
|
return c.cmdSimple("QUIT")
|
||||||
}
|
}
|
||||||
|
|||||||
28
pop3proto.go
28
pop3proto.go
@@ -9,18 +9,21 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A ResponseError describes a protocol violation such as an invalid response or a hung-up connection.
|
||||||
type ResponseError string
|
type ResponseError string
|
||||||
|
|
||||||
func (r ResponseError) Error() string {
|
func (r ResponseError) Error() string {
|
||||||
return string(r)
|
return string(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Conn represents a textual network protocol connection for POP3.
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
Reader
|
Reader
|
||||||
Writer
|
Writer
|
||||||
conn io.ReadWriteCloser
|
conn io.ReadWriteCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewConn returns a new Conn using conn for I/O.
|
||||||
func NewConn(conn io.ReadWriteCloser) *Conn {
|
func NewConn(conn io.ReadWriteCloser) *Conn {
|
||||||
return &Conn{
|
return &Conn{
|
||||||
Reader: Reader{R: textproto.NewReader(bufio.NewReader(conn))},
|
Reader: Reader{R: textproto.NewReader(bufio.NewReader(conn))},
|
||||||
@@ -29,18 +32,25 @@ func NewConn(conn io.ReadWriteCloser) *Conn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the connection.
|
||||||
func (c *Conn) Close() error {
|
func (c *Conn) Close() error {
|
||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Reader implements convenience methods
|
||||||
|
// for reading requests or responses from a text protocol network connection.
|
||||||
type Reader struct {
|
type Reader struct {
|
||||||
R *textproto.Reader
|
R *textproto.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReader returns a new Reader reading from r.
|
||||||
func NewReader(r *bufio.Reader) *Reader {
|
func NewReader(r *bufio.Reader) *Reader {
|
||||||
return &Reader{R: textproto.NewReader(r)}
|
return &Reader{R: textproto.NewReader(r)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadLine reads a single line from r,
|
||||||
|
// eliding the final \n or \r\n from the returned string.
|
||||||
|
// This calls textproto.Reader.ReadLine simply.
|
||||||
func (r *Reader) ReadLine() (string, error) {
|
func (r *Reader) ReadLine() (string, error) {
|
||||||
return r.R.ReadLine()
|
return r.R.ReadLine()
|
||||||
// for debug
|
// for debug
|
||||||
@@ -49,6 +59,9 @@ func (r *Reader) ReadLine() (string, error) {
|
|||||||
// return l, err
|
// return l, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadLines reads a multiline until the last line of the only period,
|
||||||
|
// and returns a each line at slice.
|
||||||
|
// it does not contain last period.
|
||||||
func (r *Reader) ReadLines() ([]string, error) {
|
func (r *Reader) ReadLines() ([]string, error) {
|
||||||
var lines []string
|
var lines []string
|
||||||
var line string
|
var line string
|
||||||
@@ -69,6 +82,9 @@ func (r *Reader) ReadLines() ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadToPeriod reads a multiline until the last line of the only period,
|
||||||
|
// and returns as a string.
|
||||||
|
// it does not contain last period.
|
||||||
func (r *Reader) ReadToPeriod() (string, error) {
|
func (r *Reader) ReadToPeriod() (string, error) {
|
||||||
lines, err := r.ReadLines()
|
lines, err := r.ReadLines()
|
||||||
|
|
||||||
@@ -79,6 +95,10 @@ func (r *Reader) ReadToPeriod() (string, error) {
|
|||||||
return strings.Join(lines, "\r\n"), nil
|
return strings.Join(lines, "\r\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadResponse reads a single line from r,
|
||||||
|
// and parses reponse.
|
||||||
|
// if the response is -ERR or has some other errors,
|
||||||
|
// it returns error.
|
||||||
func (r *Reader) ReadResponse() (string, error) {
|
func (r *Reader) ReadResponse() (string, error) {
|
||||||
line, err := r.ReadLine()
|
line, err := r.ReadLine()
|
||||||
|
|
||||||
@@ -93,7 +113,7 @@ func (r *Reader) parseResponse(line string) (string, error) {
|
|||||||
var index int
|
var index int
|
||||||
|
|
||||||
if index = strings.Index(line, " "); index < 0 {
|
if index = strings.Index(line, " "); index < 0 {
|
||||||
return "", ResponseError(fmt.Sprintf("レスポンスのフォーマットが不正です。: %s", line))
|
return "", ResponseError(fmt.Sprintf("invalid response format: %s", line))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch strings.ToUpper(line[:index]) {
|
switch strings.ToUpper(line[:index]) {
|
||||||
@@ -102,20 +122,24 @@ func (r *Reader) parseResponse(line string) (string, error) {
|
|||||||
case "-ERR":
|
case "-ERR":
|
||||||
return "", ResponseError(line[index+1:])
|
return "", ResponseError(line[index+1:])
|
||||||
default:
|
default:
|
||||||
return "", ResponseError(fmt.Sprintf("レスポンスの内容が不明です。: %s", line))
|
return "", ResponseError(fmt.Sprintf("unknown response: %s", line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var crnl = []byte{'\r', '\n'}
|
var crnl = []byte{'\r', '\n'}
|
||||||
|
|
||||||
|
// A Writer implements convenience methods
|
||||||
|
// for writing requests or responses to a text protocol network connection.
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
W *bufio.Writer
|
W *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewWriter returns a new Writer writing to w.
|
||||||
func NewWriter(w *bufio.Writer) *Writer {
|
func NewWriter(w *bufio.Writer) *Writer {
|
||||||
return &Writer{W: w}
|
return &Writer{W: w}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteLine writes the formatted output followed by \r\n.
|
||||||
func (w *Writer) WriteLine(format string, args ...interface{}) error {
|
func (w *Writer) WriteLine(format string, args ...interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user