From 2110fadd12a37d0ff4e899c8d3211dacc6332c5b Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 21 Feb 2012 16:39:02 -0500 Subject: [PATCH] net/smtp: use EHLO then HELO Before we were using "ESMTP" in the banner as a clue, but that is not required by the RFC and breaks mailing to smtp.yandex.ru. Fixes #3045. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/5687066 --- src/pkg/net/smtp/smtp.go | 7 ++- src/pkg/net/smtp/smtp_test.go | 95 +++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/pkg/net/smtp/smtp.go b/src/pkg/net/smtp/smtp.go index f600cc8648..59f6449f0a 100644 --- a/src/pkg/net/smtp/smtp.go +++ b/src/pkg/net/smtp/smtp.go @@ -50,15 +50,14 @@ func Dial(addr string) (*Client, error) { // server name to be used when authenticating. func NewClient(conn net.Conn, host string) (*Client, error) { text := textproto.NewConn(conn) - _, msg, err := text.ReadResponse(220) + _, _, err := text.ReadResponse(220) if err != nil { text.Close() return nil, err } c := &Client{Text: text, conn: conn, serverName: host} - if strings.Contains(msg, "ESMTP") { - err = c.ehlo() - } else { + err = c.ehlo() + if err != nil { err = c.helo() } return c, err diff --git a/src/pkg/net/smtp/smtp_test.go b/src/pkg/net/smtp/smtp_test.go index ce88782053..c315d185c9 100644 --- a/src/pkg/net/smtp/smtp_test.go +++ b/src/pkg/net/smtp/smtp_test.go @@ -8,9 +8,11 @@ import ( "bufio" "bytes" "io" + "net" "net/textproto" "strings" "testing" + "time" ) type authTest struct { @@ -59,9 +61,12 @@ type faker struct { io.ReadWriter } -func (f faker) Close() error { - return nil -} +func (f faker) Close() error { return nil } +func (f faker) LocalAddr() net.Addr { return nil } +func (f faker) RemoteAddr() net.Addr { return nil } +func (f faker) SetDeadline(time.Time) error { return nil } +func (f faker) SetReadDeadline(time.Time) error { return nil } +func (f faker) SetWriteDeadline(time.Time) error { return nil } func TestBasic(t *testing.T) { basicServer = strings.Join(strings.Split(basicServer, "\n"), "\r\n") @@ -180,3 +185,87 @@ Goodbye. . QUIT ` + +func TestNewClient(t *testing.T) { + newClientServer = strings.Join(strings.Split(newClientServer, "\n"), "\r\n") + newClientClient = strings.Join(strings.Split(newClientClient, "\n"), "\r\n") + + var cmdbuf bytes.Buffer + bcmdbuf := bufio.NewWriter(&cmdbuf) + out := func() string { + bcmdbuf.Flush() + return cmdbuf.String() + } + var fake faker + fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClientServer)), bcmdbuf) + c, err := NewClient(fake, "fake.host") + if err != nil { + t.Fatalf("NewClient: %v\n(after %v)", err, out()) + } + if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { + t.Fatalf("Expected AUTH supported") + } + if ok, _ := c.Extension("DSN"); ok { + t.Fatalf("Shouldn't support DSN") + } + if err := c.Quit(); err != nil { + t.Fatalf("QUIT failed: %s", err) + } + + actualcmds := out() + if newClientClient != actualcmds { + t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClientClient) + } +} + +var newClientServer = `220 hello world +250-mx.google.com at your service +250-SIZE 35651584 +250-AUTH LOGIN PLAIN +250 8BITMIME +221 OK +` + +var newClientClient = `EHLO localhost +QUIT +` + +func TestNewClient2(t *testing.T) { + newClient2Server = strings.Join(strings.Split(newClient2Server, "\n"), "\r\n") + newClient2Client = strings.Join(strings.Split(newClient2Client, "\n"), "\r\n") + + var cmdbuf bytes.Buffer + bcmdbuf := bufio.NewWriter(&cmdbuf) + var fake faker + fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClient2Server)), bcmdbuf) + c, err := NewClient(fake, "fake.host") + if err != nil { + t.Fatalf("NewClient: %v", err) + } + if ok, _ := c.Extension("DSN"); ok { + t.Fatalf("Shouldn't support DSN") + } + if err := c.Quit(); err != nil { + t.Fatalf("QUIT failed: %s", err) + } + + bcmdbuf.Flush() + actualcmds := cmdbuf.String() + if newClient2Client != actualcmds { + t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClient2Client) + } +} + +var newClient2Server = `220 hello world +502 EH? +250-mx.google.com at your service +250-SIZE 35651584 +250-AUTH LOGIN PLAIN +250 8BITMIME +221 OK +` + +var newClient2Client = `EHLO localhost +HELO localhost +QUIT +` -- 2.50.0