Make Dialer's domain configurable
The net/smtp library sends "localhost" unless otherwise instructed. This commit adds a new "LocalName" field to the Dialer struct that allows users to override what gets sent with SMTP's HELO command. Fixes #40
This commit is contained in:
parent
b1e55520bf
commit
c80f25c521
23
smtp.go
23
smtp.go
|
@ -24,6 +24,9 @@ type Dialer struct {
|
||||||
// TSLConfig represents the TLS configuration used for the TLS (when the
|
// TSLConfig represents the TLS configuration used for the TLS (when the
|
||||||
// STARTTLS extension is used) or SSL connection.
|
// STARTTLS extension is used) or SSL connection.
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
// LocalName is the hostname sent to the SMTP server with the HELO command.
|
||||||
|
// By default, "localhost" is sent.
|
||||||
|
LocalName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPlainDialer returns a Dialer. The given parameters are used to connect to
|
// NewPlainDialer returns a Dialer. The given parameters are used to connect to
|
||||||
|
@ -77,6 +80,12 @@ func (d *Dialer) starttlsDial() (smtpClient, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.LocalName != "" {
|
||||||
|
if err := c.Hello(d.LocalName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ok, _ := c.Extension("STARTTLS"); ok {
|
if ok, _ := c.Extension("STARTTLS"); ok {
|
||||||
if err := c.StartTLS(d.tlsConfig()); err != nil {
|
if err := c.StartTLS(d.tlsConfig()); err != nil {
|
||||||
c.Close()
|
c.Close()
|
||||||
|
@ -93,7 +102,18 @@ func (d *Dialer) sslDial() (smtpClient, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newClient(conn, d.Host)
|
c, err := newClient(conn, d.Host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.LocalName != "" {
|
||||||
|
if err := c.Hello(d.LocalName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dialer) tlsConfig() *tls.Config {
|
func (d *Dialer) tlsConfig() *tls.Config {
|
||||||
|
@ -164,6 +184,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type smtpClient interface {
|
type smtpClient interface {
|
||||||
|
Hello(string) error
|
||||||
Extension(string) (bool, string)
|
Extension(string) (bool, string)
|
||||||
StartTLS(*tls.Config) error
|
StartTLS(*tls.Config) error
|
||||||
Auth(smtp.Auth) error
|
Auth(smtp.Auth) error
|
||||||
|
|
|
@ -56,8 +56,10 @@ func TestDialerSSL(t *testing.T) {
|
||||||
|
|
||||||
func TestDialerConfig(t *testing.T) {
|
func TestDialerConfig(t *testing.T) {
|
||||||
d := NewPlainDialer(testHost, testPort, "user", "pwd")
|
d := NewPlainDialer(testHost, testPort, "user", "pwd")
|
||||||
|
d.LocalName = "test"
|
||||||
d.TLSConfig = testConfig
|
d.TLSConfig = testConfig
|
||||||
testSendMail(t, d, []string{
|
testSendMail(t, d, []string{
|
||||||
|
"Hello test",
|
||||||
"Extension STARTTLS",
|
"Extension STARTTLS",
|
||||||
"StartTLS",
|
"StartTLS",
|
||||||
"Extension AUTH",
|
"Extension AUTH",
|
||||||
|
@ -75,8 +77,10 @@ func TestDialerConfig(t *testing.T) {
|
||||||
|
|
||||||
func TestDialerSSLConfig(t *testing.T) {
|
func TestDialerSSLConfig(t *testing.T) {
|
||||||
d := NewPlainDialer(testHost, testSSLPort, "user", "pwd")
|
d := NewPlainDialer(testHost, testSSLPort, "user", "pwd")
|
||||||
|
d.LocalName = "test"
|
||||||
d.TLSConfig = testConfig
|
d.TLSConfig = testConfig
|
||||||
testSendMail(t, d, []string{
|
testSendMail(t, d, []string{
|
||||||
|
"Hello test",
|
||||||
"Extension AUTH",
|
"Extension AUTH",
|
||||||
"Auth",
|
"Auth",
|
||||||
"Mail " + testFrom,
|
"Mail " + testFrom,
|
||||||
|
@ -118,6 +122,11 @@ type mockClient struct {
|
||||||
config *tls.Config
|
config *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *mockClient) Hello(localName string) error {
|
||||||
|
c.do("Hello " + localName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *mockClient) Extension(ext string) (bool, string) {
|
func (c *mockClient) Extension(ext string) (bool, string) {
|
||||||
c.do("Extension " + ext)
|
c.do("Extension " + ext)
|
||||||
return true, ""
|
return true, ""
|
||||||
|
|
Loading…
Reference in New Issue