Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package smtp | 5 package smtp |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "bytes" | 9 "bytes" |
10 "io" | 10 "io" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 } | 62 } |
63 | 63 |
64 func (f faker) Close() error { return nil } | 64 func (f faker) Close() error { return nil } |
65 func (f faker) LocalAddr() net.Addr { return nil } | 65 func (f faker) LocalAddr() net.Addr { return nil } |
66 func (f faker) RemoteAddr() net.Addr { return nil } | 66 func (f faker) RemoteAddr() net.Addr { return nil } |
67 func (f faker) SetDeadline(time.Time) error { return nil } | 67 func (f faker) SetDeadline(time.Time) error { return nil } |
68 func (f faker) SetReadDeadline(time.Time) error { return nil } | 68 func (f faker) SetReadDeadline(time.Time) error { return nil } |
69 func (f faker) SetWriteDeadline(time.Time) error { return nil } | 69 func (f faker) SetWriteDeadline(time.Time) error { return nil } |
70 | 70 |
71 func TestBasic(t *testing.T) { | 71 func TestBasic(t *testing.T) { |
72 » basicServer = strings.Join(strings.Split(basicServer, "\n"), "\r\n") | 72 » server := strings.Join(strings.Split(basicServer, "\n"), "\r\n") |
73 » basicClient = strings.Join(strings.Split(basicClient, "\n"), "\r\n") | 73 » client := strings.Join(strings.Split(basicClient, "\n"), "\r\n") |
74 | 74 |
75 var cmdbuf bytes.Buffer | 75 var cmdbuf bytes.Buffer |
76 bcmdbuf := bufio.NewWriter(&cmdbuf) | 76 bcmdbuf := bufio.NewWriter(&cmdbuf) |
77 var fake faker | 77 var fake faker |
78 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( basicServer)), bcmdbuf) | 78 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( server)), bcmdbuf) |
79 c := &Client{Text: textproto.NewConn(fake), localName: "localhost"} | 79 c := &Client{Text: textproto.NewConn(fake), localName: "localhost"} |
80 | 80 |
81 if err := c.helo(); err != nil { | 81 if err := c.helo(); err != nil { |
82 t.Fatalf("HELO failed: %s", err) | 82 t.Fatalf("HELO failed: %s", err) |
83 } | 83 } |
84 if err := c.ehlo(); err == nil { | 84 if err := c.ehlo(); err == nil { |
85 t.Fatalf("Expected first EHLO to fail") | 85 t.Fatalf("Expected first EHLO to fail") |
86 } | 86 } |
87 if err := c.ehlo(); err != nil { | 87 if err := c.ehlo(); err != nil { |
88 t.Fatalf("Second EHLO failed: %s", err) | 88 t.Fatalf("Second EHLO failed: %s", err) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 if err := w.Close(); err != nil { | 137 if err := w.Close(); err != nil { |
138 t.Fatalf("Bad data response: %s", err) | 138 t.Fatalf("Bad data response: %s", err) |
139 } | 139 } |
140 | 140 |
141 if err := c.Quit(); err != nil { | 141 if err := c.Quit(); err != nil { |
142 t.Fatalf("QUIT failed: %s", err) | 142 t.Fatalf("QUIT failed: %s", err) |
143 } | 143 } |
144 | 144 |
145 bcmdbuf.Flush() | 145 bcmdbuf.Flush() |
146 actualcmds := cmdbuf.String() | 146 actualcmds := cmdbuf.String() |
147 » if basicClient != actualcmds { | 147 » if client != actualcmds { |
148 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, basicClient) | 148 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) |
149 } | 149 } |
150 } | 150 } |
151 | 151 |
152 var basicServer = `250 mx.google.com at your service | 152 var basicServer = `250 mx.google.com at your service |
153 502 Unrecognized command. | 153 502 Unrecognized command. |
154 250-mx.google.com at your service | 154 250-mx.google.com at your service |
155 250-SIZE 35651584 | 155 250-SIZE 35651584 |
156 250-AUTH LOGIN PLAIN | 156 250-AUTH LOGIN PLAIN |
157 250 8BITMIME | 157 250 8BITMIME |
158 530 Authentication required | 158 530 Authentication required |
(...skipping 22 matching lines...) Expand all Loading... | |
181 Subject: Hooray for Go | 181 Subject: Hooray for Go |
182 | 182 |
183 Line 1 | 183 Line 1 |
184 ..Leading dot line . | 184 ..Leading dot line . |
185 Goodbye. | 185 Goodbye. |
186 . | 186 . |
187 QUIT | 187 QUIT |
188 ` | 188 ` |
189 | 189 |
190 func TestNewClient(t *testing.T) { | 190 func TestNewClient(t *testing.T) { |
191 » newClientServer = strings.Join(strings.Split(newClientServer, "\n"), "\r \n") | 191 » server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n") |
192 » newClientClient = strings.Join(strings.Split(newClientClient, "\n"), "\r \n") | 192 » client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n") |
193 | 193 |
194 var cmdbuf bytes.Buffer | 194 var cmdbuf bytes.Buffer |
195 bcmdbuf := bufio.NewWriter(&cmdbuf) | 195 bcmdbuf := bufio.NewWriter(&cmdbuf) |
196 out := func() string { | 196 out := func() string { |
197 bcmdbuf.Flush() | 197 bcmdbuf.Flush() |
198 return cmdbuf.String() | 198 return cmdbuf.String() |
199 } | 199 } |
200 var fake faker | 200 var fake faker |
201 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( newClientServer)), bcmdbuf) | 201 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( server)), bcmdbuf) |
202 c, err := NewClient(fake, "fake.host") | 202 c, err := NewClient(fake, "fake.host") |
203 if err != nil { | 203 if err != nil { |
204 t.Fatalf("NewClient: %v\n(after %v)", err, out()) | 204 t.Fatalf("NewClient: %v\n(after %v)", err, out()) |
205 } | 205 } |
206 if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { | 206 if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { |
207 t.Fatalf("Expected AUTH supported") | 207 t.Fatalf("Expected AUTH supported") |
208 } | 208 } |
209 if ok, _ := c.Extension("DSN"); ok { | 209 if ok, _ := c.Extension("DSN"); ok { |
210 t.Fatalf("Shouldn't support DSN") | 210 t.Fatalf("Shouldn't support DSN") |
211 } | 211 } |
212 if err := c.Quit(); err != nil { | 212 if err := c.Quit(); err != nil { |
213 t.Fatalf("QUIT failed: %s", err) | 213 t.Fatalf("QUIT failed: %s", err) |
214 } | 214 } |
215 | 215 |
216 actualcmds := out() | 216 actualcmds := out() |
217 » if newClientClient != actualcmds { | 217 » if client != actualcmds { |
218 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClientClient) | 218 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) |
219 } | 219 } |
220 } | 220 } |
221 | 221 |
222 var newClientServer = `220 hello world | 222 var newClientServer = `220 hello world |
223 250-mx.google.com at your service | 223 250-mx.google.com at your service |
224 250-SIZE 35651584 | 224 250-SIZE 35651584 |
225 250-AUTH LOGIN PLAIN | 225 250-AUTH LOGIN PLAIN |
226 250 8BITMIME | 226 250 8BITMIME |
227 221 OK | 227 221 OK |
228 ` | 228 ` |
229 | 229 |
230 var newClientClient = `EHLO localhost | 230 var newClientClient = `EHLO localhost |
231 QUIT | 231 QUIT |
232 ` | 232 ` |
233 | 233 |
234 func TestNewClient2(t *testing.T) { | 234 func TestNewClient2(t *testing.T) { |
235 » newClient2Server = strings.Join(strings.Split(newClient2Server, "\n"), " \r\n") | 235 » server := strings.Join(strings.Split(newClient2Server, "\n"), "\r\n") |
236 » newClient2Client = strings.Join(strings.Split(newClient2Client, "\n"), " \r\n") | 236 » client := strings.Join(strings.Split(newClient2Client, "\n"), "\r\n") |
237 | 237 |
238 var cmdbuf bytes.Buffer | 238 var cmdbuf bytes.Buffer |
239 bcmdbuf := bufio.NewWriter(&cmdbuf) | 239 bcmdbuf := bufio.NewWriter(&cmdbuf) |
240 var fake faker | 240 var fake faker |
241 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( newClient2Server)), bcmdbuf) | 241 » fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader( server)), bcmdbuf) |
242 c, err := NewClient(fake, "fake.host") | 242 c, err := NewClient(fake, "fake.host") |
243 if err != nil { | 243 if err != nil { |
244 t.Fatalf("NewClient: %v", err) | 244 t.Fatalf("NewClient: %v", err) |
245 } | 245 } |
246 if ok, _ := c.Extension("DSN"); ok { | 246 if ok, _ := c.Extension("DSN"); ok { |
247 t.Fatalf("Shouldn't support DSN") | 247 t.Fatalf("Shouldn't support DSN") |
248 } | 248 } |
249 if err := c.Quit(); err != nil { | 249 if err := c.Quit(); err != nil { |
250 t.Fatalf("QUIT failed: %s", err) | 250 t.Fatalf("QUIT failed: %s", err) |
251 } | 251 } |
252 | 252 |
253 bcmdbuf.Flush() | 253 bcmdbuf.Flush() |
254 actualcmds := cmdbuf.String() | 254 actualcmds := cmdbuf.String() |
255 » if newClient2Client != actualcmds { | 255 » if client != actualcmds { |
256 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClient2Client ) | 256 » » t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) |
257 } | 257 } |
258 } | 258 } |
259 | 259 |
260 var newClient2Server = `220 hello world | 260 var newClient2Server = `220 hello world |
261 502 EH? | 261 502 EH? |
262 250-mx.google.com at your service | 262 250-mx.google.com at your service |
263 250-SIZE 35651584 | 263 250-SIZE 35651584 |
264 250-AUTH LOGIN PLAIN | 264 250-AUTH LOGIN PLAIN |
265 250 8BITMIME | 265 250 8BITMIME |
266 221 OK | 266 221 OK |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n") | 378 server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n") |
379 client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n") | 379 client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n") |
380 var cmdbuf bytes.Buffer | 380 var cmdbuf bytes.Buffer |
381 bcmdbuf := bufio.NewWriter(&cmdbuf) | 381 bcmdbuf := bufio.NewWriter(&cmdbuf) |
382 l, err := net.Listen("tcp", "127.0.0.1:0") | 382 l, err := net.Listen("tcp", "127.0.0.1:0") |
383 if err != nil { | 383 if err != nil { |
384 t.Fatalf("Unable to to create listener: %v", err) | 384 t.Fatalf("Unable to to create listener: %v", err) |
385 } | 385 } |
386 defer l.Close() | 386 defer l.Close() |
387 | 387 |
388 » go func(l net.Listener, data []string, w *bufio.Writer) { | 388 » // prevent data race on bcmdbuf |
389 » var done = make(chan struct{}) | |
390 » go func(data []string) { | |
391 | |
392 » » defer close(done) | |
393 | |
389 i := 0 | 394 i := 0 |
dfc
2012/12/17 06:56:50
please move this into the for loop
rick
2012/12/17 12:54:46
Done. Not sure how I ended up with this. :)
| |
390 conn, err := l.Accept() | 395 conn, err := l.Accept() |
391 if err != nil { | 396 if err != nil { |
392 » » » t.Log("Accept error: %v", err) | 397 » » » t.Errorf("Accept error: %v", err) |
393 return | 398 return |
394 } | 399 } |
395 defer conn.Close() | 400 defer conn.Close() |
396 | 401 |
397 tc := textproto.NewConn(conn) | 402 tc := textproto.NewConn(conn) |
398 for i < len(data) && data[i] != "" { | 403 for i < len(data) && data[i] != "" { |
dfc
2012/12/17 06:56:50
for i := 0 ; i < ... ; i++ {
| |
399 tc.PrintfLine(data[i]) | 404 tc.PrintfLine(data[i]) |
400 for len(data[i]) >= 4 && data[i][3] == '-' { | 405 for len(data[i]) >= 4 && data[i][3] == '-' { |
401 i++ | 406 i++ |
402 tc.PrintfLine(data[i]) | 407 tc.PrintfLine(data[i]) |
403 } | 408 } |
409 if data[i] == "221 Goodbye" { | |
410 return | |
411 } | |
404 read := false | 412 read := false |
405 for !read || data[i] == "354 Go ahead" { | 413 for !read || data[i] == "354 Go ahead" { |
406 msg, err := tc.ReadLine() | 414 msg, err := tc.ReadLine() |
407 » » » » w.Write([]byte(msg + "\r\n")) | 415 » » » » bcmdbuf.Write([]byte(msg + "\r\n")) |
408 read = true | 416 read = true |
409 if err != nil { | 417 if err != nil { |
410 » » » » » t.Log("Read error: %v", err) | 418 » » » » » t.Errorf("Read error: %v", err) |
411 return | 419 return |
412 } | 420 } |
413 if data[i] == "354 Go ahead" && msg == "." { | 421 if data[i] == "354 Go ahead" && msg == "." { |
414 break | 422 break |
415 } | 423 } |
416 } | 424 } |
417 i++ | 425 i++ |
dfc
2012/12/17 06:56:50
drop
| |
418 } | 426 } |
419 » }(l, strings.Split(server, "\r\n"), bcmdbuf) | 427 » }(strings.Split(server, "\r\n")) |
420 | 428 |
421 err = SendMail(l.Addr().String(), nil, "test@example.com", []string{"oth er@example.com"}, []byte(strings.Replace(`From: test@example.com | 429 err = SendMail(l.Addr().String(), nil, "test@example.com", []string{"oth er@example.com"}, []byte(strings.Replace(`From: test@example.com |
422 To: other@example.com | 430 To: other@example.com |
423 Subject: SendMail test | 431 Subject: SendMail test |
424 | 432 |
425 SendMail is working for me. | 433 SendMail is working for me. |
426 `, "\n", "\r\n", -1))) | 434 `, "\n", "\r\n", -1))) |
427 | 435 |
428 if err != nil { | 436 if err != nil { |
429 t.Errorf("%v", err) | 437 t.Errorf("%v", err) |
430 } | 438 } |
431 | 439 |
440 <-done | |
432 bcmdbuf.Flush() | 441 bcmdbuf.Flush() |
433 actualcmds := cmdbuf.String() | 442 actualcmds := cmdbuf.String() |
434 if client != actualcmds { | 443 if client != actualcmds { |
435 t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client) | 444 t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client) |
436 } | 445 } |
437 } | 446 } |
438 | 447 |
439 var sendMailServer = `220 hello world | 448 var sendMailServer = `220 hello world |
440 502 EH? | 449 502 EH? |
441 250 mx.google.com at your service | 450 250 mx.google.com at your service |
(...skipping 10 matching lines...) Expand all Loading... | |
452 RCPT TO:<other@example.com> | 461 RCPT TO:<other@example.com> |
453 DATA | 462 DATA |
454 From: test@example.com | 463 From: test@example.com |
455 To: other@example.com | 464 To: other@example.com |
456 Subject: SendMail test | 465 Subject: SendMail test |
457 | 466 |
458 SendMail is working for me. | 467 SendMail is working for me. |
459 . | 468 . |
460 QUIT | 469 QUIT |
461 ` | 470 ` |
OLD | NEW |