OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [http/] [transport_test.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Tests for transport.go
6
 
7
package http_test
8
 
9
import (
10
        "bytes"
11
        "compress/gzip"
12
        "crypto/rand"
13
        "fmt"
14
        "io"
15
        "io/ioutil"
16
        . "net/http"
17
        "net/http/httptest"
18
        "net/url"
19
        "strconv"
20
        "strings"
21
        "testing"
22
        "time"
23
)
24
 
25
// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
26
//       and then verify that the final 2 responses get errors back.
27
 
28
// hostPortHandler writes back the client's "host:port".
29
var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
30
        if r.FormValue("close") == "true" {
31
                w.Header().Set("Connection", "close")
32
        }
33
        w.Write([]byte(r.RemoteAddr))
34
})
35
 
36
// Two subsequent requests and verify their response is the same.
37
// The response from the server is our own IP:port
38
func TestTransportKeepAlives(t *testing.T) {
39
        ts := httptest.NewServer(hostPortHandler)
40
        defer ts.Close()
41
 
42
        for _, disableKeepAlive := range []bool{false, true} {
43
                tr := &Transport{DisableKeepAlives: disableKeepAlive}
44
                c := &Client{Transport: tr}
45
 
46
                fetch := func(n int) string {
47
                        res, err := c.Get(ts.URL)
48
                        if err != nil {
49
                                t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
50
                        }
51
                        body, err := ioutil.ReadAll(res.Body)
52
                        if err != nil {
53
                                t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
54
                        }
55
                        return string(body)
56
                }
57
 
58
                body1 := fetch(1)
59
                body2 := fetch(2)
60
 
61
                bodiesDiffer := body1 != body2
62
                if bodiesDiffer != disableKeepAlive {
63
                        t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
64
                                disableKeepAlive, bodiesDiffer, body1, body2)
65
                }
66
        }
67
}
68
 
69
func TestTransportConnectionCloseOnResponse(t *testing.T) {
70
        ts := httptest.NewServer(hostPortHandler)
71
        defer ts.Close()
72
 
73
        for _, connectionClose := range []bool{false, true} {
74
                tr := &Transport{}
75
                c := &Client{Transport: tr}
76
 
77
                fetch := func(n int) string {
78
                        req := new(Request)
79
                        var err error
80
                        req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
81
                        if err != nil {
82
                                t.Fatalf("URL parse error: %v", err)
83
                        }
84
                        req.Method = "GET"
85
                        req.Proto = "HTTP/1.1"
86
                        req.ProtoMajor = 1
87
                        req.ProtoMinor = 1
88
 
89
                        res, err := c.Do(req)
90
                        if err != nil {
91
                                t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
92
                        }
93
                        body, err := ioutil.ReadAll(res.Body)
94
                        defer res.Body.Close()
95
                        if err != nil {
96
                                t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
97
                        }
98
                        return string(body)
99
                }
100
 
101
                body1 := fetch(1)
102
                body2 := fetch(2)
103
                bodiesDiffer := body1 != body2
104
                if bodiesDiffer != connectionClose {
105
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
106
                                connectionClose, bodiesDiffer, body1, body2)
107
                }
108
        }
109
}
110
 
111
func TestTransportConnectionCloseOnRequest(t *testing.T) {
112
        ts := httptest.NewServer(hostPortHandler)
113
        defer ts.Close()
114
 
115
        for _, connectionClose := range []bool{false, true} {
116
                tr := &Transport{}
117
                c := &Client{Transport: tr}
118
 
119
                fetch := func(n int) string {
120
                        req := new(Request)
121
                        var err error
122
                        req.URL, err = url.Parse(ts.URL)
123
                        if err != nil {
124
                                t.Fatalf("URL parse error: %v", err)
125
                        }
126
                        req.Method = "GET"
127
                        req.Proto = "HTTP/1.1"
128
                        req.ProtoMajor = 1
129
                        req.ProtoMinor = 1
130
                        req.Close = connectionClose
131
 
132
                        res, err := c.Do(req)
133
                        if err != nil {
134
                                t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
135
                        }
136
                        body, err := ioutil.ReadAll(res.Body)
137
                        if err != nil {
138
                                t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
139
                        }
140
                        return string(body)
141
                }
142
 
143
                body1 := fetch(1)
144
                body2 := fetch(2)
145
                bodiesDiffer := body1 != body2
146
                if bodiesDiffer != connectionClose {
147
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
148
                                connectionClose, bodiesDiffer, body1, body2)
149
                }
150
        }
151
}
152
 
153
func TestTransportIdleCacheKeys(t *testing.T) {
154
        ts := httptest.NewServer(hostPortHandler)
155
        defer ts.Close()
156
 
157
        tr := &Transport{DisableKeepAlives: false}
158
        c := &Client{Transport: tr}
159
 
160
        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
161
                t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
162
        }
163
 
164
        resp, err := c.Get(ts.URL)
165
        if err != nil {
166
                t.Error(err)
167
        }
168
        ioutil.ReadAll(resp.Body)
169
 
170
        keys := tr.IdleConnKeysForTesting()
171
        if e, g := 1, len(keys); e != g {
172
                t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
173
        }
174
 
175
        if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
176
                t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
177
        }
178
 
179
        tr.CloseIdleConnections()
180
        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
181
                t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
182
        }
183
}
184
 
185
func TestTransportMaxPerHostIdleConns(t *testing.T) {
186
        resch := make(chan string)
187
        gotReq := make(chan bool)
188
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
189
                gotReq <- true
190
                msg := <-resch
191
                _, err := w.Write([]byte(msg))
192
                if err != nil {
193
                        t.Fatalf("Write: %v", err)
194
                }
195
        }))
196
        defer ts.Close()
197
        maxIdleConns := 2
198
        tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
199
        c := &Client{Transport: tr}
200
 
201
        // Start 3 outstanding requests and wait for the server to get them.
202
        // Their responses will hang until we we write to resch, though.
203
        donech := make(chan bool)
204
        doReq := func() {
205
                resp, err := c.Get(ts.URL)
206
                if err != nil {
207
                        t.Error(err)
208
                }
209
                _, err = ioutil.ReadAll(resp.Body)
210
                if err != nil {
211
                        t.Fatalf("ReadAll: %v", err)
212
                }
213
                donech <- true
214
        }
215
        go doReq()
216
        <-gotReq
217
        go doReq()
218
        <-gotReq
219
        go doReq()
220
        <-gotReq
221
 
222
        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
223
                t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
224
        }
225
 
226
        resch <- "res1"
227
        <-donech
228
        keys := tr.IdleConnKeysForTesting()
229
        if e, g := 1, len(keys); e != g {
230
                t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
231
        }
232
        cacheKey := "|http|" + ts.Listener.Addr().String()
233
        if keys[0] != cacheKey {
234
                t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
235
        }
236
        if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
237
                t.Errorf("after first response, expected %d idle conns; got %d", e, g)
238
        }
239
 
240
        resch <- "res2"
241
        <-donech
242
        if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
243
                t.Errorf("after second response, expected %d idle conns; got %d", e, g)
244
        }
245
 
246
        resch <- "res3"
247
        <-donech
248
        if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
249
                t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
250
        }
251
}
252
 
253
func TestTransportServerClosingUnexpectedly(t *testing.T) {
254
        ts := httptest.NewServer(hostPortHandler)
255
        defer ts.Close()
256
 
257
        tr := &Transport{}
258
        c := &Client{Transport: tr}
259
 
260
        fetch := func(n, retries int) string {
261
                condFatalf := func(format string, arg ...interface{}) {
262
                        if retries <= 0 {
263
                                t.Fatalf(format, arg...)
264
                        }
265
                        t.Logf("retrying shortly after expected error: "+format, arg...)
266
                        time.Sleep(time.Second / time.Duration(retries))
267
                }
268
                for retries >= 0 {
269
                        retries--
270
                        res, err := c.Get(ts.URL)
271
                        if err != nil {
272
                                condFatalf("error in req #%d, GET: %v", n, err)
273
                                continue
274
                        }
275
                        body, err := ioutil.ReadAll(res.Body)
276
                        if err != nil {
277
                                condFatalf("error in req #%d, ReadAll: %v", n, err)
278
                                continue
279
                        }
280
                        res.Body.Close()
281
                        return string(body)
282
                }
283
                panic("unreachable")
284
        }
285
 
286
        body1 := fetch(1, 0)
287
        body2 := fetch(2, 0)
288
 
289
        ts.CloseClientConnections() // surprise!
290
 
291
        // This test has an expected race. Sleeping for 25 ms prevents
292
        // it on most fast machines, causing the next fetch() call to
293
        // succeed quickly.  But if we do get errors, fetch() will retry 5
294
        // times with some delays between.
295
        time.Sleep(25 * time.Millisecond)
296
 
297
        body3 := fetch(3, 5)
298
 
299
        if body1 != body2 {
300
                t.Errorf("expected body1 and body2 to be equal")
301
        }
302
        if body2 == body3 {
303
                t.Errorf("expected body2 and body3 to be different")
304
        }
305
}
306
 
307
// Test for http://golang.org/issue/2616 (appropriate issue number)
308
// This fails pretty reliably with GOMAXPROCS=100 or something high.
309
func TestStressSurpriseServerCloses(t *testing.T) {
310
        if testing.Short() {
311
                t.Logf("skipping test in short mode")
312
                return
313
        }
314
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
315
                w.Header().Set("Content-Length", "5")
316
                w.Header().Set("Content-Type", "text/plain")
317
                w.Write([]byte("Hello"))
318
                w.(Flusher).Flush()
319
                conn, buf, _ := w.(Hijacker).Hijack()
320
                buf.Flush()
321
                conn.Close()
322
        }))
323
        defer ts.Close()
324
 
325
        tr := &Transport{DisableKeepAlives: false}
326
        c := &Client{Transport: tr}
327
 
328
        // Do a bunch of traffic from different goroutines. Send to activityc
329
        // after each request completes, regardless of whether it failed.
330
        const (
331
                numClients    = 50
332
                reqsPerClient = 250
333
        )
334
        activityc := make(chan bool)
335
        for i := 0; i < numClients; i++ {
336
                go func() {
337
                        for i := 0; i < reqsPerClient; i++ {
338
                                res, err := c.Get(ts.URL)
339
                                if err == nil {
340
                                        // We expect errors since the server is
341
                                        // hanging up on us after telling us to
342
                                        // send more requests, so we don't
343
                                        // actually care what the error is.
344
                                        // But we want to close the body in cases
345
                                        // where we won the race.
346
                                        res.Body.Close()
347
                                }
348
                                activityc <- true
349
                        }
350
                }()
351
        }
352
 
353
        // Make sure all the request come back, one way or another.
354
        for i := 0; i < numClients*reqsPerClient; i++ {
355
                select {
356
                case <-activityc:
357
                case <-time.After(5 * time.Second):
358
                        t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
359
                }
360
        }
361
}
362
 
363
// TestTransportHeadResponses verifies that we deal with Content-Lengths
364
// with no bodies properly
365
func TestTransportHeadResponses(t *testing.T) {
366
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
367
                if r.Method != "HEAD" {
368
                        panic("expected HEAD; got " + r.Method)
369
                }
370
                w.Header().Set("Content-Length", "123")
371
                w.WriteHeader(200)
372
        }))
373
        defer ts.Close()
374
 
375
        tr := &Transport{DisableKeepAlives: false}
376
        c := &Client{Transport: tr}
377
        for i := 0; i < 2; i++ {
378
                res, err := c.Head(ts.URL)
379
                if err != nil {
380
                        t.Errorf("error on loop %d: %v", i, err)
381
                }
382
                if e, g := "123", res.Header.Get("Content-Length"); e != g {
383
                        t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
384
                }
385
                if e, g := int64(0), res.ContentLength; e != g {
386
                        t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
387
                }
388
        }
389
}
390
 
391
// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
392
// on responses to HEAD requests.
393
func TestTransportHeadChunkedResponse(t *testing.T) {
394
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
395
                if r.Method != "HEAD" {
396
                        panic("expected HEAD; got " + r.Method)
397
                }
398
                w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
399
                w.Header().Set("x-client-ipport", r.RemoteAddr)
400
                w.WriteHeader(200)
401
        }))
402
        defer ts.Close()
403
 
404
        tr := &Transport{DisableKeepAlives: false}
405
        c := &Client{Transport: tr}
406
 
407
        res1, err := c.Head(ts.URL)
408
        if err != nil {
409
                t.Fatalf("request 1 error: %v", err)
410
        }
411
        res2, err := c.Head(ts.URL)
412
        if err != nil {
413
                t.Fatalf("request 2 error: %v", err)
414
        }
415
        if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
416
                t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
417
        }
418
}
419
 
420
var roundTripTests = []struct {
421
        accept       string
422
        expectAccept string
423
        compressed   bool
424
}{
425
        // Requests with no accept-encoding header use transparent compression
426
        {"", "gzip", false},
427
        // Requests with other accept-encoding should pass through unmodified
428
        {"foo", "foo", false},
429
        // Requests with accept-encoding == gzip should be passed through
430
        {"gzip", "gzip", true},
431
}
432
 
433
// Test that the modification made to the Request by the RoundTripper is cleaned up
434
func TestRoundTripGzip(t *testing.T) {
435
        const responseBody = "test response body"
436
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
437
                accept := req.Header.Get("Accept-Encoding")
438
                if expect := req.FormValue("expect_accept"); accept != expect {
439
                        t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
440
                                req.FormValue("testnum"), accept, expect)
441
                }
442
                if accept == "gzip" {
443
                        rw.Header().Set("Content-Encoding", "gzip")
444
                        gz, err := gzip.NewWriter(rw)
445
                        if err != nil {
446
                                t.Errorf("gzip NewWriter: %v", err)
447
                                return
448
                        }
449
                        gz.Write([]byte(responseBody))
450
                        gz.Close()
451
                } else {
452
                        rw.Header().Set("Content-Encoding", accept)
453
                        rw.Write([]byte(responseBody))
454
                }
455
        }))
456
        defer ts.Close()
457
 
458
        for i, test := range roundTripTests {
459
                // Test basic request (no accept-encoding)
460
                req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
461
                if test.accept != "" {
462
                        req.Header.Set("Accept-Encoding", test.accept)
463
                }
464
                res, err := DefaultTransport.RoundTrip(req)
465
                var body []byte
466
                if test.compressed {
467
                        gzip, err := gzip.NewReader(res.Body)
468
                        if err != nil {
469
                                t.Errorf("%d. gzip NewReader: %v", i, err)
470
                                continue
471
                        }
472
                        body, err = ioutil.ReadAll(gzip)
473
                        res.Body.Close()
474
                } else {
475
                        body, err = ioutil.ReadAll(res.Body)
476
                }
477
                if err != nil {
478
                        t.Errorf("%d. Error: %q", i, err)
479
                        continue
480
                }
481
                if g, e := string(body), responseBody; g != e {
482
                        t.Errorf("%d. body = %q; want %q", i, g, e)
483
                }
484
                if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
485
                        t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
486
                }
487
                if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
488
                        t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
489
                }
490
        }
491
 
492
}
493
 
494
func TestTransportGzip(t *testing.T) {
495
        const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
496
        const nRandBytes = 1024 * 1024
497
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
498
                if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
499
                        t.Errorf("Accept-Encoding = %q, want %q", g, e)
500
                }
501
                rw.Header().Set("Content-Encoding", "gzip")
502
                if req.Method == "HEAD" {
503
                        return
504
                }
505
 
506
                var w io.Writer = rw
507
                var buf bytes.Buffer
508
                if req.FormValue("chunked") == "0" {
509
                        w = &buf
510
                        defer io.Copy(rw, &buf)
511
                        defer func() {
512
                                rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
513
                        }()
514
                }
515
                gz, _ := gzip.NewWriter(w)
516
                gz.Write([]byte(testString))
517
                if req.FormValue("body") == "large" {
518
                        io.CopyN(gz, rand.Reader, nRandBytes)
519
                }
520
                gz.Close()
521
        }))
522
        defer ts.Close()
523
 
524
        for _, chunked := range []string{"1", "0"} {
525
                c := &Client{Transport: &Transport{}}
526
 
527
                // First fetch something large, but only read some of it.
528
                res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
529
                if err != nil {
530
                        t.Fatalf("large get: %v", err)
531
                }
532
                buf := make([]byte, len(testString))
533
                n, err := io.ReadFull(res.Body, buf)
534
                if err != nil {
535
                        t.Fatalf("partial read of large response: size=%d, %v", n, err)
536
                }
537
                if e, g := testString, string(buf); e != g {
538
                        t.Errorf("partial read got %q, expected %q", g, e)
539
                }
540
                res.Body.Close()
541
                // Read on the body, even though it's closed
542
                n, err = res.Body.Read(buf)
543
                if n != 0 || err == nil {
544
                        t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
545
                }
546
 
547
                // Then something small.
548
                res, err = c.Get(ts.URL + "/?chunked=" + chunked)
549
                if err != nil {
550
                        t.Fatal(err)
551
                }
552
                body, err := ioutil.ReadAll(res.Body)
553
                if err != nil {
554
                        t.Fatal(err)
555
                }
556
                if g, e := string(body), testString; g != e {
557
                        t.Fatalf("body = %q; want %q", g, e)
558
                }
559
                if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
560
                        t.Fatalf("Content-Encoding = %q; want %q", g, e)
561
                }
562
 
563
                // Read on the body after it's been fully read:
564
                n, err = res.Body.Read(buf)
565
                if n != 0 || err == nil {
566
                        t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
567
                }
568
                res.Body.Close()
569
                n, err = res.Body.Read(buf)
570
                if n != 0 || err == nil {
571
                        t.Errorf("expected Read error after Close; got %d, %v", n, err)
572
                }
573
        }
574
 
575
        // And a HEAD request too, because they're always weird.
576
        c := &Client{Transport: &Transport{}}
577
        res, err := c.Head(ts.URL)
578
        if err != nil {
579
                t.Fatalf("Head: %v", err)
580
        }
581
        if res.StatusCode != 200 {
582
                t.Errorf("Head status=%d; want=200", res.StatusCode)
583
        }
584
}
585
 
586
func TestTransportProxy(t *testing.T) {
587
        ch := make(chan string, 1)
588
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
589
                ch <- "real server"
590
        }))
591
        defer ts.Close()
592
        proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
593
                ch <- "proxy for " + r.URL.String()
594
        }))
595
        defer proxy.Close()
596
 
597
        pu, err := url.Parse(proxy.URL)
598
        if err != nil {
599
                t.Fatal(err)
600
        }
601
        c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
602
        c.Head(ts.URL)
603
        got := <-ch
604
        want := "proxy for " + ts.URL + "/"
605
        if got != want {
606
                t.Errorf("want %q, got %q", want, got)
607
        }
608
}
609
 
610
// TestTransportGzipRecursive sends a gzip quine and checks that the
611
// client gets the same value back. This is more cute than anything,
612
// but checks that we don't recurse forever, and checks that
613
// Content-Encoding is removed.
614
func TestTransportGzipRecursive(t *testing.T) {
615
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
616
                w.Header().Set("Content-Encoding", "gzip")
617
                w.Write(rgz)
618
        }))
619
        defer ts.Close()
620
 
621
        c := &Client{Transport: &Transport{}}
622
        res, err := c.Get(ts.URL)
623
        if err != nil {
624
                t.Fatal(err)
625
        }
626
        body, err := ioutil.ReadAll(res.Body)
627
        if err != nil {
628
                t.Fatal(err)
629
        }
630
        if !bytes.Equal(body, rgz) {
631
                t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
632
                        body, rgz)
633
        }
634
        if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
635
                t.Fatalf("Content-Encoding = %q; want %q", g, e)
636
        }
637
}
638
 
639
type fooProto struct{}
640
 
641
func (fooProto) RoundTrip(req *Request) (*Response, error) {
642
        res := &Response{
643
                Status:     "200 OK",
644
                StatusCode: 200,
645
                Header:     make(Header),
646
                Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
647
        }
648
        return res, nil
649
}
650
 
651
func TestTransportAltProto(t *testing.T) {
652
        tr := &Transport{}
653
        c := &Client{Transport: tr}
654
        tr.RegisterProtocol("foo", fooProto{})
655
        res, err := c.Get("foo://bar.com/path")
656
        if err != nil {
657
                t.Fatal(err)
658
        }
659
        bodyb, err := ioutil.ReadAll(res.Body)
660
        if err != nil {
661
                t.Fatal(err)
662
        }
663
        body := string(bodyb)
664
        if e := "You wanted foo://bar.com/path"; body != e {
665
                t.Errorf("got response %q, want %q", body, e)
666
        }
667
}
668
 
669
// rgz is a gzip quine that uncompresses to itself.
670
var rgz = []byte{
671
        0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
672
        0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
673
        0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
674
        0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
675
        0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
676
        0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
677
        0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
678
        0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
679
        0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
680
        0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
681
        0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
682
        0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
683
        0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
684
        0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
685
        0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
686
        0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
687
        0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
688
        0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
689
        0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
690
        0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
691
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
692
        0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
693
        0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
694
        0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
695
        0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
696
        0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
697
        0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
698
        0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
699
        0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
700
        0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
701
        0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
702
        0x00, 0x00,
703
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.