diff --git a/DOCS.md b/DOCS.md
index ee2f7f6..2e923b0 100644
--- a/DOCS.md
+++ b/DOCS.md
@@ -10,6 +10,7 @@ You can configure the plugin using the following parameters:
* **username** - SMTP username
* **password** - SMTP password
* **skip_verify** - Skip verification of SSL certificates, defaults to `false`
+* **starttls** - Enable/Disable STARTTLS
* **recipients** - List of recipients to send this mail to (besides the commit author)
* **recipients_file** - Filename to load additional recipients from (textfile with one email per line) (besides the commit author)
* **recipients_only** - Do not send mails to the commit author, but only to **recipients**, defaults to `false`
@@ -127,3 +128,22 @@ steps:
password: 12345
+ skip_verify: true
```
+
+### STARTTLS
+
+By default, STARTTLS is being used opportunistically meaning, if advertised
+by the server, traffic is going to be encrypted.
+
+You may want to disable STARTTLS, e.g., with faulty and/or internal servers:
+
+```diff
+steps:
+ - name: notify
+ image: drillster/drone-email
+ settings:
+ from: noreply@github.com
+ host: smtp.mailgun.org
+ username: octocat
+ password: 12345
++ starttls: false
+```
diff --git a/main.go b/main.go
index 1210307..18499b4 100644
--- a/main.go
+++ b/main.go
@@ -66,6 +66,11 @@ func main() {
Usage: "skip tls verify",
EnvVar: "PLUGIN_SKIP_VERIFY",
},
+ cli.BoolFlag{
+ Name: "starttls",
+ Usage: "Enable/Disable STARTTLS",
+ EnvVar: "PLUGIN_STARTTLS",
+ },
cli.StringFlag{
Name: "recipients.file",
Usage: "file to read recipients from",
@@ -407,6 +412,7 @@ func run(c *cli.Context) error {
Username: c.String("username"),
Password: c.String("password"),
SkipVerify: c.Bool("skip.verify"),
+ StartTLS: c.Bool("starttls"),
Recipients: c.StringSlice("recipients"),
RecipientsFile: c.String("recipients.file"),
RecipientsOnly: c.Bool("recipients.only"),
diff --git a/plugin.go b/plugin.go
index 9057941..35dc85b 100644
--- a/plugin.go
+++ b/plugin.go
@@ -9,7 +9,7 @@ import (
"github.com/aymerick/douceur/inliner"
"github.com/drone/drone-go/template"
"github.com/jaytaylor/html2text"
- "gopkg.in/gomail.v2"
+ gomail "gopkg.in/mail.v2"
)
type (
@@ -88,6 +88,7 @@ type (
Username string
Password string
SkipVerify bool
+ StartTLS bool
Recipients []string
RecipientsFile string
RecipientsOnly bool
@@ -147,9 +148,15 @@ func (p Plugin) Exec() error {
} else {
dialer = gomail.NewDialer(p.Config.Host, p.Config.Port, p.Config.Username, p.Config.Password)
}
+
if p.Config.SkipVerify {
dialer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
}
+
+ if !p.Config.StartTLS {
+ dialer.StartTLSPolicy = gomail.NoStartTLS
+ }
+
dialer.LocalName = p.Config.ClientHostname
closer, err := dialer.Dial()
diff --git a/vendor/gopkg.in/gomail.v2/CHANGELOG.md b/vendor/gopkg.in/gomail.v2/CHANGELOG.md
deleted file mode 100644
index a797ab4..0000000
--- a/vendor/gopkg.in/gomail.v2/CHANGELOG.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Change Log
-All notable changes to this project will be documented in this file.
-This project adheres to [Semantic Versioning](http://semver.org/).
-
-## [2.0.0] - 2015-09-02
-
-- Mailer has been removed. It has been replaced by Dialer and Sender.
-- `File` type and the `CreateFile` and `OpenFile` functions have been removed.
-- `Message.Attach` and `Message.Embed` have a new signature.
-- `Message.GetBodyWriter` has been removed. Use `Message.AddAlternativeWriter`
-instead.
-- `Message.Export` has been removed. `Message.WriteTo` can be used instead.
-- `Message.DelHeader` has been removed.
-- The `Bcc` header field is no longer sent. It is far more simpler and
-efficient: the same message is sent to all recipients instead of sending a
-different email to each Bcc address.
-- LoginAuth has been removed. `NewPlainDialer` now implements the LOGIN
-authentication mechanism when needed.
-- Go 1.2 is now required instead of Go 1.3. No external dependency are used when
-using Go 1.5.
diff --git a/vendor/gopkg.in/gomail.v2/README.md b/vendor/gopkg.in/gomail.v2/README.md
deleted file mode 100644
index b3be9e1..0000000
--- a/vendor/gopkg.in/gomail.v2/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Gomail
-[![Build Status](https://travis-ci.org/go-gomail/gomail.svg?branch=v2)](https://travis-ci.org/go-gomail/gomail) [![Code Coverage](http://gocover.io/_badge/gopkg.in/gomail.v2)](http://gocover.io/gopkg.in/gomail.v2) [![Documentation](https://godoc.org/gopkg.in/gomail.v2?status.svg)](https://godoc.org/gopkg.in/gomail.v2)
-
-## Introduction
-
-Gomail is a simple and efficient package to send emails. It is well tested and
-documented.
-
-Gomail can only send emails using an SMTP server. But the API is flexible and it
-is easy to implement other methods for sending emails using a local Postfix, an
-API, etc.
-
-It is versioned using [gopkg.in](https://gopkg.in) so I promise
-there will never be backward incompatible changes within each version.
-
-It requires Go 1.2 or newer. With Go 1.5, no external dependencies are used.
-
-
-## Features
-
-Gomail supports:
-- Attachments
-- Embedded images
-- HTML and text templates
-- Automatic encoding of special characters
-- SSL and TLS
-- Sending multiple emails with the same SMTP connection
-
-
-## Documentation
-
-https://godoc.org/gopkg.in/gomail.v2
-
-
-## Download
-
- go get gopkg.in/gomail.v2
-
-
-## Examples
-
-See the [examples in the documentation](https://godoc.org/gopkg.in/gomail.v2#example-package).
-
-
-## FAQ
-
-### x509: certificate signed by unknown authority
-
-If you get this error it means the certificate used by the SMTP server is not
-considered valid by the client running Gomail. As a quick workaround you can
-bypass the verification of the server's certificate chain and host name by using
-`SetTLSConfig`:
-
- package main
-
- import (
- "crypto/tls"
-
- "gopkg.in/gomail.v2"
- )
-
- func main() {
- d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
- d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
-
- // Send emails using d.
- }
-
-Note, however, that this is insecure and should not be used in production.
-
-
-## Contribute
-
-Contributions are more than welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for
-more info.
-
-
-## Change log
-
-See [CHANGELOG.md](CHANGELOG.md).
-
-
-## License
-
-[MIT](LICENSE)
-
-
-## Contact
-
-You can ask questions on the [Gomail
-thread](https://groups.google.com/d/topic/golang-nuts/jMxZHzvvEVg/discussion)
-in the Go mailing-list.
diff --git a/vendor/gopkg.in/mail.v2/CHANGELOG.md b/vendor/gopkg.in/mail.v2/CHANGELOG.md
new file mode 100644
index 0000000..cdd898a
--- /dev/null
+++ b/vendor/gopkg.in/mail.v2/CHANGELOG.md
@@ -0,0 +1,88 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
+
+## *Unreleased*
+
+## [2.3.1] - 2018-11-12
+
+### Fixed
+
+- #39: Reverts addition of Go modules `go.mod` manifest.
+
+## [2.3.0] - 2018-11-10
+
+### Added
+
+- #12: Adds `SendError` to provide additional info about the cause and index of
+ a failed attempt to transmit a batch of messages.
+- go-gomail#78: Adds new `Message` methods for attaching and embedding
+ `io.Reader`s: `AttachReader` and `EmbedReader`.
+
+### Fixed
+
+- #26: Fixes RFC 1341 compliance by properly capitalizing the
+ `MIME-Version` header.
+- #30: Fixes IO errors being silently dropped in `Message.WriteTo`.
+
+## [2.2.0] - 2018-03-01
+
+### Added
+
+- #20: Adds `Message.SetBoundary` to allow specifying a custom MIME boundary.
+- #22: Adds `Message.SetBodyWriter` to make it easy to use text/template and
+ html/template for message bodies. Contributed by Quantcast.
+- #25: Adds `Dialer.StartTLSPolicy` so that `MandatoryStartTLS` can be required,
+ or `NoStartTLS` can disable it. Contributed by Quantcast.
+
+## [2.1.0] - 2017-12-14
+
+### Added
+
+- go-gomail#40: Adds `Dialer.LocalName` field to allow specifying the hostname
+ sent with SMTP's HELO command.
+- go-gomail#47: `Message.SetBody`, `Message.AddAlternative`, and
+ `Message.AddAlternativeWriter` allow specifying the encoding of message parts.
+- `Dialer.Dial`'s returned `SendCloser` automatically redials after a timeout.
+- go-gomail#55, go-gomail#56: Adds `Rename` to allow specifying filename
+ of an attachment.
+- go-gomail#100: Exports `NetDialTimeout` to allow setting a custom dialer.
+- go-gomail#70: Adds `Dialer.Timeout` field to allow specifying a timeout for
+ dials, reads, and writes.
+
+### Changed
+
+- go-gomail#52: `Dialer.Dial` automatically uses CRAM-MD5 when available.
+- `Dialer.Dial` specifies a default timeout of 10 seconds.
+- Gomail is forked from to
+ .
+
+### Deprecated
+
+- go-gomail#52: `NewPlainDialer` is deprecated in favor of `NewDialer`.
+
+### Fixed
+
+- go-gomail#41, go-gomail#42: Fixes a panic when a `Message` contains a
+ nil header.
+- go-gomail#44: Fixes `AddAlternativeWriter` replacing the message body instead
+ of adding a body part.
+- go-gomail#53: Folds long header lines for RFC 2047 compliance.
+- go-gomail#54: Fixes `Message.FormatAddress` when name is blank.
+
+## [2.0.0] - 2015-09-02
+
+- Mailer has been removed. It has been replaced by Dialer and Sender.
+- `File` type and the `CreateFile` and `OpenFile` functions have been removed.
+- `Message.Attach` and `Message.Embed` have a new signature.
+- `Message.GetBodyWriter` has been removed. Use `Message.AddAlternativeWriter`
+instead.
+- `Message.Export` has been removed. `Message.WriteTo` can be used instead.
+- `Message.DelHeader` has been removed.
+- The `Bcc` header field is no longer sent. It is far more simpler and
+efficient: the same message is sent to all recipients instead of sending a
+different email to each Bcc address.
+- LoginAuth has been removed. `NewPlainDialer` now implements the LOGIN
+authentication mechanism when needed.
+- Go 1.2 is now required instead of Go 1.3. No external dependency are used when
+using Go 1.5.
diff --git a/vendor/gopkg.in/gomail.v2/CONTRIBUTING.md b/vendor/gopkg.in/mail.v2/CONTRIBUTING.md
similarity index 100%
rename from vendor/gopkg.in/gomail.v2/CONTRIBUTING.md
rename to vendor/gopkg.in/mail.v2/CONTRIBUTING.md
diff --git a/vendor/gopkg.in/gomail.v2/LICENSE b/vendor/gopkg.in/mail.v2/LICENSE
similarity index 100%
rename from vendor/gopkg.in/gomail.v2/LICENSE
rename to vendor/gopkg.in/mail.v2/LICENSE
diff --git a/vendor/gopkg.in/mail.v2/README.md b/vendor/gopkg.in/mail.v2/README.md
new file mode 100644
index 0000000..8cc31b6
--- /dev/null
+++ b/vendor/gopkg.in/mail.v2/README.md
@@ -0,0 +1,129 @@
+# Gomail
+[![Build Status](https://travis-ci.org/go-mail/mail.svg?branch=master)](https://travis-ci.org/go-mail/mail) [![Code Coverage](http://gocover.io/_badge/github.com/go-mail/mail)](http://gocover.io/github.com/go-mail/mail) [![Documentation](https://godoc.org/github.com/go-mail/mail?status.svg)](https://godoc.org/github.com/go-mail/mail)
+
+This is an actively maintained fork of [Gomail][1] and includes fixes and
+improvements for a number of outstanding issues. The current progress is
+as follows:
+
+ - [x] Timeouts and retries can be specified outside of the 10 second default.
+ - [x] Proxying is supported through specifying a custom [NetDialTimeout][2].
+ - [ ] Filenames are properly encoded for non-ASCII characters.
+ - [ ] Email addresses are properly encoded for non-ASCII characters.
+ - [ ] Embedded files and attachments are tested for their existence.
+ - [ ] An `io.Reader` can be supplied when embedding and attaching files.
+
+See [Transitioning Existing Codebases][3] for more information on switching.
+
+[1]: https://github.com/go-gomail/gomail
+[2]: https://godoc.org/gopkg.in/mail.v2#NetDialTimeout
+[3]: #transitioning-existing-codebases
+
+## Introduction
+
+Gomail is a simple and efficient package to send emails. It is well tested and
+documented.
+
+Gomail can only send emails using an SMTP server. But the API is flexible and it
+is easy to implement other methods for sending emails using a local Postfix, an
+API, etc.
+
+It requires Go 1.2 or newer. With Go 1.5, no external dependencies are used.
+
+
+## Features
+
+Gomail supports:
+- Attachments
+- Embedded images
+- HTML and text templates
+- Automatic encoding of special characters
+- SSL and TLS
+- Sending multiple emails with the same SMTP connection
+
+
+## Documentation
+
+https://godoc.org/github.com/go-mail/mail
+
+
+## Download
+
+If you're already using a dependency manager, like [dep][dep], use the following
+import path:
+
+```
+github.com/go-mail/mail
+```
+
+If you *aren't* using vendoring, `go get` the [Gopkg.in](http://gopkg.in)
+import path:
+
+```
+gopkg.in/mail.v2
+```
+
+[dep]: https://github.com/golang/dep#readme
+
+## Examples
+
+See the [examples in the documentation](https://godoc.org/github.com/go-mail/mail#example-package).
+
+
+## FAQ
+
+### x509: certificate signed by unknown authority
+
+If you get this error it means the certificate used by the SMTP server is not
+considered valid by the client running Gomail. As a quick workaround you can
+bypass the verification of the server's certificate chain and host name by using
+`SetTLSConfig`:
+
+```go
+package main
+
+import (
+ "crypto/tls"
+
+ "gopkg.in/mail.v2"
+)
+
+func main() {
+ d := mail.NewDialer("smtp.example.com", 587, "user", "123456")
+ d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
+
+ // Send emails using d.
+}
+```
+
+Note, however, that this is insecure and should not be used in production.
+
+### Transitioning Existing Codebases
+
+If you're already using the original Gomail, switching is as easy as updating
+the import line to:
+
+```
+import gomail "gopkg.in/mail.v2"
+```
+
+## Contribute
+
+Contributions are more than welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for
+more info.
+
+
+## Change log
+
+See [CHANGELOG.md](CHANGELOG.md).
+
+
+## License
+
+[MIT](LICENSE)
+
+
+## Support & Contact
+
+You can ask questions on the [Gomail
+thread](https://groups.google.com/d/topic/golang-nuts/jMxZHzvvEVg/discussion)
+in the Go mailing-list.
diff --git a/vendor/gopkg.in/gomail.v2/auth.go b/vendor/gopkg.in/mail.v2/auth.go
similarity index 98%
rename from vendor/gopkg.in/gomail.v2/auth.go
rename to vendor/gopkg.in/mail.v2/auth.go
index d28b83a..b8c0dde 100644
--- a/vendor/gopkg.in/gomail.v2/auth.go
+++ b/vendor/gopkg.in/mail.v2/auth.go
@@ -1,4 +1,4 @@
-package gomail
+package mail
import (
"bytes"
diff --git a/vendor/gopkg.in/gomail.v2/doc.go b/vendor/gopkg.in/mail.v2/doc.go
similarity index 57%
rename from vendor/gopkg.in/gomail.v2/doc.go
rename to vendor/gopkg.in/mail.v2/doc.go
index a8f5091..d65bf35 100644
--- a/vendor/gopkg.in/gomail.v2/doc.go
+++ b/vendor/gopkg.in/mail.v2/doc.go
@@ -1,5 +1,6 @@
// Package gomail provides a simple interface to compose emails and to mail them
// efficiently.
//
-// More info on Github: https://github.com/go-gomail/gomail
-package gomail
+// More info on Github: https://github.com/go-mail/mail
+//
+package mail
diff --git a/vendor/gopkg.in/mail.v2/errors.go b/vendor/gopkg.in/mail.v2/errors.go
new file mode 100644
index 0000000..770da8c
--- /dev/null
+++ b/vendor/gopkg.in/mail.v2/errors.go
@@ -0,0 +1,16 @@
+package mail
+
+import "fmt"
+
+// A SendError represents the failure to transmit a Message, detailing the cause
+// of the failure and index of the Message within a batch.
+type SendError struct {
+ // Index specifies the index of the Message within a batch.
+ Index uint
+ Cause error
+}
+
+func (err *SendError) Error() string {
+ return fmt.Sprintf("gomail: could not send email %d: %v",
+ err.Index+1, err.Cause)
+}
diff --git a/vendor/gopkg.in/gomail.v2/message.go b/vendor/gopkg.in/mail.v2/message.go
similarity index 82%
rename from vendor/gopkg.in/gomail.v2/message.go
rename to vendor/gopkg.in/mail.v2/message.go
index 4bffb1e..9f7f7bd 100644
--- a/vendor/gopkg.in/gomail.v2/message.go
+++ b/vendor/gopkg.in/mail.v2/message.go
@@ -1,4 +1,4 @@
-package gomail
+package mail
import (
"bytes"
@@ -18,6 +18,7 @@ type Message struct {
encoding Encoding
hEncoder mimeEncoder
buf bytes.Buffer
+ boundary string
}
type header map[string][]string
@@ -97,6 +98,11 @@ const (
Unencoded Encoding = "8bit"
)
+// SetBoundary sets a custom multipart boundary.
+func (m *Message) SetBoundary(boundary string) {
+ m.boundary = boundary
+}
+
// SetHeader sets a value to the given header field.
func (m *Message) SetHeader(field string, value ...string) {
m.encodeHeader(value)
@@ -183,9 +189,15 @@ func (m *Message) GetHeader(field string) []string {
}
// SetBody sets the body of the message. It replaces any content previously set
-// by SetBody, AddAlternative or AddAlternativeWriter.
+// by SetBody, SetBodyWriter, AddAlternative or AddAlternativeWriter.
func (m *Message) SetBody(contentType, body string, settings ...PartSetting) {
- m.parts = []*part{m.newPart(contentType, newCopier(body), settings)}
+ m.SetBodyWriter(contentType, newCopier(body), settings...)
+}
+
+// SetBodyWriter sets the body of the message. It can be useful with the
+// text/template or html/template packages.
+func (m *Message) SetBodyWriter(contentType string, f func(io.Writer) error, settings ...PartSetting) {
+ m.parts = []*part{m.newPart(contentType, f, settings)}
}
// AddAlternative adds an alternative part to the message.
@@ -226,8 +238,8 @@ func (m *Message) newPart(contentType string, f func(io.Writer) error, settings
}
// A PartSetting can be used as an argument in Message.SetBody,
-// Message.AddAlternative or Message.AddAlternativeWriter to configure the part
-// added to a message.
+// Message.SetBodyWriter, Message.AddAlternative or Message.AddAlternativeWriter
+// to configure the part added to a message.
type PartSetting func(*part)
// SetPartEncoding sets the encoding of the part added to the message. By
@@ -283,8 +295,28 @@ func SetCopyFunc(f func(io.Writer) error) FileSetting {
}
}
-func (m *Message) appendFile(list []*file, name string, settings []FileSetting) []*file {
- f := &file{
+// AttachReader attaches a file using an io.Reader
+func (m *Message) AttachReader(name string, r io.Reader, settings ...FileSetting) {
+ m.attachments = m.appendFile(m.attachments, fileFromReader(name, r), settings)
+}
+
+// Attach attaches the files to the email.
+func (m *Message) Attach(filename string, settings ...FileSetting) {
+ m.attachments = m.appendFile(m.attachments, fileFromFilename(filename), settings)
+}
+
+// EmbedReader embeds the images to the email.
+func (m *Message) EmbedReader(name string, r io.Reader, settings ...FileSetting) {
+ m.embedded = m.appendFile(m.embedded, fileFromReader(name, r), settings)
+}
+
+// Embed embeds the images to the email.
+func (m *Message) Embed(filename string, settings ...FileSetting) {
+ m.embedded = m.appendFile(m.embedded, fileFromFilename(filename), settings)
+}
+
+func fileFromFilename(name string) *file {
+ return &file{
Name: filepath.Base(name),
Header: make(map[string][]string),
CopyFunc: func(w io.Writer) error {
@@ -299,7 +331,22 @@ func (m *Message) appendFile(list []*file, name string, settings []FileSetting)
return h.Close()
},
}
+}
+func fileFromReader(name string, r io.Reader) *file {
+ return &file{
+ Name: filepath.Base(name),
+ Header: make(map[string][]string),
+ CopyFunc: func(w io.Writer) error {
+ if _, err := io.Copy(w, r); err != nil {
+ return err
+ }
+ return nil
+ },
+ }
+}
+
+func (m *Message) appendFile(list []*file, f *file, settings []FileSetting) []*file {
for _, s := range settings {
s(f)
}
@@ -310,13 +357,3 @@ func (m *Message) appendFile(list []*file, name string, settings []FileSetting)
return append(list, f)
}
-
-// Attach attaches the files to the email.
-func (m *Message) Attach(filename string, settings ...FileSetting) {
- m.attachments = m.appendFile(m.attachments, filename, settings)
-}
-
-// Embed embeds the images to the email.
-func (m *Message) Embed(filename string, settings ...FileSetting) {
- m.embedded = m.appendFile(m.embedded, filename, settings)
-}
diff --git a/vendor/gopkg.in/gomail.v2/mime.go b/vendor/gopkg.in/mail.v2/mime.go
similarity index 95%
rename from vendor/gopkg.in/gomail.v2/mime.go
rename to vendor/gopkg.in/mail.v2/mime.go
index 194d4a7..d95ea2e 100644
--- a/vendor/gopkg.in/gomail.v2/mime.go
+++ b/vendor/gopkg.in/mail.v2/mime.go
@@ -1,6 +1,6 @@
// +build go1.5
-package gomail
+package mail
import (
"mime"
diff --git a/vendor/gopkg.in/gomail.v2/mime_go14.go b/vendor/gopkg.in/mail.v2/mime_go14.go
similarity index 96%
rename from vendor/gopkg.in/gomail.v2/mime_go14.go
rename to vendor/gopkg.in/mail.v2/mime_go14.go
index 3dc26aa..bdb605d 100644
--- a/vendor/gopkg.in/gomail.v2/mime_go14.go
+++ b/vendor/gopkg.in/mail.v2/mime_go14.go
@@ -1,6 +1,6 @@
// +build !go1.5
-package gomail
+package mail
import "gopkg.in/alexcesaro/quotedprintable.v3"
diff --git a/vendor/gopkg.in/gomail.v2/send.go b/vendor/gopkg.in/mail.v2/send.go
similarity index 94%
rename from vendor/gopkg.in/gomail.v2/send.go
rename to vendor/gopkg.in/mail.v2/send.go
index 9115ebe..62e67f0 100644
--- a/vendor/gopkg.in/gomail.v2/send.go
+++ b/vendor/gopkg.in/mail.v2/send.go
@@ -1,10 +1,10 @@
-package gomail
+package mail
import (
"errors"
"fmt"
"io"
- "net/mail"
+ stdmail "net/mail"
)
// Sender is the interface that wraps the Send method.
@@ -36,7 +36,7 @@ func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
func Send(s Sender, msg ...*Message) error {
for i, m := range msg {
if err := send(s, m); err != nil {
- return fmt.Errorf("gomail: could not send email %d: %v", i+1, err)
+ return &SendError{Cause: err, Index: uint(i)}
}
}
@@ -108,7 +108,7 @@ func addAddress(list []string, addr string) []string {
}
func parseAddress(field string) (string, error) {
- addr, err := mail.ParseAddress(field)
+ addr, err := stdmail.ParseAddress(field)
if err != nil {
return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
}
diff --git a/vendor/gopkg.in/gomail.v2/smtp.go b/vendor/gopkg.in/mail.v2/smtp.go
similarity index 55%
rename from vendor/gopkg.in/gomail.v2/smtp.go
rename to vendor/gopkg.in/mail.v2/smtp.go
index 2aa49c8..547e04d 100644
--- a/vendor/gopkg.in/gomail.v2/smtp.go
+++ b/vendor/gopkg.in/mail.v2/smtp.go
@@ -1,4 +1,4 @@
-package gomail
+package mail
import (
"crypto/tls"
@@ -27,23 +27,39 @@ type Dialer struct {
// most cases since the authentication mechanism should use the STARTTLS
// extension instead.
SSL bool
- // TSLConfig represents the TLS configuration used for the TLS (when the
+ // TLSConfig represents the TLS configuration used for the TLS (when the
// STARTTLS extension is used) or SSL connection.
TLSConfig *tls.Config
+ // StartTLSPolicy represents the TLS security level required to
+ // communicate with the SMTP server.
+ //
+ // This defaults to OpportunisticStartTLS for backwards compatibility,
+ // but we recommend MandatoryStartTLS for all modern SMTP servers.
+ //
+ // This option has no effect if SSL is set to true.
+ StartTLSPolicy StartTLSPolicy
// LocalName is the hostname sent to the SMTP server with the HELO command.
// By default, "localhost" is sent.
LocalName string
+ // Timeout to use for read/write operations. Defaults to 10 seconds, can
+ // be set to 0 to disable timeouts.
+ Timeout time.Duration
+ // Whether we should retry mailing if the connection returned an error,
+ // defaults to true.
+ RetryFailure bool
}
// NewDialer returns a new SMTP Dialer. The given parameters are used to connect
// to the SMTP server.
func NewDialer(host string, port int, username, password string) *Dialer {
return &Dialer{
- Host: host,
- Port: port,
- Username: username,
- Password: password,
- SSL: port == 465,
+ Host: host,
+ Port: port,
+ Username: username,
+ Password: password,
+ SSL: port == 465,
+ Timeout: 10 * time.Second,
+ RetryFailure: true,
}
}
@@ -55,10 +71,15 @@ func NewPlainDialer(host string, port int, username, password string) *Dialer {
return NewDialer(host, port, username, password)
}
+// NetDialTimeout specifies the DialTimeout function to establish a connection
+// to the SMTP server. This can be used to override dialing in the case that a
+// proxy or other special behavior is needed.
+var NetDialTimeout = net.DialTimeout
+
// Dial dials and authenticates to an SMTP server. The returned SendCloser
// should be closed when done using it.
func (d *Dialer) Dial() (SendCloser, error) {
- conn, err := netDialTimeout("tcp", addr(d.Host, d.Port), 10*time.Second)
+ conn, err := NetDialTimeout("tcp", addr(d.Host, d.Port), d.Timeout)
if err != nil {
return nil, err
}
@@ -72,14 +93,25 @@ func (d *Dialer) Dial() (SendCloser, error) {
return nil, err
}
+ if d.Timeout > 0 {
+ conn.SetDeadline(time.Now().Add(d.Timeout))
+ }
+
if d.LocalName != "" {
if err := c.Hello(d.LocalName); err != nil {
return nil, err
}
}
- if !d.SSL {
- if ok, _ := c.Extension("STARTTLS"); ok {
+ if !d.SSL && d.StartTLSPolicy != NoStartTLS {
+ ok, _ := c.Extension("STARTTLS")
+ if !ok && d.StartTLSPolicy == MandatoryStartTLS {
+ err := StartTLSUnsupportedError{
+ Policy: d.StartTLSPolicy}
+ return nil, err
+ }
+
+ if ok {
if err := c.StartTLS(d.tlsConfig()); err != nil {
c.Close()
return nil, err
@@ -111,7 +143,7 @@ func (d *Dialer) Dial() (SendCloser, error) {
}
}
- return &smtpSender{c, d}, nil
+ return &smtpSender{c, conn, d}, nil
}
func (d *Dialer) tlsConfig() *tls.Config {
@@ -121,6 +153,47 @@ func (d *Dialer) tlsConfig() *tls.Config {
return d.TLSConfig
}
+// StartTLSPolicy constants are valid values for Dialer.StartTLSPolicy.
+type StartTLSPolicy int
+
+const (
+ // OpportunisticStartTLS means that SMTP transactions are encrypted if
+ // STARTTLS is supported by the SMTP server. Otherwise, messages are
+ // sent in the clear. This is the default setting.
+ OpportunisticStartTLS StartTLSPolicy = iota
+ // MandatoryStartTLS means that SMTP transactions must be encrypted.
+ // SMTP transactions are aborted unless STARTTLS is supported by the
+ // SMTP server.
+ MandatoryStartTLS
+ // NoStartTLS means encryption is disabled and messages are sent in the
+ // clear.
+ NoStartTLS = -1
+)
+
+func (policy *StartTLSPolicy) String() string {
+ switch *policy {
+ case OpportunisticStartTLS:
+ return "OpportunisticStartTLS"
+ case MandatoryStartTLS:
+ return "MandatoryStartTLS"
+ case NoStartTLS:
+ return "NoStartTLS"
+ default:
+ return fmt.Sprintf("StartTLSPolicy:%v", *policy)
+ }
+}
+
+// StartTLSUnsupportedError is returned by Dial when connecting to an SMTP
+// server that does not support STARTTLS.
+type StartTLSUnsupportedError struct {
+ Policy StartTLSPolicy
+}
+
+func (e StartTLSUnsupportedError) Error() string {
+ return "gomail: " + e.Policy.String() + " required, but " +
+ "SMTP server does not support STARTTLS"
+}
+
func addr(host string, port int) string {
return fmt.Sprintf("%s:%d", host, port)
}
@@ -139,12 +212,29 @@ func (d *Dialer) DialAndSend(m ...*Message) error {
type smtpSender struct {
smtpClient
- d *Dialer
+ conn net.Conn
+ d *Dialer
+}
+
+func (c *smtpSender) retryError(err error) bool {
+ if !c.d.RetryFailure {
+ return false
+ }
+
+ if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
+ return true
+ }
+
+ return err == io.EOF
}
func (c *smtpSender) Send(from string, to []string, msg io.WriterTo) error {
+ if c.d.Timeout > 0 {
+ c.conn.SetDeadline(time.Now().Add(c.d.Timeout))
+ }
+
if err := c.Mail(from); err != nil {
- if err == io.EOF {
+ if c.retryError(err) {
// This is probably due to a timeout, so reconnect and try again.
sc, derr := c.d.Dial()
if derr == nil {
@@ -154,6 +244,7 @@ func (c *smtpSender) Send(from string, to []string, msg io.WriterTo) error {
}
}
}
+
return err
}
@@ -182,9 +273,8 @@ func (c *smtpSender) Close() error {
// Stubbed out for tests.
var (
- netDialTimeout = net.DialTimeout
- tlsClient = tls.Client
- smtpNewClient = func(conn net.Conn, host string) (smtpClient, error) {
+ tlsClient = tls.Client
+ smtpNewClient = func(conn net.Conn, host string) (smtpClient, error) {
return smtp.NewClient(conn, host)
}
)
diff --git a/vendor/gopkg.in/gomail.v2/writeto.go b/vendor/gopkg.in/mail.v2/writeto.go
similarity index 93%
rename from vendor/gopkg.in/gomail.v2/writeto.go
rename to vendor/gopkg.in/mail.v2/writeto.go
index 9fb6b86..faf6124 100644
--- a/vendor/gopkg.in/gomail.v2/writeto.go
+++ b/vendor/gopkg.in/mail.v2/writeto.go
@@ -1,4 +1,4 @@
-package gomail
+package mail
import (
"encoding/base64"
@@ -19,8 +19,8 @@ func (m *Message) WriteTo(w io.Writer) (int64, error) {
}
func (w *messageWriter) writeMessage(m *Message) {
- if _, ok := m.header["Mime-Version"]; !ok {
- w.writeString("Mime-Version: 1.0\r\n")
+ if _, ok := m.header["MIME-Version"]; !ok {
+ w.writeString("MIME-Version: 1.0\r\n")
}
if _, ok := m.header["Date"]; !ok {
w.writeHeader("Date", m.FormatDate(now()))
@@ -28,15 +28,15 @@ func (w *messageWriter) writeMessage(m *Message) {
w.writeHeaders(m.header)
if m.hasMixedPart() {
- w.openMultipart("mixed")
+ w.openMultipart("mixed", m.boundary)
}
if m.hasRelatedPart() {
- w.openMultipart("related")
+ w.openMultipart("related", m.boundary)
}
if m.hasAlternativePart() {
- w.openMultipart("alternative")
+ w.openMultipart("alternative", m.boundary)
}
for _, part := range m.parts {
w.writePart(part, m.charset)
@@ -77,8 +77,11 @@ type messageWriter struct {
err error
}
-func (w *messageWriter) openMultipart(mimeType string) {
+func (w *messageWriter) openMultipart(mimeType, boundary string) {
mw := multipart.NewWriter(w)
+ if boundary != "" {
+ mw.SetBoundary(boundary)
+ }
contentType := "multipart/" + mimeType + ";\r\n boundary=" + mw.Boundary()
w.writers[w.depth] = mw
@@ -158,7 +161,11 @@ func (w *messageWriter) Write(p []byte) (int, error) {
}
func (w *messageWriter) writeString(s string) {
- n, _ := io.WriteString(w.w, s)
+ if w.err != nil { // do nothing when in error
+ return
+ }
+ var n int
+ n, w.err = io.WriteString(w.w, s)
w.n += int64(n)
}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 67be634..01e92ec 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -129,10 +129,10 @@
"revisionTime": "2015-07-16T17:19:45Z"
},
{
- "checksumSHA1": "iq5WdjScmTU+LfNoerLuwcnXpdM=",
- "path": "gopkg.in/gomail.v2",
- "revision": "81ebce5c23dfd25c6c67194b37d3dd3f338c98b1",
- "revisionTime": "2016-04-11T21:29:32Z"
+ "checksumSHA1": "SoHkt4HLtGvg9wZIDX6BJTqkDgs=",
+ "path": "gopkg.in/mail.v2",
+ "revision": "f59b9b83a4e522098e3d3eb94e6f81850ad6e973",
+ "revisionTime": "2018-11-12T22:01:18Z"
},
{
"checksumSHA1": "12GqsW8PiRPnezDDy0v4brZrndM=",