summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2017-08-17 17:19:06 -0700
committerGitHub <noreply@github.com>2017-08-17 17:19:06 -0700
commit96eab1202717e073782ec399a4e0820cae15b1bb (patch)
tree011012982be971c7e9ef91466f026bc0956ac9a2 /vendor/gopkg.in
parent2c895ee66eed626721135acfcc48254c6e3f3b29 (diff)
downloadchat-96eab1202717e073782ec399a4e0820cae15b1bb.tar.gz
chat-96eab1202717e073782ec399a4e0820cae15b1bb.tar.bz2
chat-96eab1202717e073782ec399a4e0820cae15b1bb.zip
Updating server dependancies. (#7246)
Diffstat (limited to 'vendor/gopkg.in')
-rw-r--r--vendor/gopkg.in/gomail.v2/.travis.yml1
-rw-r--r--vendor/gopkg.in/gomail.v2/README.md43
-rw-r--r--vendor/gopkg.in/gomail.v2/auth.go52
-rw-r--r--vendor/gopkg.in/gomail.v2/auth_test.go88
-rw-r--r--vendor/gopkg.in/gomail.v2/example_test.go14
-rw-r--r--vendor/gopkg.in/gomail.v2/message.go96
-rw-r--r--vendor/gopkg.in/gomail.v2/message_test.go177
-rw-r--r--vendor/gopkg.in/gomail.v2/mime.go6
-rw-r--r--vendor/gopkg.in/gomail.v2/mime_go14.go13
-rw-r--r--vendor/gopkg.in/gomail.v2/send.go11
-rw-r--r--vendor/gopkg.in/gomail.v2/smtp.go125
-rw-r--r--vendor/gopkg.in/gomail.v2/smtp_test.go118
-rw-r--r--vendor/gopkg.in/gomail.v2/writeto.go96
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/client.go9
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/client_test.go16
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/retry_test.go6
-rwxr-xr-xvendor/gopkg.in/olivere/elastic.v5/run-es-5.5.1.sh1
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms.go110
-rw-r--r--vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms_test.go51
-rw-r--r--vendor/gopkg.in/yaml.v2/LICENSE208
-rw-r--r--vendor/gopkg.in/yaml.v2/README.md2
-rw-r--r--vendor/gopkg.in/yaml.v2/decode_test.go10
-rw-r--r--vendor/gopkg.in/yaml.v2/example_embedded_test.go41
-rw-r--r--vendor/gopkg.in/yaml.v2/scannerc.go9
24 files changed, 714 insertions, 589 deletions
diff --git a/vendor/gopkg.in/gomail.v2/.travis.yml b/vendor/gopkg.in/gomail.v2/.travis.yml
index 48915e737..24edf22cc 100644
--- a/vendor/gopkg.in/gomail.v2/.travis.yml
+++ b/vendor/gopkg.in/gomail.v2/.travis.yml
@@ -5,5 +5,4 @@ go:
- 1.3
- 1.4
- 1.5
- - 1.6
- tip
diff --git a/vendor/gopkg.in/gomail.v2/README.md b/vendor/gopkg.in/gomail.v2/README.md
index b3be9e146..18cb88130 100644
--- a/vendor/gopkg.in/gomail.v2/README.md
+++ b/vendor/gopkg.in/gomail.v2/README.md
@@ -6,12 +6,8 @@
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.
+they 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.
@@ -25,6 +21,7 @@ Gomail supports:
- Automatic encoding of special characters
- SSL and TLS
- Sending multiple emails with the same SMTP connection
+- Any method to send emails: SMTP, postfix (not included but easily doable), etc
## Documentation
@@ -51,20 +48,8 @@ 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.
- }
+ d := gomail.NewPlainDialer("smtp.example.com", "user", "123456", 587)
+ d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
Note, however, that this is insecure and should not be used in production.
@@ -90,3 +75,23 @@ See [CHANGELOG.md](CHANGELOG.md).
You can ask questions on the [Gomail
thread](https://groups.google.com/d/topic/golang-nuts/jMxZHzvvEVg/discussion)
in the Go mailing-list.
+
+
+## Support
+
+If you want to support the development of Gomail, I gladly accept donations.
+
+I will give 100% of the money I receive to
+[Enfants, Espoir Du Monde](http://www.eedm.fr/).
+EEDM is a French NGO which helps children in Bangladesh, Cameroun, Haiti, India
+and Madagascar.
+
+All its members are volunteers so its operating costs are only
+1.9%. So your money will directly helps children of these countries.
+
+As an added bonus, your donations will also tip me by lowering my taxes :smile:
+
+I will send an email with the receipt of the donation to EEDM annually to all
+donors.
+
+[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PYQKC7VFVXCFG)
diff --git a/vendor/gopkg.in/gomail.v2/auth.go b/vendor/gopkg.in/gomail.v2/auth.go
index d28b83ab7..4bcdd0620 100644
--- a/vendor/gopkg.in/gomail.v2/auth.go
+++ b/vendor/gopkg.in/gomail.v2/auth.go
@@ -7,33 +7,51 @@ import (
"net/smtp"
)
-// loginAuth is an smtp.Auth that implements the LOGIN authentication mechanism.
-type loginAuth struct {
+// plainAuth is an smtp.Auth that implements the PLAIN authentication mechanism.
+// It fallbacks to the LOGIN mechanism if it is the only mechanism advertised
+// by the server.
+type plainAuth struct {
username string
password string
host string
+ login bool
}
-func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
- if !server.TLS {
- advertised := false
- for _, mechanism := range server.Auth {
- if mechanism == "LOGIN" {
- advertised = true
- break
- }
- }
- if !advertised {
- return "", nil, errors.New("gomail: unencrypted connection")
- }
- }
+func (a *plainAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
if server.Name != a.host {
return "", nil, errors.New("gomail: wrong host name")
}
- return "LOGIN", nil, nil
+
+ var plain, login bool
+ for _, a := range server.Auth {
+ switch a {
+ case "PLAIN":
+ plain = true
+ case "LOGIN":
+ login = true
+ }
+ }
+
+ if !server.TLS && !plain && !login {
+ return "", nil, errors.New("gomail: unencrypted connection")
+ }
+
+ if !plain && login {
+ a.login = true
+ return "LOGIN", nil, nil
+ }
+
+ return "PLAIN", []byte("\x00" + a.username + "\x00" + a.password), nil
}
-func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
+func (a *plainAuth) Next(fromServer []byte, more bool) ([]byte, error) {
+ if !a.login {
+ if more {
+ return nil, errors.New("gomail: unexpected server challenge")
+ }
+ return nil, nil
+ }
+
if !more {
return nil, nil
}
diff --git a/vendor/gopkg.in/gomail.v2/auth_test.go b/vendor/gopkg.in/gomail.v2/auth_test.go
index 428ef3467..20b477214 100644
--- a/vendor/gopkg.in/gomail.v2/auth_test.go
+++ b/vendor/gopkg.in/gomail.v2/auth_test.go
@@ -11,51 +11,103 @@ const (
testHost = "smtp.example.com"
)
-type authTest struct {
+var testAuth = &plainAuth{
+ username: testUser,
+ password: testPwd,
+ host: testHost,
+}
+
+type plainAuthTest struct {
auths []string
challenges []string
tls bool
+ wantProto string
wantData []string
wantError bool
}
func TestNoAdvertisement(t *testing.T) {
- testLoginAuth(t, &authTest{
- auths: []string{},
- tls: false,
- wantError: true,
+ testPlainAuth(t, &plainAuthTest{
+ auths: []string{},
+ challenges: []string{"Username:", "Password:"},
+ tls: false,
+ wantProto: "PLAIN",
+ wantError: true,
})
}
func TestNoAdvertisementTLS(t *testing.T) {
- testLoginAuth(t, &authTest{
+ testPlainAuth(t, &plainAuthTest{
auths: []string{},
challenges: []string{"Username:", "Password:"},
tls: true,
- wantData: []string{"", testUser, testPwd},
+ wantProto: "PLAIN",
+ wantData: []string{"\x00" + testUser + "\x00" + testPwd},
})
}
-func TestLogin(t *testing.T) {
- testLoginAuth(t, &authTest{
+func TestPlain(t *testing.T) {
+ testPlainAuth(t, &plainAuthTest{
+ auths: []string{"PLAIN"},
+ challenges: []string{"Username:", "Password:"},
+ tls: false,
+ wantProto: "PLAIN",
+ wantData: []string{"\x00" + testUser + "\x00" + testPwd},
+ })
+}
+
+func TestPlainTLS(t *testing.T) {
+ testPlainAuth(t, &plainAuthTest{
+ auths: []string{"PLAIN"},
+ challenges: []string{"Username:", "Password:"},
+ tls: true,
+ wantProto: "PLAIN",
+ wantData: []string{"\x00" + testUser + "\x00" + testPwd},
+ })
+}
+
+func TestPlainAndLogin(t *testing.T) {
+ testPlainAuth(t, &plainAuthTest{
auths: []string{"PLAIN", "LOGIN"},
challenges: []string{"Username:", "Password:"},
tls: false,
+ wantProto: "PLAIN",
+ wantData: []string{"\x00" + testUser + "\x00" + testPwd},
+ })
+}
+
+func TestPlainAndLoginTLS(t *testing.T) {
+ testPlainAuth(t, &plainAuthTest{
+ auths: []string{"PLAIN", "LOGIN"},
+ challenges: []string{"Username:", "Password:"},
+ tls: true,
+ wantProto: "PLAIN",
+ wantData: []string{"\x00" + testUser + "\x00" + testPwd},
+ })
+}
+
+func TestLogin(t *testing.T) {
+ testPlainAuth(t, &plainAuthTest{
+ auths: []string{"LOGIN"},
+ challenges: []string{"Username:", "Password:"},
+ tls: false,
+ wantProto: "LOGIN",
wantData: []string{"", testUser, testPwd},
})
}
func TestLoginTLS(t *testing.T) {
- testLoginAuth(t, &authTest{
+ testPlainAuth(t, &plainAuthTest{
auths: []string{"LOGIN"},
challenges: []string{"Username:", "Password:"},
tls: true,
+ wantProto: "LOGIN",
wantData: []string{"", testUser, testPwd},
})
}
-func testLoginAuth(t *testing.T, test *authTest) {
- auth := &loginAuth{
+func testPlainAuth(t *testing.T, test *plainAuthTest) {
+ auth := &plainAuth{
username: testUser,
password: testPwd,
host: testHost,
@@ -67,13 +119,13 @@ func testLoginAuth(t *testing.T, test *authTest) {
}
proto, toServer, err := auth.Start(server)
if err != nil && !test.wantError {
- t.Fatalf("loginAuth.Start(): %v", err)
+ t.Fatalf("plainAuth.Start(): %v", err)
}
if err != nil && test.wantError {
return
}
- if proto != "LOGIN" {
- t.Errorf("invalid protocol, got %q, want LOGIN", proto)
+ if proto != test.wantProto {
+ t.Errorf("invalid protocol, got %q, want %q", proto, test.wantProto)
}
i := 0
@@ -82,6 +134,10 @@ func testLoginAuth(t *testing.T, test *authTest) {
t.Errorf("Invalid response, got %q, want %q", got, test.wantData[i])
}
+ if proto == "PLAIN" {
+ return
+ }
+
for _, challenge := range test.challenges {
i++
if i >= len(test.wantData) {
@@ -90,7 +146,7 @@ func testLoginAuth(t *testing.T, test *authTest) {
toServer, err = auth.Next([]byte(challenge), true)
if err != nil {
- t.Fatalf("loginAuth.Auth(): %v", err)
+ t.Fatalf("plainAuth.Auth(): %v", err)
}
got = string(toServer)
if got != test.wantData[i] {
diff --git a/vendor/gopkg.in/gomail.v2/example_test.go b/vendor/gopkg.in/gomail.v2/example_test.go
index 90008abe8..8d9c6c293 100644
--- a/vendor/gopkg.in/gomail.v2/example_test.go
+++ b/vendor/gopkg.in/gomail.v2/example_test.go
@@ -19,7 +19,7 @@ func Example() {
m.SetBody("text/html", "Hello <b>Bob</b> and <i>Cora</i>!")
m.Attach("/home/Alex/lolcat.jpg")
- d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
+ d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
// Send the email to Bob, Cora and Dan.
if err := d.DialAndSend(m); err != nil {
@@ -32,7 +32,7 @@ func Example_daemon() {
ch := make(chan *gomail.Message)
go func() {
- d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
+ d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
var s gomail.SendCloser
var err error
@@ -79,7 +79,7 @@ func Example_newsletter() {
Address string
}
- d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
+ d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
s, err := d.Dial()
if err != nil {
panic(err)
@@ -151,10 +151,6 @@ func ExampleSetHeader() {
m.Attach("foo.jpg", gomail.SetHeader(h))
}
-func ExampleRename() {
- m.Attach("/tmp/0000146.jpg", gomail.Rename("picture.jpg"))
-}
-
func ExampleMessage_AddAlternative() {
m.SetBody("text/plain", "Hello!")
m.AddAlternative("text/html", "<p>Hello!</p>")
@@ -217,7 +213,3 @@ func ExampleSetCharset() {
func ExampleSetEncoding() {
m = gomail.NewMessage(gomail.SetEncoding(gomail.Base64))
}
-
-func ExampleSetPartEncoding() {
- m.SetBody("text/plain", "Hello!", gomail.SetPartEncoding(gomail.Unencoded))
-}
diff --git a/vendor/gopkg.in/gomail.v2/message.go b/vendor/gopkg.in/gomail.v2/message.go
index 4bffb1e7f..2f75368bd 100644
--- a/vendor/gopkg.in/gomail.v2/message.go
+++ b/vendor/gopkg.in/gomail.v2/message.go
@@ -11,7 +11,7 @@ import (
// Message represents an email.
type Message struct {
header header
- parts []*part
+ parts []part
attachments []*file
embedded []*file
charset string
@@ -23,9 +23,8 @@ type Message struct {
type header map[string][]string
type part struct {
- contentType string
- copier func(io.Writer) error
- encoding Encoding
+ header header
+ copier func(io.Writer) error
}
// NewMessage creates a new message. It uses UTF-8 and quoted-printable encoding
@@ -127,10 +126,6 @@ func (m *Message) SetAddressHeader(field, address, name string) {
// FormatAddress formats an address and a name as a valid RFC 5322 address.
func (m *Message) FormatAddress(address, name string) string {
- if name == "" {
- return address
- }
-
enc := m.encodeString(name)
if enc == name {
m.buf.WriteByte('"')
@@ -182,60 +177,53 @@ func (m *Message) GetHeader(field string) []string {
return m.header[field]
}
-// SetBody sets the body of the message. It replaces any content previously set
-// by SetBody, AddAlternative or AddAlternativeWriter.
-func (m *Message) SetBody(contentType, body string, settings ...PartSetting) {
- m.parts = []*part{m.newPart(contentType, newCopier(body), settings)}
+// SetBody sets the body of the message.
+func (m *Message) SetBody(contentType, body string) {
+ m.parts = []part{
+ {
+ header: m.getPartHeader(contentType),
+ copier: func(w io.Writer) error {
+ _, err := io.WriteString(w, body)
+ return err
+ },
+ },
+ }
}
// AddAlternative adds an alternative part to the message.
//
// It is commonly used to send HTML emails that default to the plain text
-// version for backward compatibility. AddAlternative appends the new part to
-// the end of the message. So the plain text part should be added before the
-// HTML part. See http://en.wikipedia.org/wiki/MIME#Alternative
-func (m *Message) AddAlternative(contentType, body string, settings ...PartSetting) {
- m.AddAlternativeWriter(contentType, newCopier(body), settings...)
-}
-
-func newCopier(s string) func(io.Writer) error {
- return func(w io.Writer) error {
- _, err := io.WriteString(w, s)
- return err
- }
+// version for backward compatibility.
+//
+// More info: http://en.wikipedia.org/wiki/MIME#Alternative
+func (m *Message) AddAlternative(contentType, body string) {
+ m.parts = append(m.parts,
+ part{
+ header: m.getPartHeader(contentType),
+ copier: func(w io.Writer) error {
+ _, err := io.WriteString(w, body)
+ return err
+ },
+ },
+ )
}
// AddAlternativeWriter adds an alternative part to the message. It can be
// useful with the text/template or html/template packages.
-func (m *Message) AddAlternativeWriter(contentType string, f func(io.Writer) error, settings ...PartSetting) {
- m.parts = append(m.parts, m.newPart(contentType, f, settings))
-}
-
-func (m *Message) newPart(contentType string, f func(io.Writer) error, settings []PartSetting) *part {
- p := &part{
- contentType: contentType,
- copier: f,
- encoding: m.encoding,
- }
-
- for _, s := range settings {
- s(p)
+func (m *Message) AddAlternativeWriter(contentType string, f func(io.Writer) error) {
+ m.parts = []part{
+ {
+ header: m.getPartHeader(contentType),
+ copier: f,
+ },
}
-
- return p
}
-// A PartSetting can be used as an argument in Message.SetBody,
-// 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
-// default, parts use the same encoding than the message.
-func SetPartEncoding(e Encoding) PartSetting {
- return PartSetting(func(p *part) {
- p.encoding = e
- })
+func (m *Message) getPartHeader(contentType string) header {
+ return map[string][]string{
+ "Content-Type": {contentType + "; charset=" + m.charset},
+ "Content-Transfer-Encoding": {string(m.encoding)},
+ }
}
type file struct {
@@ -264,14 +252,6 @@ func SetHeader(h map[string][]string) FileSetting {
}
}
-// Rename is a file setting to set the name of the attachment if the name is
-// different than the filename on disk.
-func Rename(name string) FileSetting {
- return func(f *file) {
- f.Name = name
- }
-}
-
// SetCopyFunc is a file setting to replace the function that runs when the
// message is sent. It should copy the content of the file to the io.Writer.
//
diff --git a/vendor/gopkg.in/gomail.v2/message_test.go b/vendor/gopkg.in/gomail.v2/message_test.go
index acceff2a6..fdd9ff9bd 100644
--- a/vendor/gopkg.in/gomail.v2/message_test.go
+++ b/vendor/gopkg.in/gomail.v2/message_test.go
@@ -63,6 +63,29 @@ func TestMessage(t *testing.T) {
testMessage(t, m, 0, want)
}
+func TestBodyWriter(t *testing.T) {
+ m := NewMessage()
+ m.SetHeader("From", "from@example.com")
+ m.SetHeader("To", "to@example.com")
+ m.AddAlternativeWriter("text/plain", func(w io.Writer) error {
+ _, err := w.Write([]byte("Test message"))
+ return err
+ })
+
+ want := &message{
+ from: "from@example.com",
+ to: []string{"to@example.com"},
+ content: "From: from@example.com\r\n" +
+ "To: to@example.com\r\n" +
+ "Content-Type: text/plain; charset=UTF-8\r\n" +
+ "Content-Transfer-Encoding: quoted-printable\r\n" +
+ "\r\n" +
+ "Test message",
+ }
+
+ testMessage(t, m, 0, want)
+}
+
func TestCustomMessage(t *testing.T) {
m := NewMessage(SetCharset("ISO-8859-1"), SetEncoding(Base64))
m.SetHeaders(map[string][]string{
@@ -150,8 +173,7 @@ func TestAlternative(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/alternative;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/alternative; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
@@ -169,74 +191,6 @@ func TestAlternative(t *testing.T) {
testMessage(t, m, 1, want)
}
-func TestPartSetting(t *testing.T) {
- m := NewMessage()
- m.SetHeader("From", "from@example.com")
- m.SetHeader("To", "to@example.com")
- m.SetBody("text/plain; format=flowed", "¡Hola, señor!", SetPartEncoding(Unencoded))
- m.AddAlternative("text/html", "¡<b>Hola</b>, <i>señor</i>!</h1>")
-
- want := &message{
- from: "from@example.com",
- to: []string{"to@example.com"},
- content: "From: from@example.com\r\n" +
- "To: to@example.com\r\n" +
- "Content-Type: multipart/alternative;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
- "\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: text/plain; format=flowed; charset=UTF-8\r\n" +
- "Content-Transfer-Encoding: 8bit\r\n" +
- "\r\n" +
- "¡Hola, señor!\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: text/html; charset=UTF-8\r\n" +
- "Content-Transfer-Encoding: quoted-printable\r\n" +
- "\r\n" +
- "=C2=A1<b>Hola</b>, <i>se=C3=B1or</i>!</h1>\r\n" +
- "--_BOUNDARY_1_--\r\n",
- }
-
- testMessage(t, m, 1, want)
-}
-
-func TestBodyWriter(t *testing.T) {
- m := NewMessage()
- m.SetHeader("From", "from@example.com")
- m.SetHeader("To", "to@example.com")
- m.AddAlternativeWriter("text/plain", func(w io.Writer) error {
- _, err := w.Write([]byte("Test message"))
- return err
- })
- m.AddAlternativeWriter("text/html", func(w io.Writer) error {
- _, err := w.Write([]byte("Test HTML"))
- return err
- })
-
- want := &message{
- from: "from@example.com",
- to: []string{"to@example.com"},
- content: "From: from@example.com\r\n" +
- "To: to@example.com\r\n" +
- "Content-Type: multipart/alternative;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
- "\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: text/plain; charset=UTF-8\r\n" +
- "Content-Transfer-Encoding: quoted-printable\r\n" +
- "\r\n" +
- "Test message\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: text/html; charset=UTF-8\r\n" +
- "Content-Transfer-Encoding: quoted-printable\r\n" +
- "\r\n" +
- "Test HTML\r\n" +
- "--_BOUNDARY_1_--\r\n",
- }
-
- testMessage(t, m, 1, want)
-}
-
func TestAttachmentOnly(t *testing.T) {
m := NewMessage()
m.SetHeader("From", "from@example.com")
@@ -270,8 +224,7 @@ func TestAttachment(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/mixed;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/mixed; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
@@ -290,40 +243,6 @@ func TestAttachment(t *testing.T) {
testMessage(t, m, 1, want)
}
-func TestRename(t *testing.T) {
- m := NewMessage()
- m.SetHeader("From", "from@example.com")
- m.SetHeader("To", "to@example.com")
- m.SetBody("text/plain", "Test")
- name, copy := mockCopyFile("/tmp/test.pdf")
- rename := Rename("another.pdf")
- m.Attach(name, copy, rename)
-
- want := &message{
- from: "from@example.com",
- to: []string{"to@example.com"},
- content: "From: from@example.com\r\n" +
- "To: to@example.com\r\n" +
- "Content-Type: multipart/mixed;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
- "\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: text/plain; charset=UTF-8\r\n" +
- "Content-Transfer-Encoding: quoted-printable\r\n" +
- "\r\n" +
- "Test\r\n" +
- "--_BOUNDARY_1_\r\n" +
- "Content-Type: application/pdf; name=\"another.pdf\"\r\n" +
- "Content-Disposition: attachment; filename=\"another.pdf\"\r\n" +
- "Content-Transfer-Encoding: base64\r\n" +
- "\r\n" +
- base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" +
- "--_BOUNDARY_1_--\r\n",
- }
-
- testMessage(t, m, 1, want)
-}
-
func TestAttachmentsOnly(t *testing.T) {
m := NewMessage()
m.SetHeader("From", "from@example.com")
@@ -336,8 +255,7 @@ func TestAttachmentsOnly(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/mixed;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/mixed; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
"Content-Type: application/pdf; name=\"test.pdf\"\r\n" +
@@ -370,8 +288,7 @@ func TestAttachments(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/mixed;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/mixed; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
@@ -409,8 +326,7 @@ func TestEmbedded(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/related;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/related; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
@@ -451,16 +367,13 @@ func TestFullMessage(t *testing.T) {
to: []string{"to@example.com"},
content: "From: from@example.com\r\n" +
"To: to@example.com\r\n" +
- "Content-Type: multipart/mixed;\r\n" +
- " boundary=_BOUNDARY_1_\r\n" +
+ "Content-Type: multipart/mixed; boundary=_BOUNDARY_1_\r\n" +
"\r\n" +
"--_BOUNDARY_1_\r\n" +
- "Content-Type: multipart/related;\r\n" +
- " boundary=_BOUNDARY_2_\r\n" +
+ "Content-Type: multipart/related; boundary=_BOUNDARY_2_\r\n" +
"\r\n" +
"--_BOUNDARY_2_\r\n" +
- "Content-Type: multipart/alternative;\r\n" +
- " boundary=_BOUNDARY_3_\r\n" +
+ "Content-Type: multipart/alternative; boundary=_BOUNDARY_3_\r\n" +
"\r\n" +
"--_BOUNDARY_3_\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
@@ -564,34 +477,6 @@ func TestBase64LineLength(t *testing.T) {
testMessage(t, m, 0, want)
}
-func TestEmptyName(t *testing.T) {
- m := NewMessage()
- m.SetAddressHeader("From", "from@example.com", "")
-
- want := &message{
- from: "from@example.com",
- content: "From: from@example.com\r\n",
- }
-
- testMessage(t, m, 0, want)
-}
-
-func TestEmptyHeader(t *testing.T) {
- m := NewMessage()
- m.SetHeaders(map[string][]string{
- "From": {"from@example.com"},
- "X-Empty": nil,
- })
-
- want := &message{
- from: "from@example.com",
- content: "From: from@example.com\r\n" +
- "X-Empty:\r\n",
- }
-
- testMessage(t, m, 0, want)
-}
-
func testMessage(t *testing.T, m *Message, bCount int, want *message) {
err := Send(stubSendMail(t, bCount, want), m)
if err != nil {
diff --git a/vendor/gopkg.in/gomail.v2/mime.go b/vendor/gopkg.in/gomail.v2/mime.go
index 194d4a769..51cba724b 100644
--- a/vendor/gopkg.in/gomail.v2/mime.go
+++ b/vendor/gopkg.in/gomail.v2/mime.go
@@ -5,7 +5,6 @@ package gomail
import (
"mime"
"mime/quotedprintable"
- "strings"
)
var newQPWriter = quotedprintable.NewWriter
@@ -15,7 +14,6 @@ type mimeEncoder struct {
}
var (
- bEncoding = mimeEncoder{mime.BEncoding}
- qEncoding = mimeEncoder{mime.QEncoding}
- lastIndexByte = strings.LastIndexByte
+ bEncoding = mimeEncoder{mime.BEncoding}
+ qEncoding = mimeEncoder{mime.QEncoding}
)
diff --git a/vendor/gopkg.in/gomail.v2/mime_go14.go b/vendor/gopkg.in/gomail.v2/mime_go14.go
index 3dc26aa2a..246e2e5e5 100644
--- a/vendor/gopkg.in/gomail.v2/mime_go14.go
+++ b/vendor/gopkg.in/gomail.v2/mime_go14.go
@@ -11,15 +11,6 @@ type mimeEncoder struct {
}
var (
- bEncoding = mimeEncoder{quotedprintable.BEncoding}
- qEncoding = mimeEncoder{quotedprintable.QEncoding}
- lastIndexByte = func(s string, c byte) int {
- for i := len(s) - 1; i >= 0; i-- {
-
- if s[i] == c {
- return i
- }
- }
- return -1
- }
+ bEncoding = mimeEncoder{quotedprintable.BEncoding}
+ qEncoding = mimeEncoder{quotedprintable.QEncoding}
)
diff --git a/vendor/gopkg.in/gomail.v2/send.go b/vendor/gopkg.in/gomail.v2/send.go
index 9115ebe72..3e6726509 100644
--- a/vendor/gopkg.in/gomail.v2/send.go
+++ b/vendor/gopkg.in/gomail.v2/send.go
@@ -20,7 +20,7 @@ type SendCloser interface {
Close() error
}
-// A SendFunc is a function that sends emails to the given addresses.
+// A SendFunc is a function that sends emails to the given adresses.
//
// The SendFunc type is an adapter to allow the use of ordinary functions as
// email senders. If f is a function with the appropriate signature, SendFunc(f)
@@ -108,9 +108,10 @@ func addAddress(list []string, addr string) []string {
}
func parseAddress(field string) (string, error) {
- addr, err := mail.ParseAddress(field)
- if err != nil {
- return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
+ a, err := mail.ParseAddress(field)
+ if a == nil {
+ return "", err
}
- return addr.Address, nil
+
+ return a.Address, err
}
diff --git a/vendor/gopkg.in/gomail.v2/smtp.go b/vendor/gopkg.in/gomail.v2/smtp.go
index 2aa49c8b6..cf773a102 100644
--- a/vendor/gopkg.in/gomail.v2/smtp.go
+++ b/vendor/gopkg.in/gomail.v2/smtp.go
@@ -6,8 +6,6 @@ import (
"io"
"net"
"net/smtp"
- "strings"
- "time"
)
// A Dialer is a dialer to an SMTP server.
@@ -16,10 +14,6 @@ type Dialer struct {
Host string
// Port represents the port of the SMTP server.
Port int
- // Username is the username to use to authenticate to the SMTP server.
- Username string
- // Password is the password to use to authenticate to the SMTP server.
- Password string
// Auth represents the authentication mechanism used to authenticate to the
// SMTP server.
Auth smtp.Auth
@@ -30,94 +24,83 @@ type Dialer struct {
// TSLConfig represents the TLS configuration used for the TLS (when the
// STARTTLS extension is used) or SSL connection.
TLSConfig *tls.Config
- // LocalName is the hostname sent to the SMTP server with the HELO command.
- // By default, "localhost" is sent.
- LocalName string
}
-// 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,
- }
-}
-
-// NewPlainDialer returns a new SMTP Dialer. The given parameters are used to
-// connect to the SMTP server.
+// NewPlainDialer returns a Dialer. The given parameters are used to connect to
+// the SMTP server via a PLAIN authentication mechanism.
//
-// Deprecated: Use NewDialer instead.
+// It fallbacks to the LOGIN mechanism if it is the only mechanism advertised by
+// the server.
func NewPlainDialer(host string, port int, username, password string) *Dialer {
- return NewDialer(host, port, username, password)
+ return &Dialer{
+ Host: host,
+ Port: port,
+ Auth: &plainAuth{
+ username: username,
+ password: password,
+ host: host,
+ },
+ SSL: port == 465,
+ }
}
// 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)
+ c, err := d.dial()
if err != nil {
return nil, err
}
+ if d.Auth != nil {
+ if ok, _ := c.Extension("AUTH"); ok {
+ if err = c.Auth(d.Auth); err != nil {
+ c.Close()
+ return nil, err
+ }
+ }
+ }
+
+ return &smtpSender{c}, nil
+}
+
+func (d *Dialer) dial() (smtpClient, error) {
if d.SSL {
- conn = tlsClient(conn, d.tlsConfig())
+ return d.sslDial()
}
+ return d.starttlsDial()
+}
- c, err := smtpNewClient(conn, d.Host)
+func (d *Dialer) starttlsDial() (smtpClient, error) {
+ c, err := smtpDial(addr(d.Host, d.Port))
if err != nil {
return nil, err
}
- if d.LocalName != "" {
- if err := c.Hello(d.LocalName); err != nil {
+ if ok, _ := c.Extension("STARTTLS"); ok {
+ if err := c.StartTLS(d.tlsConfig()); err != nil {
+ c.Close()
return nil, err
}
}
- if !d.SSL {
- if ok, _ := c.Extension("STARTTLS"); ok {
- if err := c.StartTLS(d.tlsConfig()); err != nil {
- c.Close()
- return nil, err
- }
- }
- }
-
- if d.Auth == nil && d.Username != "" {
- if ok, auths := c.Extension("AUTH"); ok {
- if strings.Contains(auths, "CRAM-MD5") {
- d.Auth = smtp.CRAMMD5Auth(d.Username, d.Password)
- } else if strings.Contains(auths, "LOGIN") &&
- !strings.Contains(auths, "PLAIN") {
- d.Auth = &loginAuth{
- username: d.Username,
- password: d.Password,
- host: d.Host,
- }
- } else {
- d.Auth = smtp.PlainAuth("", d.Username, d.Password, d.Host)
- }
- }
- }
+ return c, nil
+}
- if d.Auth != nil {
- if err = c.Auth(d.Auth); err != nil {
- c.Close()
- return nil, err
- }
+func (d *Dialer) sslDial() (smtpClient, error) {
+ conn, err := tlsDial("tcp", addr(d.Host, d.Port), d.tlsConfig())
+ if err != nil {
+ return nil, err
}
- return &smtpSender{c, d}, nil
+ return newClient(conn, d.Host)
}
func (d *Dialer) tlsConfig() *tls.Config {
if d.TLSConfig == nil {
return &tls.Config{ServerName: d.Host}
}
+
return d.TLSConfig
}
@@ -139,21 +122,10 @@ func (d *Dialer) DialAndSend(m ...*Message) error {
type smtpSender struct {
smtpClient
- d *Dialer
}
func (c *smtpSender) Send(from string, to []string, msg io.WriterTo) error {
if err := c.Mail(from); err != nil {
- if err == io.EOF {
- // This is probably due to a timeout, so reconnect and try again.
- sc, derr := c.d.Dial()
- if derr == nil {
- if s, ok := sc.(*smtpSender); ok {
- *c = *s
- return c.Send(from, to, msg)
- }
- }
- }
return err
}
@@ -182,15 +154,16 @@ 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) {
+ smtpDial = func(addr string) (smtpClient, error) {
+ return smtp.Dial(addr)
+ }
+ tlsDial = tls.Dial
+ newClient = func(conn net.Conn, host string) (smtpClient, error) {
return smtp.NewClient(conn, host)
}
)
type smtpClient interface {
- Hello(string) error
Extension(string) (bool, string)
StartTLS(*tls.Config) error
Auth(smtp.Auth) error
diff --git a/vendor/gopkg.in/gomail.v2/smtp_test.go b/vendor/gopkg.in/gomail.v2/smtp_test.go
index b6f91555b..c8503489b 100644
--- a/vendor/gopkg.in/gomail.v2/smtp_test.go
+++ b/vendor/gopkg.in/gomail.v2/smtp_test.go
@@ -8,7 +8,6 @@ import (
"net/smtp"
"reflect"
"testing"
- "time"
)
const (
@@ -17,14 +16,12 @@ const (
)
var (
- testConn = &net.TCPConn{}
testTLSConn = &tls.Conn{}
testConfig = &tls.Config{InsecureSkipVerify: true}
- testAuth = smtp.PlainAuth("", testUser, testPwd, testHost)
)
func TestDialer(t *testing.T) {
- d := NewDialer(testHost, testPort, "user", "pwd")
+ d := NewPlainDialer(testHost, testPort, "user", "pwd")
testSendMail(t, d, []string{
"Extension STARTTLS",
"StartTLS",
@@ -42,7 +39,7 @@ func TestDialer(t *testing.T) {
}
func TestDialerSSL(t *testing.T) {
- d := NewDialer(testHost, testSSLPort, "user", "pwd")
+ d := NewPlainDialer(testHost, testSSLPort, "user", "pwd")
testSendMail(t, d, []string{
"Extension AUTH",
"Auth",
@@ -58,11 +55,9 @@ func TestDialerSSL(t *testing.T) {
}
func TestDialerConfig(t *testing.T) {
- d := NewDialer(testHost, testPort, "user", "pwd")
- d.LocalName = "test"
+ d := NewPlainDialer(testHost, testPort, "user", "pwd")
d.TLSConfig = testConfig
testSendMail(t, d, []string{
- "Hello test",
"Extension STARTTLS",
"StartTLS",
"Extension AUTH",
@@ -79,11 +74,9 @@ func TestDialerConfig(t *testing.T) {
}
func TestDialerSSLConfig(t *testing.T) {
- d := NewDialer(testHost, testSSLPort, "user", "pwd")
- d.LocalName = "test"
+ d := NewPlainDialer(testHost, testSSLPort, "user", "pwd")
d.TLSConfig = testConfig
testSendMail(t, d, []string{
- "Hello test",
"Extension AUTH",
"Auth",
"Mail " + testFrom,
@@ -116,40 +109,13 @@ func TestDialerNoAuth(t *testing.T) {
})
}
-func TestDialerTimeout(t *testing.T) {
- d := &Dialer{
- Host: testHost,
- Port: testPort,
- }
- testSendMailTimeout(t, d, []string{
- "Extension STARTTLS",
- "StartTLS",
- "Mail " + testFrom,
- "Extension STARTTLS",
- "StartTLS",
- "Mail " + testFrom,
- "Rcpt " + testTo1,
- "Rcpt " + testTo2,
- "Data",
- "Write message",
- "Close writer",
- "Quit",
- "Close",
- })
-}
-
type mockClient struct {
- t *testing.T
- i int
- want []string
- addr string
- config *tls.Config
- timeout bool
-}
-
-func (c *mockClient) Hello(localName string) error {
- c.do("Hello " + localName)
- return nil
+ t *testing.T
+ i int
+ want []string
+ addr string
+ auth smtp.Auth
+ config *tls.Config
}
func (c *mockClient) Extension(ext string) (bool, string) {
@@ -164,19 +130,13 @@ func (c *mockClient) StartTLS(config *tls.Config) error {
}
func (c *mockClient) Auth(a smtp.Auth) error {
- if !reflect.DeepEqual(a, testAuth) {
- c.t.Errorf("Invalid auth, got %#v, want %#v", a, testAuth)
- }
+ assertAuth(c.t, a, c.auth)
c.do("Auth")
return nil
}
func (c *mockClient) Mail(from string) error {
c.do("Mail " + from)
- if c.timeout {
- c.timeout = false
- return io.EOF
- }
return nil
}
@@ -232,42 +192,32 @@ func (w *mockWriter) Close() error {
}
func testSendMail(t *testing.T, d *Dialer, want []string) {
- doTestSendMail(t, d, want, false)
-}
-
-func testSendMailTimeout(t *testing.T, d *Dialer, want []string) {
- doTestSendMail(t, d, want, true)
-}
-
-func doTestSendMail(t *testing.T, d *Dialer, want []string, timeout bool) {
testClient := &mockClient{
- t: t,
- want: want,
- addr: addr(d.Host, d.Port),
- config: d.TLSConfig,
- timeout: timeout,
+ t: t,
+ want: want,
+ addr: addr(d.Host, d.Port),
+ auth: testAuth,
+ config: d.TLSConfig,
}
- netDialTimeout = func(network, address string, d time.Duration) (net.Conn, error) {
- if network != "tcp" {
- t.Errorf("Invalid network, got %q, want tcp", network)
- }
- if address != testClient.addr {
- t.Errorf("Invalid address, got %q, want %q",
- address, testClient.addr)
- }
- return testConn, nil
+ smtpDial = func(addr string) (smtpClient, error) {
+ assertAddr(t, addr, testClient.addr)
+ return testClient, nil
}
- tlsClient = func(conn net.Conn, config *tls.Config) *tls.Conn {
- if conn != testConn {
- t.Errorf("Invalid conn, got %#v, want %#v", conn, testConn)
+ tlsDial = func(network, addr string, config *tls.Config) (*tls.Conn, error) {
+ if network != "tcp" {
+ t.Errorf("Invalid network, got %q, want tcp", network)
}
+ assertAddr(t, addr, testClient.addr)
assertConfig(t, config, testClient.config)
- return testTLSConn
+ return testTLSConn, nil
}
- smtpNewClient = func(conn net.Conn, host string) (smtpClient, error) {
+ newClient = func(conn net.Conn, host string) (smtpClient, error) {
+ if conn != testTLSConn {
+ t.Error("Invalid TLS connection used")
+ }
if host != testHost {
t.Errorf("Invalid host, got %q, want %q", host, testHost)
}
@@ -279,6 +229,18 @@ func doTestSendMail(t *testing.T, d *Dialer, want []string, timeout bool) {
}
}
+func assertAuth(t *testing.T, got, want smtp.Auth) {
+ if !reflect.DeepEqual(got, want) {
+ t.Errorf("Invalid auth, got %#v, want %#v", got, want)
+ }
+}
+
+func assertAddr(t *testing.T, got, want string) {
+ if got != want {
+ t.Errorf("Invalid addr, got %q, want %q", got, want)
+ }
+}
+
func assertConfig(t *testing.T, got, want *tls.Config) {
if want == nil {
want = &tls.Config{ServerName: testHost}
diff --git a/vendor/gopkg.in/gomail.v2/writeto.go b/vendor/gopkg.in/gomail.v2/writeto.go
index 9fb6b86e8..57a1dd7f1 100644
--- a/vendor/gopkg.in/gomail.v2/writeto.go
+++ b/vendor/gopkg.in/gomail.v2/writeto.go
@@ -7,7 +7,6 @@ import (
"mime"
"mime/multipart"
"path/filepath"
- "strings"
"time"
)
@@ -39,7 +38,8 @@ func (w *messageWriter) writeMessage(m *Message) {
w.openMultipart("alternative")
}
for _, part := range m.parts {
- w.writePart(part, m.charset)
+ w.writeHeaders(part.header)
+ w.writeBody(part.copier, m.encoding)
}
if m.hasAlternativePart() {
w.closeMultipart()
@@ -79,7 +79,7 @@ type messageWriter struct {
func (w *messageWriter) openMultipart(mimeType string) {
mw := multipart.NewWriter(w)
- contentType := "multipart/" + mimeType + ";\r\n boundary=" + mw.Boundary()
+ contentType := "multipart/" + mimeType + "; boundary=" + mw.Boundary()
w.writers[w.depth] = mw
if w.depth == 0 {
@@ -104,14 +104,6 @@ func (w *messageWriter) closeMultipart() {
}
}
-func (w *messageWriter) writePart(p *part, charset string) {
- w.writeHeaders(map[string][]string{
- "Content-Type": {p.contentType + "; charset=" + charset},
- "Content-Transfer-Encoding": {string(p.encoding)},
- })
- w.writeBody(p.copier, p.encoding)
-}
-
func (w *messageWriter) addFiles(files []*file, isAttachment bool) {
for _, f := range files {
if _, ok := f.Header["Content-Type"]; !ok {
@@ -162,80 +154,24 @@ func (w *messageWriter) writeString(s string) {
w.n += int64(n)
}
-func (w *messageWriter) writeHeader(k string, v ...string) {
- w.writeString(k)
- if len(v) == 0 {
- w.writeString(":\r\n")
- return
- }
- w.writeString(": ")
-
- // Max header line length is 78 characters in RFC 5322 and 76 characters
- // in RFC 2047. So for the sake of simplicity we use the 76 characters
- // limit.
- charsLeft := 76 - len(k) - len(": ")
-
- for i, s := range v {
- // If the line is already too long, insert a newline right away.
- if charsLeft < 1 {
- if i == 0 {
- w.writeString("\r\n ")
- } else {
- w.writeString(",\r\n ")
- }
- charsLeft = 75
- } else if i != 0 {
- w.writeString(", ")
- charsLeft -= 2
- }
-
- // While the header content is too long, fold it by inserting a newline.
- for len(s) > charsLeft {
- s = w.writeLine(s, charsLeft)
- charsLeft = 75
+func (w *messageWriter) writeStrings(a []string, sep string) {
+ if len(a) > 0 {
+ w.writeString(a[0])
+ if len(a) == 1 {
+ return
}
+ }
+ for _, s := range a[1:] {
+ w.writeString(sep)
w.writeString(s)
- if i := lastIndexByte(s, '\n'); i != -1 {
- charsLeft = 75 - (len(s) - i - 1)
- } else {
- charsLeft -= len(s)
- }
}
- w.writeString("\r\n")
}
-func (w *messageWriter) writeLine(s string, charsLeft int) string {
- // If there is already a newline before the limit. Write the line.
- if i := strings.IndexByte(s, '\n'); i != -1 && i < charsLeft {
- w.writeString(s[:i+1])
- return s[i+1:]
- }
-
- for i := charsLeft - 1; i >= 0; i-- {
- if s[i] == ' ' {
- w.writeString(s[:i])
- w.writeString("\r\n ")
- return s[i+1:]
- }
- }
-
- // We could not insert a newline cleanly so look for a space or a newline
- // even if it is after the limit.
- for i := 75; i < len(s); i++ {
- if s[i] == ' ' {
- w.writeString(s[:i])
- w.writeString("\r\n ")
- return s[i+1:]
- }
- if s[i] == '\n' {
- w.writeString(s[:i+1])
- return s[i+1:]
- }
- }
-
- // Too bad, no space or newline in the whole string. Just write everything.
- w.writeString(s)
- return ""
+func (w *messageWriter) writeHeader(k string, v ...string) {
+ w.writeString(k)
+ w.writeString(": ")
+ w.writeStrings(v, ", ")
+ w.writeString("\r\n")
}
func (w *messageWriter) writeHeaders(h map[string][]string) {
diff --git a/vendor/gopkg.in/olivere/elastic.v5/client.go b/vendor/gopkg.in/olivere/elastic.v5/client.go
index 13be369bd..e517a7fa8 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/client.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/client.go
@@ -26,7 +26,7 @@ import (
const (
// Version is the current version of Elastic.
- Version = "5.0.43"
+ Version = "5.0.45"
// DefaultURL is the default endpoint of Elasticsearch on the local machine.
// It is used e.g. when initializing a new Client without a specific URL.
@@ -1257,6 +1257,13 @@ func (c *Client) PerformRequest(ctx context.Context, method, path string, params
// Proceed, but don't mark the node as dead
return nil, err
}
+ if ue, ok := err.(*url.Error); ok {
+ // This happens e.g. on redirect errors, see https://golang.org/src/net/http/client_test.go#L329
+ if ue.Err == context.Canceled || ue.Err == context.DeadlineExceeded {
+ // Proceed, but don't mark the node as dead
+ return nil, err
+ }
+ }
if err != nil {
n++
wait, ok, rerr := c.retrier.Retry(ctx, n, (*http.Request)(req), res, err)
diff --git a/vendor/gopkg.in/olivere/elastic.v5/client_test.go b/vendor/gopkg.in/olivere/elastic.v5/client_test.go
index 1441f1791..6caf7b797 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/client_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/client_test.go
@@ -16,6 +16,7 @@ import (
"reflect"
"regexp"
"strings"
+ "sync"
"testing"
"time"
@@ -294,6 +295,7 @@ func TestClientHealthcheckTimeoutLeak(t *testing.T) {
// leaks via leaktest.
mux := http.NewServeMux()
+ var reqDoneMu sync.Mutex
var reqDone bool
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
cn, ok := w.(http.CloseNotifier)
@@ -301,7 +303,9 @@ func TestClientHealthcheckTimeoutLeak(t *testing.T) {
t.Fatalf("Writer is not CloseNotifier, but %v", reflect.TypeOf(w).Name())
}
<-cn.CloseNotify()
+ reqDoneMu.Lock()
reqDone = true
+ reqDoneMu.Unlock()
})
lis, err := net.Listen("tcp", "127.0.0.1:0")
@@ -346,9 +350,12 @@ func TestClientHealthcheckTimeoutLeak(t *testing.T) {
}
<-time.After(time.Second)
+ reqDoneMu.Lock()
if !reqDone {
+ reqDoneMu.Unlock()
t.Fatal("Request wasn't canceled or stopped")
}
+ reqDoneMu.Unlock()
}
// -- NewSimpleClient --
@@ -552,6 +559,7 @@ func TestClientSniffTimeoutLeak(t *testing.T) {
// leaks via leaktest.
mux := http.NewServeMux()
+ var reqDoneMu sync.Mutex
var reqDone bool
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
cn, ok := w.(http.CloseNotifier)
@@ -559,7 +567,9 @@ func TestClientSniffTimeoutLeak(t *testing.T) {
t.Fatalf("Writer is not CloseNotifier, but %v", reflect.TypeOf(w).Name())
}
<-cn.CloseNotify()
+ reqDoneMu.Lock()
reqDone = true
+ reqDoneMu.Unlock()
})
lis, err := net.Listen("tcp", "127.0.0.1:0")
@@ -605,9 +615,12 @@ func TestClientSniffTimeoutLeak(t *testing.T) {
}
<-time.After(time.Second)
+ reqDoneMu.Lock()
if !reqDone {
+ reqDoneMu.Unlock()
t.Fatal("Request wasn't canceled or stopped")
}
+ reqDoneMu.Unlock()
}
func TestClientExtractHostname(t *testing.T) {
@@ -1195,7 +1208,8 @@ func TestPerformRequestWithTimeout(t *testing.T) {
res *Response
err error
}
- ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
+ ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
+ defer cancel()
resc := make(chan result, 1)
go func() {
diff --git a/vendor/gopkg.in/olivere/elastic.v5/retry_test.go b/vendor/gopkg.in/olivere/elastic.v5/retry_test.go
index 14ebbb835..804313095 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/retry_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/retry_test.go
@@ -21,14 +21,14 @@ func TestRetry(t *testing.T) {
// This function is successfull on "successOn" calls.
f := func() error {
i++
- t.Logf("function is called %d. time\n", i)
+ // t.Logf("function is called %d. time\n", i)
if i == successOn {
- t.Log("OK")
+ // t.Log("OK")
return nil
}
- t.Log("error")
+ // t.Log("error")
return errors.New("error")
}
diff --git a/vendor/gopkg.in/olivere/elastic.v5/run-es-5.5.1.sh b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.5.1.sh
new file mode 100755
index 000000000..343a605ba
--- /dev/null
+++ b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.5.1.sh
@@ -0,0 +1 @@
+docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -v "$PWD/etc:/usr/share/elasticsearch/config" -e ES_JAVA_OPTS='-Xms1g -Xmx1g' elasticsearch:5.5.1 elasticsearch
diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms.go b/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms.go
index 5497aa6e9..6bcc322d0 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms.go
@@ -20,15 +20,10 @@ type TermsAggregation struct {
minDocCount *int
shardMinDocCount *int
valueType string
- includePattern string
- includeFlags *int
- excludePattern string
- excludeFlags *int
+ includeExclude *TermsAggregationIncludeExclude
executionHint string
collectionMode string
showTermDocCountError *bool
- includeTerms []string
- excludeTerms []string
order []TermsOrder
}
@@ -91,24 +86,50 @@ func (a *TermsAggregation) ShardMinDocCount(shardMinDocCount int) *TermsAggregat
}
func (a *TermsAggregation) Include(regexp string) *TermsAggregation {
- a.includePattern = regexp
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.Include = regexp
return a
}
-func (a *TermsAggregation) IncludeWithFlags(regexp string, flags int) *TermsAggregation {
- a.includePattern = regexp
- a.includeFlags = &flags
+func (a *TermsAggregation) IncludeValues(values ...interface{}) *TermsAggregation {
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.IncludeValues = append(a.includeExclude.IncludeValues, values...)
return a
}
func (a *TermsAggregation) Exclude(regexp string) *TermsAggregation {
- a.excludePattern = regexp
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.Exclude = regexp
+ return a
+}
+
+func (a *TermsAggregation) ExcludeValues(values ...interface{}) *TermsAggregation {
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.ExcludeValues = append(a.includeExclude.ExcludeValues, values...)
+ return a
+}
+
+func (a *TermsAggregation) Partition(p int) *TermsAggregation {
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.Partition = p
return a
}
-func (a *TermsAggregation) ExcludeWithFlags(regexp string, flags int) *TermsAggregation {
- a.excludePattern = regexp
- a.excludeFlags = &flags
+func (a *TermsAggregation) NumPartitions(n int) *TermsAggregation {
+ if a.includeExclude == nil {
+ a.includeExclude = &TermsAggregationIncludeExclude{}
+ }
+ a.includeExclude.NumPartitions = n
return a
}
@@ -207,16 +228,6 @@ func (a *TermsAggregation) ShowTermDocCountError(showTermDocCountError bool) *Te
return a
}
-func (a *TermsAggregation) IncludeTerms(terms ...string) *TermsAggregation {
- a.includeTerms = append(a.includeTerms, terms...)
- return a
-}
-
-func (a *TermsAggregation) ExcludeTerms(terms ...string) *TermsAggregation {
- a.excludeTerms = append(a.excludeTerms, terms...)
- return a
-}
-
func (a *TermsAggregation) Source() (interface{}, error) {
// Example:
// {
@@ -283,32 +294,27 @@ func (a *TermsAggregation) Source() (interface{}, error) {
}
opts["order"] = orderSlice
}
- if len(a.includeTerms) > 0 {
- opts["include"] = a.includeTerms
- }
- if a.includePattern != "" {
- if a.includeFlags == nil || *a.includeFlags == 0 {
- opts["include"] = a.includePattern
- } else {
- p := make(map[string]interface{})
- p["pattern"] = a.includePattern
- p["flags"] = *a.includeFlags
- opts["include"] = p
+ // Include/Exclude
+ if ie := a.includeExclude; ie != nil {
+ // Include
+ if ie.Include != "" {
+ opts["include"] = ie.Include
+ } else if len(ie.IncludeValues) > 0 {
+ opts["include"] = ie.IncludeValues
+ } else if ie.NumPartitions > 0 {
+ inc := make(map[string]interface{})
+ inc["partition"] = ie.Partition
+ inc["num_partitions"] = ie.NumPartitions
+ opts["include"] = inc
}
- }
- if len(a.excludeTerms) > 0 {
- opts["exclude"] = a.excludeTerms
- }
- if a.excludePattern != "" {
- if a.excludeFlags == nil || *a.excludeFlags == 0 {
- opts["exclude"] = a.excludePattern
- } else {
- p := make(map[string]interface{})
- p["pattern"] = a.excludePattern
- p["flags"] = *a.excludeFlags
- opts["exclude"] = p
+ // Exclude
+ if ie.Exclude != "" {
+ opts["exclude"] = ie.Exclude
+ } else if len(ie.ExcludeValues) > 0 {
+ opts["exclude"] = ie.ExcludeValues
}
}
+
if a.executionHint != "" {
opts["execution_hint"] = a.executionHint
}
@@ -334,6 +340,16 @@ func (a *TermsAggregation) Source() (interface{}, error) {
return source, nil
}
+// TermsAggregationIncludeExclude allows for include/exclude in a TermsAggregation.
+type TermsAggregationIncludeExclude struct {
+ Include string
+ Exclude string
+ IncludeValues []interface{}
+ ExcludeValues []interface{}
+ Partition int
+ NumPartitions int
+}
+
// TermsOrder specifies a single order field for a terms aggregation.
type TermsOrder struct {
Field string
diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms_test.go b/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms_test.go
index 6b5c1bb8a..351cbf63b 100644
--- a/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms_test.go
+++ b/vendor/gopkg.in/olivere/elastic.v5/search_aggs_bucket_terms_test.go
@@ -102,3 +102,54 @@ func TestTermsAggregationWithMissing(t *testing.T) {
t.Errorf("expected\n%s\n,got:\n%s", expected, got)
}
}
+
+func TestTermsAggregationWithIncludeExclude(t *testing.T) {
+ agg := NewTermsAggregation().Field("tags").Include(".*sport.*").Exclude("water_.*")
+ src, err := agg.Source()
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := json.Marshal(src)
+ if err != nil {
+ t.Fatalf("marshaling to JSON failed: %v", err)
+ }
+ got := string(data)
+ expected := `{"terms":{"exclude":"water_.*","field":"tags","include":".*sport.*"}}`
+ if got != expected {
+ t.Errorf("expected\n%s\n,got:\n%s", expected, got)
+ }
+}
+
+func TestTermsAggregationWithIncludeExcludeValues(t *testing.T) {
+ agg := NewTermsAggregation().Field("make").IncludeValues("mazda", "honda").ExcludeValues("rover", "jensen")
+ src, err := agg.Source()
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := json.Marshal(src)
+ if err != nil {
+ t.Fatalf("marshaling to JSON failed: %v", err)
+ }
+ got := string(data)
+ expected := `{"terms":{"exclude":["rover","jensen"],"field":"make","include":["mazda","honda"]}}`
+ if got != expected {
+ t.Errorf("expected\n%s\n,got:\n%s", expected, got)
+ }
+}
+
+func TestTermsAggregationWithPartitions(t *testing.T) {
+ agg := NewTermsAggregation().Field("account_id").Partition(0).NumPartitions(20)
+ src, err := agg.Source()
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := json.Marshal(src)
+ if err != nil {
+ t.Fatalf("marshaling to JSON failed: %v", err)
+ }
+ got := string(data)
+ expected := `{"terms":{"field":"account_id","include":{"num_partitions":20,"partition":0}}}`
+ if got != expected {
+ t.Errorf("expected\n%s\n,got:\n%s", expected, got)
+ }
+}
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE
index 866d74a7a..8dada3eda 100644
--- a/vendor/gopkg.in/yaml.v2/LICENSE
+++ b/vendor/gopkg.in/yaml.v2/LICENSE
@@ -1,13 +1,201 @@
-Copyright 2011-2016 Canonical Ltd.
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- http://www.apache.org/licenses/LICENSE-2.0
+ 1. Definitions.
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md
index 1884de6a7..7a512d67c 100644
--- a/vendor/gopkg.in/yaml.v2/README.md
+++ b/vendor/gopkg.in/yaml.v2/README.md
@@ -48,6 +48,8 @@ The yaml package is licensed under the Apache License 2.0. Please see the LICENS
Example
-------
+Some more examples can be found in the "examples" folder.
+
```Go
package main
diff --git a/vendor/gopkg.in/yaml.v2/decode_test.go b/vendor/gopkg.in/yaml.v2/decode_test.go
index 3d0807a07..713b1ee9c 100644
--- a/vendor/gopkg.in/yaml.v2/decode_test.go
+++ b/vendor/gopkg.in/yaml.v2/decode_test.go
@@ -405,6 +405,12 @@ var unmarshalTests = []struct {
map[string]interface{}{"v": 1},
},
+ // Non-specific tag (Issue #75)
+ {
+ "v: ! test",
+ map[string]interface{}{"v": "test"},
+ },
+
// Anchors and aliases.
{
"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
@@ -604,7 +610,8 @@ type inlineC struct {
}
func (s *S) TestUnmarshal(c *C) {
- for _, item := range unmarshalTests {
+ for i, item := range unmarshalTests {
+ c.Logf("test %d: %q", i, item.data)
t := reflect.ValueOf(item.value).Type()
var value interface{}
switch t.Kind() {
@@ -648,6 +655,7 @@ var unmarshalErrorTests = []struct {
{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
+ {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
}
func (s *S) TestUnmarshalErrors(c *C) {
diff --git a/vendor/gopkg.in/yaml.v2/example_embedded_test.go b/vendor/gopkg.in/yaml.v2/example_embedded_test.go
new file mode 100644
index 000000000..c8b241d54
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/example_embedded_test.go
@@ -0,0 +1,41 @@
+package yaml_test
+
+import (
+ "fmt"
+ "log"
+
+ "gopkg.in/yaml.v2"
+)
+
+// An example showing how to unmarshal embedded
+// structs from YAML.
+
+type StructA struct {
+ A string `yaml:"a"`
+}
+
+type StructB struct {
+ // Embedded structs are not treated as embedded in YAML by default. To do that,
+ // add the ",inline" annotation below
+ StructA `yaml:",inline"`
+ B string `yaml:"b"`
+}
+
+var data = `
+a: a string from struct A
+b: a string from struct B
+`
+
+func ExampleUnmarshal_embedded() {
+ var b StructB
+
+ err := yaml.Unmarshal([]byte(data), &b)
+ if err != nil {
+ log.Fatal("cannot unmarshal data: %v", err)
+ }
+ fmt.Println(b.A)
+ fmt.Println(b.B)
+ // Output:
+ // a string from struct A
+ // a string from struct B
+}
diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go
index 2c9d5111f..074484455 100644
--- a/vendor/gopkg.in/yaml.v2/scannerc.go
+++ b/vendor/gopkg.in/yaml.v2/scannerc.go
@@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
if directive {
context = "while parsing a %TAG directive"
}
- return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
+ return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
}
func trace(args ...interface{}) func() {
@@ -1944,7 +1944,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
} else {
// It's either the '!' tag or not really a tag handle. If it's a %TAG
// directive, it's an error. If it's a tag token, it must be a part of URI.
- if directive && !(s[0] == '!' && s[1] == 0) {
+ if directive && string(s) != "!" {
yaml_parser_set_scanner_tag_error(parser, directive,
start_mark, "did not find expected '!'")
return false
@@ -1959,6 +1959,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
//size_t length = head ? strlen((char *)head) : 0
var s []byte
+ hasTag := len(head) > 0
// Copy the head if needed.
//
@@ -2000,10 +2001,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
return false
}
+ hasTag = true
}
- // Check if the tag is non-empty.
- if len(s) == 0 {
+ if !hasTag {
yaml_parser_set_scanner_tag_error(parser, directive,
start_mark, "did not find expected tag URI")
return false