~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/net/http/client_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
package http_test
8
8
 
9
9
import (
 
10
        "bytes"
10
11
        "crypto/tls"
 
12
        "crypto/x509"
11
13
        "errors"
12
14
        "fmt"
13
15
        "io"
49
51
                        return b, err
50
52
                }
51
53
        }
52
 
        panic("unreachable")
53
54
}
54
55
 
55
56
func TestClient(t *testing.T) {
 
57
        defer afterTest(t)
56
58
        ts := httptest.NewServer(robotsTxtHandler)
57
59
        defer ts.Close()
58
60
 
70
72
}
71
73
 
72
74
func TestClientHead(t *testing.T) {
 
75
        defer afterTest(t)
73
76
        ts := httptest.NewServer(robotsTxtHandler)
74
77
        defer ts.Close()
75
78
 
92
95
}
93
96
 
94
97
func TestGetRequestFormat(t *testing.T) {
 
98
        defer afterTest(t)
95
99
        tr := &recordingTransport{}
96
100
        client := &Client{Transport: tr}
97
101
        url := "http://dummy.faketld/"
108
112
}
109
113
 
110
114
func TestPostRequestFormat(t *testing.T) {
 
115
        defer afterTest(t)
111
116
        tr := &recordingTransport{}
112
117
        client := &Client{Transport: tr}
113
118
 
134
139
}
135
140
 
136
141
func TestPostFormRequestFormat(t *testing.T) {
 
142
        defer afterTest(t)
137
143
        tr := &recordingTransport{}
138
144
        client := &Client{Transport: tr}
139
145
 
174
180
        }
175
181
}
176
182
 
177
 
func TestRedirects(t *testing.T) {
 
183
func TestClientRedirects(t *testing.T) {
 
184
        defer afterTest(t)
178
185
        var ts *httptest.Server
179
186
        ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
180
187
                n, _ := strconv.Atoi(r.FormValue("n"))
218
225
                return checkErr
219
226
        }}
220
227
        res, err := c.Get(ts.URL)
 
228
        if err != nil {
 
229
                t.Fatalf("Get error: %v", err)
 
230
        }
 
231
        res.Body.Close()
221
232
        finalUrl := res.Request.URL.String()
222
233
        if e, g := "<nil>", fmt.Sprintf("%v", err); e != g {
223
234
                t.Errorf("with custom client, expected error %q, got %q", e, g)
231
242
 
232
243
        checkErr = errors.New("no redirects allowed")
233
244
        res, err = c.Get(ts.URL)
234
 
        finalUrl = res.Request.URL.String()
235
 
        if e, g := "Get /?n=1: no redirects allowed", fmt.Sprintf("%v", err); e != g {
236
 
                t.Errorf("with redirects forbidden, expected error %q, got %q", e, g)
 
245
        if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr {
 
246
                t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
 
247
        }
 
248
        if res == nil {
 
249
                t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)")
 
250
        }
 
251
        res.Body.Close()
 
252
        if res.Header.Get("Location") == "" {
 
253
                t.Errorf("no Location header in Response")
 
254
        }
 
255
}
 
256
 
 
257
func TestPostRedirects(t *testing.T) {
 
258
        defer afterTest(t)
 
259
        var log struct {
 
260
                sync.Mutex
 
261
                bytes.Buffer
 
262
        }
 
263
        var ts *httptest.Server
 
264
        ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 
265
                log.Lock()
 
266
                fmt.Fprintf(&log.Buffer, "%s %s ", r.Method, r.RequestURI)
 
267
                log.Unlock()
 
268
                if v := r.URL.Query().Get("code"); v != "" {
 
269
                        code, _ := strconv.Atoi(v)
 
270
                        if code/100 == 3 {
 
271
                                w.Header().Set("Location", ts.URL)
 
272
                        }
 
273
                        w.WriteHeader(code)
 
274
                }
 
275
        }))
 
276
        defer ts.Close()
 
277
        tests := []struct {
 
278
                suffix string
 
279
                want   int // response code
 
280
        }{
 
281
                {"/", 200},
 
282
                {"/?code=301", 301},
 
283
                {"/?code=302", 200},
 
284
                {"/?code=303", 200},
 
285
                {"/?code=404", 404},
 
286
        }
 
287
        for _, tt := range tests {
 
288
                res, err := Post(ts.URL+tt.suffix, "text/plain", strings.NewReader("Some content"))
 
289
                if err != nil {
 
290
                        t.Fatal(err)
 
291
                }
 
292
                if res.StatusCode != tt.want {
 
293
                        t.Errorf("POST %s: status code = %d; want %d", tt.suffix, res.StatusCode, tt.want)
 
294
                }
 
295
        }
 
296
        log.Lock()
 
297
        got := log.String()
 
298
        log.Unlock()
 
299
        want := "POST / POST /?code=301 POST /?code=302 GET / POST /?code=303 GET / POST /?code=404 "
 
300
        if got != want {
 
301
                t.Errorf("Log differs.\n Got: %q\nWant: %q", got, want)
237
302
        }
238
303
}
239
304
 
279
344
        req, _ := NewRequest("GET", us, nil)
280
345
        client.Do(req) // Note: doesn't hit network
281
346
        matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
 
347
 
 
348
        req, _ = NewRequest("POST", us, nil)
 
349
        client.Do(req) // Note: doesn't hit network
 
350
        matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
282
351
}
283
352
 
284
353
// Just enough correctness for our redirect tests. Uses the URL.Host as the
291
360
func (j *TestJar) SetCookies(u *url.URL, cookies []*Cookie) {
292
361
        j.m.Lock()
293
362
        defer j.m.Unlock()
 
363
        if j.perURL == nil {
 
364
                j.perURL = make(map[string][]*Cookie)
 
365
        }
294
366
        j.perURL[u.Host] = cookies
295
367
}
296
368
 
301
373
}
302
374
 
303
375
func TestRedirectCookiesOnRequest(t *testing.T) {
 
376
        defer afterTest(t)
304
377
        var ts *httptest.Server
305
378
        ts = httptest.NewServer(echoCookiesRedirectHandler)
306
379
        defer ts.Close()
318
391
}
319
392
 
320
393
func TestRedirectCookiesJar(t *testing.T) {
 
394
        defer afterTest(t)
321
395
        var ts *httptest.Server
322
396
        ts = httptest.NewServer(echoCookiesRedirectHandler)
323
397
        defer ts.Close()
324
 
        c := &Client{}
325
 
        c.Jar = &TestJar{perURL: make(map[string][]*Cookie)}
 
398
        c := &Client{
 
399
                Jar: new(TestJar),
 
400
        }
326
401
        u, _ := url.Parse(ts.URL)
327
402
        c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]})
328
 
        resp, _ := c.Get(ts.URL)
 
403
        resp, err := c.Get(ts.URL)
 
404
        if err != nil {
 
405
                t.Fatalf("Get: %v", err)
 
406
        }
 
407
        resp.Body.Close()
329
408
        matchReturnedCookies(t, expectedCookies, resp.Cookies())
330
409
}
331
410
 
348
427
        }
349
428
}
350
429
 
 
430
func TestJarCalls(t *testing.T) {
 
431
        defer afterTest(t)
 
432
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 
433
                pathSuffix := r.RequestURI[1:]
 
434
                if r.RequestURI == "/nosetcookie" {
 
435
                        return // dont set cookies for this path
 
436
                }
 
437
                SetCookie(w, &Cookie{Name: "name" + pathSuffix, Value: "val" + pathSuffix})
 
438
                if r.RequestURI == "/" {
 
439
                        Redirect(w, r, "http://secondhost.fake/secondpath", 302)
 
440
                }
 
441
        }))
 
442
        defer ts.Close()
 
443
        jar := new(RecordingJar)
 
444
        c := &Client{
 
445
                Jar: jar,
 
446
                Transport: &Transport{
 
447
                        Dial: func(_ string, _ string) (net.Conn, error) {
 
448
                                return net.Dial("tcp", ts.Listener.Addr().String())
 
449
                        },
 
450
                },
 
451
        }
 
452
        _, err := c.Get("http://firsthost.fake/")
 
453
        if err != nil {
 
454
                t.Fatal(err)
 
455
        }
 
456
        _, err = c.Get("http://firsthost.fake/nosetcookie")
 
457
        if err != nil {
 
458
                t.Fatal(err)
 
459
        }
 
460
        got := jar.log.String()
 
461
        want := `Cookies("http://firsthost.fake/")
 
462
SetCookie("http://firsthost.fake/", [name=val])
 
463
Cookies("http://secondhost.fake/secondpath")
 
464
SetCookie("http://secondhost.fake/secondpath", [namesecondpath=valsecondpath])
 
465
Cookies("http://firsthost.fake/nosetcookie")
 
466
`
 
467
        if got != want {
 
468
                t.Errorf("Got Jar calls:\n%s\nWant:\n%s", got, want)
 
469
        }
 
470
}
 
471
 
 
472
// RecordingJar keeps a log of calls made to it, without
 
473
// tracking any cookies.
 
474
type RecordingJar struct {
 
475
        mu  sync.Mutex
 
476
        log bytes.Buffer
 
477
}
 
478
 
 
479
func (j *RecordingJar) SetCookies(u *url.URL, cookies []*Cookie) {
 
480
        j.logf("SetCookie(%q, %v)\n", u, cookies)
 
481
}
 
482
 
 
483
func (j *RecordingJar) Cookies(u *url.URL) []*Cookie {
 
484
        j.logf("Cookies(%q)\n", u)
 
485
        return nil
 
486
}
 
487
 
 
488
func (j *RecordingJar) logf(format string, args ...interface{}) {
 
489
        j.mu.Lock()
 
490
        defer j.mu.Unlock()
 
491
        fmt.Fprintf(&j.log, format, args...)
 
492
}
 
493
 
351
494
func TestStreamingGet(t *testing.T) {
 
495
        defer afterTest(t)
352
496
        say := make(chan string)
353
497
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
354
498
                w.(Flusher).Flush()
399
543
// TestClientWrites verifies that client requests are buffered and we
400
544
// don't send a TCP packet per line of the http request + body.
401
545
func TestClientWrites(t *testing.T) {
 
546
        defer afterTest(t)
402
547
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
403
548
        }))
404
549
        defer ts.Close()
432
577
}
433
578
 
434
579
func TestClientInsecureTransport(t *testing.T) {
 
580
        defer afterTest(t)
435
581
        ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
436
582
                w.Write([]byte("Hello"))
437
583
        }))
446
592
                                InsecureSkipVerify: insecure,
447
593
                        },
448
594
                }
 
595
                defer tr.CloseIdleConnections()
449
596
                c := &Client{Transport: tr}
450
 
                _, err := c.Get(ts.URL)
 
597
                res, err := c.Get(ts.URL)
451
598
                if (err == nil) != insecure {
452
599
                        t.Errorf("insecure=%v: got unexpected err=%v", insecure, err)
453
600
                }
 
601
                if res != nil {
 
602
                        res.Body.Close()
 
603
                }
454
604
        }
455
605
}
456
606
 
457
607
func TestClientErrorWithRequestURI(t *testing.T) {
 
608
        defer afterTest(t)
458
609
        req, _ := NewRequest("GET", "http://localhost:1234/", nil)
459
610
        req.RequestURI = "/this/field/is/illegal/and/should/error/"
460
611
        _, err := DefaultClient.Do(req)
465
616
                t.Errorf("wanted error mentioning RequestURI; got error: %v", err)
466
617
        }
467
618
}
 
619
 
 
620
func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport {
 
621
        certs := x509.NewCertPool()
 
622
        for _, c := range ts.TLS.Certificates {
 
623
                roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
 
624
                if err != nil {
 
625
                        t.Fatalf("error parsing server's root cert: %v", err)
 
626
                }
 
627
                for _, root := range roots {
 
628
                        certs.AddCert(root)
 
629
                }
 
630
        }
 
631
        return &Transport{
 
632
                TLSClientConfig: &tls.Config{RootCAs: certs},
 
633
        }
 
634
}
 
635
 
 
636
func TestClientWithCorrectTLSServerName(t *testing.T) {
 
637
        defer afterTest(t)
 
638
        ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 
639
                if r.TLS.ServerName != "127.0.0.1" {
 
640
                        t.Errorf("expected client to set ServerName 127.0.0.1, got: %q", r.TLS.ServerName)
 
641
                }
 
642
        }))
 
643
        defer ts.Close()
 
644
 
 
645
        c := &Client{Transport: newTLSTransport(t, ts)}
 
646
        if _, err := c.Get(ts.URL); err != nil {
 
647
                t.Fatalf("expected successful TLS connection, got error: %v", err)
 
648
        }
 
649
}
 
650
 
 
651
func TestClientWithIncorrectTLSServerName(t *testing.T) {
 
652
        defer afterTest(t)
 
653
        ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
 
654
        defer ts.Close()
 
655
 
 
656
        trans := newTLSTransport(t, ts)
 
657
        trans.TLSClientConfig.ServerName = "badserver"
 
658
        c := &Client{Transport: trans}
 
659
        _, err := c.Get(ts.URL)
 
660
        if err == nil {
 
661
                t.Fatalf("expected an error")
 
662
        }
 
663
        if !strings.Contains(err.Error(), "127.0.0.1") || !strings.Contains(err.Error(), "badserver") {
 
664
                t.Errorf("wanted error mentioning 127.0.0.1 and badserver; got error: %v", err)
 
665
        }
 
666
}
 
667
 
 
668
// Verify Response.ContentLength is populated. http://golang.org/issue/4126
 
669
func TestClientHeadContentLength(t *testing.T) {
 
670
        defer afterTest(t)
 
671
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 
672
                if v := r.FormValue("cl"); v != "" {
 
673
                        w.Header().Set("Content-Length", v)
 
674
                }
 
675
        }))
 
676
        defer ts.Close()
 
677
        tests := []struct {
 
678
                suffix string
 
679
                want   int64
 
680
        }{
 
681
                {"/?cl=1234", 1234},
 
682
                {"/?cl=0", 0},
 
683
                {"", -1},
 
684
        }
 
685
        for _, tt := range tests {
 
686
                req, _ := NewRequest("HEAD", ts.URL+tt.suffix, nil)
 
687
                res, err := DefaultClient.Do(req)
 
688
                if err != nil {
 
689
                        t.Fatal(err)
 
690
                }
 
691
                if res.ContentLength != tt.want {
 
692
                        t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want)
 
693
                }
 
694
                bs, err := ioutil.ReadAll(res.Body)
 
695
                if err != nil {
 
696
                        t.Fatal(err)
 
697
                }
 
698
                if len(bs) != 0 {
 
699
                        t.Errorf("Unexpected content: %q", bs)
 
700
                }
 
701
        }
 
702
}