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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2010 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
// End-to-end serving tests
6
 
7
package http_test
8
 
9
import (
10
        "bufio"
11
        "bytes"
12
        "crypto/tls"
13
        "fmt"
14
        "io"
15
        "io/ioutil"
16
        "log"
17
        "net"
18
        . "net/http"
19
        "net/http/httptest"
20
        "net/http/httputil"
21
        "net/url"
22
        "os"
23
        "reflect"
24
        "strings"
25
        "syscall"
26
        "testing"
27
        "time"
28
)
29
 
30
type dummyAddr string
31
type oneConnListener struct {
32
        conn net.Conn
33
}
34
 
35
func (l *oneConnListener) Accept() (c net.Conn, err error) {
36
        c = l.conn
37
        if c == nil {
38
                err = io.EOF
39
                return
40
        }
41
        err = nil
42
        l.conn = nil
43
        return
44
}
45
 
46
func (l *oneConnListener) Close() error {
47
        return nil
48
}
49
 
50
func (l *oneConnListener) Addr() net.Addr {
51
        return dummyAddr("test-address")
52
}
53
 
54
func (a dummyAddr) Network() string {
55
        return string(a)
56
}
57
 
58
func (a dummyAddr) String() string {
59
        return string(a)
60
}
61
 
62
type testConn struct {
63
        readBuf  bytes.Buffer
64
        writeBuf bytes.Buffer
65
}
66
 
67
func (c *testConn) Read(b []byte) (int, error) {
68
        return c.readBuf.Read(b)
69
}
70
 
71
func (c *testConn) Write(b []byte) (int, error) {
72
        return c.writeBuf.Write(b)
73
}
74
 
75
func (c *testConn) Close() error {
76
        return nil
77
}
78
 
79
func (c *testConn) LocalAddr() net.Addr {
80
        return dummyAddr("local-addr")
81
}
82
 
83
func (c *testConn) RemoteAddr() net.Addr {
84
        return dummyAddr("remote-addr")
85
}
86
 
87
func (c *testConn) SetDeadline(t time.Time) error {
88
        return nil
89
}
90
 
91
func (c *testConn) SetReadDeadline(t time.Time) error {
92
        return nil
93
}
94
 
95
func (c *testConn) SetWriteDeadline(t time.Time) error {
96
        return nil
97
}
98
 
99
func TestConsumingBodyOnNextConn(t *testing.T) {
100
        conn := new(testConn)
101
        for i := 0; i < 2; i++ {
102
                conn.readBuf.Write([]byte(
103
                        "POST / HTTP/1.1\r\n" +
104
                                "Host: test\r\n" +
105
                                "Content-Length: 11\r\n" +
106
                                "\r\n" +
107
                                "foo=1&bar=1"))
108
        }
109
 
110
        reqNum := 0
111
        ch := make(chan *Request)
112
        servech := make(chan error)
113
        listener := &oneConnListener{conn}
114
        handler := func(res ResponseWriter, req *Request) {
115
                reqNum++
116
                ch <- req
117
        }
118
 
119
        go func() {
120
                servech <- Serve(listener, HandlerFunc(handler))
121
        }()
122
 
123
        var req *Request
124
        req = <-ch
125
        if req == nil {
126
                t.Fatal("Got nil first request.")
127
        }
128
        if req.Method != "POST" {
129
                t.Errorf("For request #1's method, got %q; expected %q",
130
                        req.Method, "POST")
131
        }
132
 
133
        req = <-ch
134
        if req == nil {
135
                t.Fatal("Got nil first request.")
136
        }
137
        if req.Method != "POST" {
138
                t.Errorf("For request #2's method, got %q; expected %q",
139
                        req.Method, "POST")
140
        }
141
 
142
        if serveerr := <-servech; serveerr != io.EOF {
143
                t.Errorf("Serve returned %q; expected EOF", serveerr)
144
        }
145
}
146
 
147
type stringHandler string
148
 
149
func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
150
        w.Header().Set("Result", string(s))
151
}
152
 
153
var handlers = []struct {
154
        pattern string
155
        msg     string
156
}{
157
        {"/", "Default"},
158
        {"/someDir/", "someDir"},
159
        {"someHost.com/someDir/", "someHost.com/someDir"},
160
}
161
 
162
var vtests = []struct {
163
        url      string
164
        expected string
165
}{
166
        {"http://localhost/someDir/apage", "someDir"},
167
        {"http://localhost/otherDir/apage", "Default"},
168
        {"http://someHost.com/someDir/apage", "someHost.com/someDir"},
169
        {"http://otherHost.com/someDir/apage", "someDir"},
170
        {"http://otherHost.com/aDir/apage", "Default"},
171
}
172
 
173
func TestHostHandlers(t *testing.T) {
174
        for _, h := range handlers {
175
                Handle(h.pattern, stringHandler(h.msg))
176
        }
177
        ts := httptest.NewServer(nil)
178
        defer ts.Close()
179
 
180
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
181
        if err != nil {
182
                t.Fatal(err)
183
        }
184
        defer conn.Close()
185
        cc := httputil.NewClientConn(conn, nil)
186
        for _, vt := range vtests {
187
                var r *Response
188
                var req Request
189
                if req.URL, err = url.Parse(vt.url); err != nil {
190
                        t.Errorf("cannot parse url: %v", err)
191
                        continue
192
                }
193
                if err := cc.Write(&req); err != nil {
194
                        t.Errorf("writing request: %v", err)
195
                        continue
196
                }
197
                r, err := cc.Read(&req)
198
                if err != nil {
199
                        t.Errorf("reading response: %v", err)
200
                        continue
201
                }
202
                s := r.Header.Get("Result")
203
                if s != vt.expected {
204
                        t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
205
                }
206
        }
207
}
208
 
209
// Tests for http://code.google.com/p/go/issues/detail?id=900
210
func TestMuxRedirectLeadingSlashes(t *testing.T) {
211
        paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
212
        for _, path := range paths {
213
                req, err := ReadRequest(bufio.NewReader(bytes.NewBufferString("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
214
                if err != nil {
215
                        t.Errorf("%s", err)
216
                }
217
                mux := NewServeMux()
218
                resp := httptest.NewRecorder()
219
 
220
                mux.ServeHTTP(resp, req)
221
 
222
                if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected {
223
                        t.Errorf("Expected Location header set to %q; got %q", expected, loc)
224
                        return
225
                }
226
 
227
                if code, expected := resp.Code, StatusMovedPermanently; code != expected {
228
                        t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
229
                        return
230
                }
231
        }
232
}
233
 
234
func TestServerTimeouts(t *testing.T) {
235
        // TODO(bradfitz): convert this to use httptest.Server
236
        l, err := net.Listen("tcp", "127.0.0.1:0")
237
        if err != nil {
238
                t.Fatalf("listen error: %v", err)
239
        }
240
        addr, _ := l.Addr().(*net.TCPAddr)
241
 
242
        reqNum := 0
243
        handler := HandlerFunc(func(res ResponseWriter, req *Request) {
244
                reqNum++
245
                fmt.Fprintf(res, "req=%d", reqNum)
246
        })
247
 
248
        const second = 1000000000 /* nanos */
249
        server := &Server{Handler: handler, ReadTimeout: 0.25 * second, WriteTimeout: 0.25 * second}
250
        go server.Serve(l)
251
 
252
        url := fmt.Sprintf("http://%s/", addr)
253
 
254
        // Hit the HTTP server successfully.
255
        tr := &Transport{DisableKeepAlives: true} // they interfere with this test
256
        c := &Client{Transport: tr}
257
        r, err := c.Get(url)
258
        if err != nil {
259
                t.Fatalf("http Get #1: %v", err)
260
        }
261
        got, _ := ioutil.ReadAll(r.Body)
262
        expected := "req=1"
263
        if string(got) != expected {
264
                t.Errorf("Unexpected response for request #1; got %q; expected %q",
265
                        string(got), expected)
266
        }
267
 
268
        // Slow client that should timeout.
269
        t1 := time.Now()
270
        conn, err := net.Dial("tcp", addr.String())
271
        if err != nil {
272
                t.Fatalf("Dial: %v", err)
273
        }
274
        buf := make([]byte, 1)
275
        n, err := conn.Read(buf)
276
        latency := time.Now().Sub(t1)
277
        if n != 0 || err != io.EOF {
278
                t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
279
        }
280
        if latency < 200*time.Millisecond /* fudge from 0.25 above */ {
281
                t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
282
        }
283
 
284
        // Hit the HTTP server successfully again, verifying that the
285
        // previous slow connection didn't run our handler.  (that we
286
        // get "req=2", not "req=3")
287
        r, err = Get(url)
288
        if err != nil {
289
                t.Fatalf("http Get #2: %v", err)
290
        }
291
        got, _ = ioutil.ReadAll(r.Body)
292
        expected = "req=2"
293
        if string(got) != expected {
294
                t.Errorf("Get #2 got %q, want %q", string(got), expected)
295
        }
296
 
297
        l.Close()
298
}
299
 
300
// TestIdentityResponse verifies that a handler can unset
301
func TestIdentityResponse(t *testing.T) {
302
        handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
303
                rw.Header().Set("Content-Length", "3")
304
                rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
305
                switch {
306
                case req.FormValue("overwrite") == "1":
307
                        _, err := rw.Write([]byte("foo TOO LONG"))
308
                        if err != ErrContentLength {
309
                                t.Errorf("expected ErrContentLength; got %v", err)
310
                        }
311
                case req.FormValue("underwrite") == "1":
312
                        rw.Header().Set("Content-Length", "500")
313
                        rw.Write([]byte("too short"))
314
                default:
315
                        rw.Write([]byte("foo"))
316
                }
317
        })
318
 
319
        ts := httptest.NewServer(handler)
320
        defer ts.Close()
321
 
322
        // Note: this relies on the assumption (which is true) that
323
        // Get sends HTTP/1.1 or greater requests.  Otherwise the
324
        // server wouldn't have the choice to send back chunked
325
        // responses.
326
        for _, te := range []string{"", "identity"} {
327
                url := ts.URL + "/?te=" + te
328
                res, err := Get(url)
329
                if err != nil {
330
                        t.Fatalf("error with Get of %s: %v", url, err)
331
                }
332
                if cl, expected := res.ContentLength, int64(3); cl != expected {
333
                        t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
334
                }
335
                if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
336
                        t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
337
                }
338
                if tl, expected := len(res.TransferEncoding), 0; tl != expected {
339
                        t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
340
                                url, expected, tl, res.TransferEncoding)
341
                }
342
                res.Body.Close()
343
        }
344
 
345
        // Verify that ErrContentLength is returned
346
        url := ts.URL + "/?overwrite=1"
347
        _, err := Get(url)
348
        if err != nil {
349
                t.Fatalf("error with Get of %s: %v", url, err)
350
        }
351
        // Verify that the connection is closed when the declared Content-Length
352
        // is larger than what the handler wrote.
353
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
354
        if err != nil {
355
                t.Fatalf("error dialing: %v", err)
356
        }
357
        _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
358
        if err != nil {
359
                t.Fatalf("error writing: %v", err)
360
        }
361
 
362
        // The ReadAll will hang for a failing test, so use a Timer to
363
        // fail explicitly.
364
        goTimeout(t, 2*time.Second, func() {
365
                got, _ := ioutil.ReadAll(conn)
366
                expectedSuffix := "\r\n\r\ntoo short"
367
                if !strings.HasSuffix(string(got), expectedSuffix) {
368
                        t.Errorf("Expected output to end with %q; got response body %q",
369
                                expectedSuffix, string(got))
370
                }
371
        })
372
}
373
 
374
func testTcpConnectionCloses(t *testing.T, req string, h Handler) {
375
        s := httptest.NewServer(h)
376
        defer s.Close()
377
 
378
        conn, err := net.Dial("tcp", s.Listener.Addr().String())
379
        if err != nil {
380
                t.Fatal("dial error:", err)
381
        }
382
        defer conn.Close()
383
 
384
        _, err = fmt.Fprint(conn, req)
385
        if err != nil {
386
                t.Fatal("print error:", err)
387
        }
388
 
389
        r := bufio.NewReader(conn)
390
        _, err = ReadResponse(r, &Request{Method: "GET"})
391
        if err != nil {
392
                t.Fatal("ReadResponse error:", err)
393
        }
394
 
395
        success := make(chan bool)
396
        go func() {
397
                select {
398
                case <-time.After(5 * time.Second):
399
                        t.Fatal("body not closed after 5s")
400
                case <-success:
401
                }
402
        }()
403
 
404
        _, err = ioutil.ReadAll(r)
405
        if err != nil {
406
                t.Fatal("read error:", err)
407
        }
408
 
409
        success <- true
410
}
411
 
412
// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
413
func TestServeHTTP10Close(t *testing.T) {
414
        testTcpConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
415
                ServeFile(w, r, "testdata/file")
416
        }))
417
}
418
 
419
// TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
420
// even for HTTP/1.1 requests.
421
func TestHandlersCanSetConnectionClose11(t *testing.T) {
422
        testTcpConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
423
                w.Header().Set("Connection", "close")
424
        }))
425
}
426
 
427
func TestHandlersCanSetConnectionClose10(t *testing.T) {
428
        testTcpConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
429
                w.Header().Set("Connection", "close")
430
        }))
431
}
432
 
433
func TestSetsRemoteAddr(t *testing.T) {
434
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
435
                fmt.Fprintf(w, "%s", r.RemoteAddr)
436
        }))
437
        defer ts.Close()
438
 
439
        res, err := Get(ts.URL)
440
        if err != nil {
441
                t.Fatalf("Get error: %v", err)
442
        }
443
        body, err := ioutil.ReadAll(res.Body)
444
        if err != nil {
445
                t.Fatalf("ReadAll error: %v", err)
446
        }
447
        ip := string(body)
448
        if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
449
                t.Fatalf("Expected local addr; got %q", ip)
450
        }
451
}
452
 
453
func TestChunkedResponseHeaders(t *testing.T) {
454
        log.SetOutput(ioutil.Discard) // is noisy otherwise
455
        defer log.SetOutput(os.Stderr)
456
 
457
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
458
                w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
459
                fmt.Fprintf(w, "I am a chunked response.")
460
        }))
461
        defer ts.Close()
462
 
463
        res, err := Get(ts.URL)
464
        if err != nil {
465
                t.Fatalf("Get error: %v", err)
466
        }
467
        if g, e := res.ContentLength, int64(-1); g != e {
468
                t.Errorf("expected ContentLength of %d; got %d", e, g)
469
        }
470
        if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
471
                t.Errorf("expected TransferEncoding of %v; got %v", e, g)
472
        }
473
        if _, haveCL := res.Header["Content-Length"]; haveCL {
474
                t.Errorf("Unexpected Content-Length")
475
        }
476
}
477
 
478
// Test304Responses verifies that 304s don't declare that they're
479
// chunking in their response headers and aren't allowed to produce
480
// output.
481
func Test304Responses(t *testing.T) {
482
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
483
                w.WriteHeader(StatusNotModified)
484
                _, err := w.Write([]byte("illegal body"))
485
                if err != ErrBodyNotAllowed {
486
                        t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
487
                }
488
        }))
489
        defer ts.Close()
490
        res, err := Get(ts.URL)
491
        if err != nil {
492
                t.Error(err)
493
        }
494
        if len(res.TransferEncoding) > 0 {
495
                t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
496
        }
497
        body, err := ioutil.ReadAll(res.Body)
498
        if err != nil {
499
                t.Error(err)
500
        }
501
        if len(body) > 0 {
502
                t.Errorf("got unexpected body %q", string(body))
503
        }
504
}
505
 
506
// TestHeadResponses verifies that responses to HEAD requests don't
507
// declare that they're chunking in their response headers, aren't
508
// allowed to produce output, and don't set a Content-Type since
509
// the real type of the body data cannot be inferred.
510
func TestHeadResponses(t *testing.T) {
511
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
512
                _, err := w.Write([]byte("Ignored body"))
513
                if err != ErrBodyNotAllowed {
514
                        t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
515
                }
516
 
517
                // Also exercise the ReaderFrom path
518
                _, err = io.Copy(w, strings.NewReader("Ignored body"))
519
                if err != ErrBodyNotAllowed {
520
                        t.Errorf("on Copy, expected ErrBodyNotAllowed, got %v", err)
521
                }
522
        }))
523
        defer ts.Close()
524
        res, err := Head(ts.URL)
525
        if err != nil {
526
                t.Error(err)
527
        }
528
        if len(res.TransferEncoding) > 0 {
529
                t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
530
        }
531
        ct := res.Header.Get("Content-Type")
532
        if ct != "" {
533
                t.Errorf("expected no Content-Type; got %s", ct)
534
        }
535
        body, err := ioutil.ReadAll(res.Body)
536
        if err != nil {
537
                t.Error(err)
538
        }
539
        if len(body) > 0 {
540
                t.Errorf("got unexpected body %q", string(body))
541
        }
542
}
543
 
544
func TestTLSHandshakeTimeout(t *testing.T) {
545
        ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
546
        ts.Config.ReadTimeout = 250 * time.Millisecond
547
        ts.StartTLS()
548
        defer ts.Close()
549
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
550
        if err != nil {
551
                t.Fatalf("Dial: %v", err)
552
        }
553
        defer conn.Close()
554
        goTimeout(t, 10*time.Second, func() {
555
                var buf [1]byte
556
                n, err := conn.Read(buf[:])
557
                if err == nil || n != 0 {
558
                        t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
559
                }
560
        })
561
}
562
 
563
func TestTLSServer(t *testing.T) {
564
        ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
565
                if r.TLS != nil {
566
                        w.Header().Set("X-TLS-Set", "true")
567
                        if r.TLS.HandshakeComplete {
568
                                w.Header().Set("X-TLS-HandshakeComplete", "true")
569
                        }
570
                }
571
        }))
572
        defer ts.Close()
573
 
574
        // Connect an idle TCP connection to this server before we run
575
        // our real tests.  This idle connection used to block forever
576
        // in the TLS handshake, preventing future connections from
577
        // being accepted. It may prevent future accidental blocking
578
        // in newConn.
579
        idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
580
        if err != nil {
581
                t.Fatalf("Dial: %v", err)
582
        }
583
        defer idleConn.Close()
584
        goTimeout(t, 10*time.Second, func() {
585
                if !strings.HasPrefix(ts.URL, "https://") {
586
                        t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
587
                        return
588
                }
589
                noVerifyTransport := &Transport{
590
                        TLSClientConfig: &tls.Config{
591
                                InsecureSkipVerify: true,
592
                        },
593
                }
594
                client := &Client{Transport: noVerifyTransport}
595
                res, err := client.Get(ts.URL)
596
                if err != nil {
597
                        t.Error(err)
598
                        return
599
                }
600
                if res == nil {
601
                        t.Errorf("got nil Response")
602
                        return
603
                }
604
                defer res.Body.Close()
605
                if res.Header.Get("X-TLS-Set") != "true" {
606
                        t.Errorf("expected X-TLS-Set response header")
607
                        return
608
                }
609
                if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
610
                        t.Errorf("expected X-TLS-HandshakeComplete header")
611
                }
612
        })
613
}
614
 
615
type serverExpectTest struct {
616
        contentLength    int    // of request body
617
        expectation      string // e.g. "100-continue"
618
        readBody         bool   // whether handler should read the body (if false, sends StatusUnauthorized)
619
        expectedResponse string // expected substring in first line of http response
620
}
621
 
622
var serverExpectTests = []serverExpectTest{
623
        // Normal 100-continues, case-insensitive.
624
        {100, "100-continue", true, "100 Continue"},
625
        {100, "100-cOntInUE", true, "100 Continue"},
626
 
627
        // No 100-continue.
628
        {100, "", true, "200 OK"},
629
 
630
        // 100-continue but requesting client to deny us,
631
        // so it never reads the body.
632
        {100, "100-continue", false, "401 Unauthorized"},
633
        // Likewise without 100-continue:
634
        {100, "", false, "401 Unauthorized"},
635
 
636
        // Non-standard expectations are failures
637
        {0, "a-pony", false, "417 Expectation Failed"},
638
 
639
        // Expect-100 requested but no body
640
        {0, "100-continue", true, "400 Bad Request"},
641
}
642
 
643
// Tests that the server responds to the "Expect" request header
644
// correctly.
645
func TestServerExpect(t *testing.T) {
646
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
647
                // Note using r.FormValue("readbody") because for POST
648
                // requests that would read from r.Body, which we only
649
                // conditionally want to do.
650
                if strings.Contains(r.URL.RawQuery, "readbody=true") {
651
                        ioutil.ReadAll(r.Body)
652
                        w.Write([]byte("Hi"))
653
                } else {
654
                        w.WriteHeader(StatusUnauthorized)
655
                }
656
        }))
657
        defer ts.Close()
658
 
659
        runTest := func(test serverExpectTest) {
660
                conn, err := net.Dial("tcp", ts.Listener.Addr().String())
661
                if err != nil {
662
                        t.Fatalf("Dial: %v", err)
663
                }
664
                defer conn.Close()
665
                sendf := func(format string, args ...interface{}) {
666
                        _, err := fmt.Fprintf(conn, format, args...)
667
                        if err != nil {
668
                                t.Fatalf("On test %#v, error writing %q: %v", test, format, err)
669
                        }
670
                }
671
                go func() {
672
                        sendf("POST /?readbody=%v HTTP/1.1\r\n"+
673
                                "Connection: close\r\n"+
674
                                "Content-Length: %d\r\n"+
675
                                "Expect: %s\r\nHost: foo\r\n\r\n",
676
                                test.readBody, test.contentLength, test.expectation)
677
                        if test.contentLength > 0 && strings.ToLower(test.expectation) != "100-continue" {
678
                                body := strings.Repeat("A", test.contentLength)
679
                                sendf(body)
680
                        }
681
                }()
682
                bufr := bufio.NewReader(conn)
683
                line, err := bufr.ReadString('\n')
684
                if err != nil {
685
                        t.Fatalf("ReadString: %v", err)
686
                }
687
                if !strings.Contains(line, test.expectedResponse) {
688
                        t.Errorf("for test %#v got first line=%q", test, line)
689
                }
690
        }
691
 
692
        for _, test := range serverExpectTests {
693
                runTest(test)
694
        }
695
}
696
 
697
// Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
698
// should consume client request bodies that a handler didn't read.
699
func TestServerUnreadRequestBodyLittle(t *testing.T) {
700
        conn := new(testConn)
701
        body := strings.Repeat("x", 100<<10)
702
        conn.readBuf.Write([]byte(fmt.Sprintf(
703
                "POST / HTTP/1.1\r\n"+
704
                        "Host: test\r\n"+
705
                        "Content-Length: %d\r\n"+
706
                        "\r\n", len(body))))
707
        conn.readBuf.Write([]byte(body))
708
 
709
        done := make(chan bool)
710
 
711
        ls := &oneConnListener{conn}
712
        go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
713
                defer close(done)
714
                if conn.readBuf.Len() < len(body)/2 {
715
                        t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
716
                }
717
                rw.WriteHeader(200)
718
                if g, e := conn.readBuf.Len(), 0; g != e {
719
                        t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
720
                }
721
                if c := rw.Header().Get("Connection"); c != "" {
722
                        t.Errorf(`Connection header = %q; want ""`, c)
723
                }
724
        }))
725
        <-done
726
}
727
 
728
// Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
729
// should ignore client request bodies that a handler didn't read
730
// and close the connection.
731
func TestServerUnreadRequestBodyLarge(t *testing.T) {
732
        conn := new(testConn)
733
        body := strings.Repeat("x", 1<<20)
734
        conn.readBuf.Write([]byte(fmt.Sprintf(
735
                "POST / HTTP/1.1\r\n"+
736
                        "Host: test\r\n"+
737
                        "Content-Length: %d\r\n"+
738
                        "\r\n", len(body))))
739
        conn.readBuf.Write([]byte(body))
740
 
741
        done := make(chan bool)
742
 
743
        ls := &oneConnListener{conn}
744
        go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
745
                defer close(done)
746
                if conn.readBuf.Len() < len(body)/2 {
747
                        t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
748
                }
749
                rw.WriteHeader(200)
750
                if conn.readBuf.Len() < len(body)/2 {
751
                        t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
752
                }
753
                if c := rw.Header().Get("Connection"); c != "close" {
754
                        t.Errorf(`Connection header = %q; want "close"`, c)
755
                }
756
        }))
757
        <-done
758
}
759
 
760
func TestTimeoutHandler(t *testing.T) {
761
        sendHi := make(chan bool, 1)
762
        writeErrors := make(chan error, 1)
763
        sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
764
                <-sendHi
765
                _, werr := w.Write([]byte("hi"))
766
                writeErrors <- werr
767
        })
768
        timeout := make(chan time.Time, 1) // write to this to force timeouts
769
        ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
770
        defer ts.Close()
771
 
772
        // Succeed without timing out:
773
        sendHi <- true
774
        res, err := Get(ts.URL)
775
        if err != nil {
776
                t.Error(err)
777
        }
778
        if g, e := res.StatusCode, StatusOK; g != e {
779
                t.Errorf("got res.StatusCode %d; expected %d", g, e)
780
        }
781
        body, _ := ioutil.ReadAll(res.Body)
782
        if g, e := string(body), "hi"; g != e {
783
                t.Errorf("got body %q; expected %q", g, e)
784
        }
785
        if g := <-writeErrors; g != nil {
786
                t.Errorf("got unexpected Write error on first request: %v", g)
787
        }
788
 
789
        // Times out:
790
        timeout <- time.Time{}
791
        res, err = Get(ts.URL)
792
        if err != nil {
793
                t.Error(err)
794
        }
795
        if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
796
                t.Errorf("got res.StatusCode %d; expected %d", g, e)
797
        }
798
        body, _ = ioutil.ReadAll(res.Body)
799
        if !strings.Contains(string(body), "Timeout") {
800
                t.Errorf("expected timeout body; got %q", string(body))
801
        }
802
 
803
        // Now make the previously-timed out handler speak again,
804
        // which verifies the panic is handled:
805
        sendHi <- true
806
        if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
807
                t.Errorf("expected Write error of %v; got %v", e, g)
808
        }
809
}
810
 
811
// Verifies we don't path.Clean() on the wrong parts in redirects.
812
func TestRedirectMunging(t *testing.T) {
813
        req, _ := NewRequest("GET", "http://example.com/", nil)
814
 
815
        resp := httptest.NewRecorder()
816
        Redirect(resp, req, "/foo?next=http://bar.com/", 302)
817
        if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
818
                t.Errorf("Location header was %q; want %q", g, e)
819
        }
820
 
821
        resp = httptest.NewRecorder()
822
        Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
823
        if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
824
                t.Errorf("Location header was %q; want %q", g, e)
825
        }
826
}
827
 
828
// TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
829
// when there is no body (either because the method doesn't permit a body, or an
830
// explicit Content-Length of zero is present), then the transport can re-use the
831
// connection immediately. But when it re-uses the connection, it typically closes
832
// the previous request's body, which is not optimal for zero-lengthed bodies,
833
// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
834
func TestZeroLengthPostAndResponse(t *testing.T) {
835
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
836
                all, err := ioutil.ReadAll(r.Body)
837
                if err != nil {
838
                        t.Fatalf("handler ReadAll: %v", err)
839
                }
840
                if len(all) != 0 {
841
                        t.Errorf("handler got %d bytes; expected 0", len(all))
842
                }
843
                rw.Header().Set("Content-Length", "0")
844
        }))
845
        defer ts.Close()
846
 
847
        req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
848
        if err != nil {
849
                t.Fatal(err)
850
        }
851
        req.ContentLength = 0
852
 
853
        var resp [5]*Response
854
        for i := range resp {
855
                resp[i], err = DefaultClient.Do(req)
856
                if err != nil {
857
                        t.Fatalf("client post #%d: %v", i, err)
858
                }
859
        }
860
 
861
        for i := range resp {
862
                all, err := ioutil.ReadAll(resp[i].Body)
863
                if err != nil {
864
                        t.Fatalf("req #%d: client ReadAll: %v", i, err)
865
                }
866
                if len(all) != 0 {
867
                        t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
868
                }
869
        }
870
}
871
 
872
func TestHandlerPanic(t *testing.T) {
873
        testHandlerPanic(t, false)
874
}
875
 
876
func TestHandlerPanicWithHijack(t *testing.T) {
877
        testHandlerPanic(t, true)
878
}
879
 
880
func testHandlerPanic(t *testing.T, withHijack bool) {
881
        // Unlike the other tests that set the log output to ioutil.Discard
882
        // to quiet the output, this test uses a pipe.  The pipe serves three
883
        // purposes:
884
        //
885
        //   1) The log.Print from the http server (generated by the caught
886
        //      panic) will go to the pipe instead of stderr, making the
887
        //      output quiet.
888
        //
889
        //   2) We read from the pipe to verify that the handler
890
        //      actually caught the panic and logged something.
891
        //
892
        //   3) The blocking Read call prevents this TestHandlerPanic
893
        //      function from exiting before the HTTP server handler
894
        //      finishes crashing. If this text function exited too
895
        //      early (and its defer log.SetOutput(os.Stderr) ran),
896
        //      then the crash output could spill into the next test.
897
        pr, pw := io.Pipe()
898
        log.SetOutput(pw)
899
        defer log.SetOutput(os.Stderr)
900
 
901
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
902
                if withHijack {
903
                        rwc, _, err := w.(Hijacker).Hijack()
904
                        if err != nil {
905
                                t.Logf("unexpected error: %v", err)
906
                        }
907
                        defer rwc.Close()
908
                }
909
                panic("intentional death for testing")
910
        }))
911
        defer ts.Close()
912
 
913
        // Do a blocking read on the log output pipe so its logging
914
        // doesn't bleed into the next test.  But wait only 5 seconds
915
        // for it.
916
        done := make(chan bool, 1)
917
        go func() {
918
                buf := make([]byte, 4<<10)
919
                _, err := pr.Read(buf)
920
                pr.Close()
921
                if err != nil {
922
                        t.Fatal(err)
923
                }
924
                done <- true
925
        }()
926
 
927
        _, err := Get(ts.URL)
928
        if err == nil {
929
                t.Logf("expected an error")
930
        }
931
 
932
        select {
933
        case <-done:
934
                return
935
        case <-time.After(5 * time.Second):
936
                t.Fatal("expected server handler to log an error")
937
        }
938
}
939
 
940
func TestNoDate(t *testing.T) {
941
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
942
                w.Header()["Date"] = nil
943
        }))
944
        defer ts.Close()
945
        res, err := Get(ts.URL)
946
        if err != nil {
947
                t.Fatal(err)
948
        }
949
        _, present := res.Header["Date"]
950
        if present {
951
                t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
952
        }
953
}
954
 
955
func TestStripPrefix(t *testing.T) {
956
        h := HandlerFunc(func(w ResponseWriter, r *Request) {
957
                w.Header().Set("X-Path", r.URL.Path)
958
        })
959
        ts := httptest.NewServer(StripPrefix("/foo", h))
960
        defer ts.Close()
961
 
962
        res, err := Get(ts.URL + "/foo/bar")
963
        if err != nil {
964
                t.Fatal(err)
965
        }
966
        if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
967
                t.Errorf("test 1: got %s, want %s", g, e)
968
        }
969
 
970
        res, err = Get(ts.URL + "/bar")
971
        if err != nil {
972
                t.Fatal(err)
973
        }
974
        if g, e := res.StatusCode, 404; g != e {
975
                t.Errorf("test 2: got status %v, want %v", g, e)
976
        }
977
}
978
 
979
func TestRequestLimit(t *testing.T) {
980
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
981
                t.Fatalf("didn't expect to get request in Handler")
982
        }))
983
        defer ts.Close()
984
        req, _ := NewRequest("GET", ts.URL, nil)
985
        var bytesPerHeader = len("header12345: val12345\r\n")
986
        for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
987
                req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
988
        }
989
        res, err := DefaultClient.Do(req)
990
        if err != nil {
991
                // Some HTTP clients may fail on this undefined behavior (server replying and
992
                // closing the connection while the request is still being written), but
993
                // we do support it (at least currently), so we expect a response below.
994
                t.Fatalf("Do: %v", err)
995
        }
996
        if res.StatusCode != 413 {
997
                t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
998
        }
999
}
1000
 
1001
type neverEnding byte
1002
 
1003
func (b neverEnding) Read(p []byte) (n int, err error) {
1004
        for i := range p {
1005
                p[i] = byte(b)
1006
        }
1007
        return len(p), nil
1008
}
1009
 
1010
type countReader struct {
1011
        r io.Reader
1012
        n *int64
1013
}
1014
 
1015
func (cr countReader) Read(p []byte) (n int, err error) {
1016
        n, err = cr.r.Read(p)
1017
        *cr.n += int64(n)
1018
        return
1019
}
1020
 
1021
func TestRequestBodyLimit(t *testing.T) {
1022
        const limit = 1 << 20
1023
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1024
                r.Body = MaxBytesReader(w, r.Body, limit)
1025
                n, err := io.Copy(ioutil.Discard, r.Body)
1026
                if err == nil {
1027
                        t.Errorf("expected error from io.Copy")
1028
                }
1029
                if n != limit {
1030
                        t.Errorf("io.Copy = %d, want %d", n, limit)
1031
                }
1032
        }))
1033
        defer ts.Close()
1034
 
1035
        nWritten := int64(0)
1036
        req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), &nWritten}, limit*200))
1037
 
1038
        // Send the POST, but don't care it succeeds or not.  The
1039
        // remote side is going to reply and then close the TCP
1040
        // connection, and HTTP doesn't really define if that's
1041
        // allowed or not.  Some HTTP clients will get the response
1042
        // and some (like ours, currently) will complain that the
1043
        // request write failed, without reading the response.
1044
        //
1045
        // But that's okay, since what we're really testing is that
1046
        // the remote side hung up on us before we wrote too much.
1047
        _, _ = DefaultClient.Do(req)
1048
 
1049
        if nWritten > limit*100 {
1050
                t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
1051
                        limit, nWritten)
1052
        }
1053
}
1054
 
1055
// TestClientWriteShutdown tests that if the client shuts down the write
1056
// side of their TCP connection, the server doesn't send a 400 Bad Request.
1057
func TestClientWriteShutdown(t *testing.T) {
1058
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
1059
        defer ts.Close()
1060
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1061
        if err != nil {
1062
                t.Fatalf("Dial: %v", err)
1063
        }
1064
        err = conn.(*net.TCPConn).CloseWrite()
1065
        if err != nil {
1066
                t.Fatalf("Dial: %v", err)
1067
        }
1068
        donec := make(chan bool)
1069
        go func() {
1070
                defer close(donec)
1071
                bs, err := ioutil.ReadAll(conn)
1072
                if err != nil {
1073
                        t.Fatalf("ReadAll: %v", err)
1074
                }
1075
                got := string(bs)
1076
                if got != "" {
1077
                        t.Errorf("read %q from server; want nothing", got)
1078
                }
1079
        }()
1080
        select {
1081
        case <-donec:
1082
        case <-time.After(10 * time.Second):
1083
                t.Fatalf("timeout")
1084
        }
1085
}
1086
 
1087
// Tests that chunked server responses that write 1 byte at a time are
1088
// buffered before chunk headers are added, not after chunk headers.
1089
func TestServerBufferedChunking(t *testing.T) {
1090
        if true {
1091
                t.Logf("Skipping known broken test; see Issue 2357")
1092
                return
1093
        }
1094
        conn := new(testConn)
1095
        conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
1096
        done := make(chan bool)
1097
        ls := &oneConnListener{conn}
1098
        go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1099
                defer close(done)
1100
                rw.Header().Set("Content-Type", "text/plain") // prevent sniffing, which buffers
1101
                rw.Write([]byte{'x'})
1102
                rw.Write([]byte{'y'})
1103
                rw.Write([]byte{'z'})
1104
        }))
1105
        <-done
1106
        if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
1107
                t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
1108
                        conn.writeBuf.Bytes())
1109
        }
1110
}
1111
 
1112
// goTimeout runs f, failing t if f takes more than ns to complete.
1113
func goTimeout(t *testing.T, d time.Duration, f func()) {
1114
        ch := make(chan bool, 2)
1115
        timer := time.AfterFunc(d, func() {
1116
                t.Errorf("Timeout expired after %v", d)
1117
                ch <- true
1118
        })
1119
        defer timer.Stop()
1120
        go func() {
1121
                defer func() { ch <- true }()
1122
                f()
1123
        }()
1124
        <-ch
1125
}
1126
 
1127
type errorListener struct {
1128
        errs []error
1129
}
1130
 
1131
func (l *errorListener) Accept() (c net.Conn, err error) {
1132
        if len(l.errs) == 0 {
1133
                return nil, io.EOF
1134
        }
1135
        err = l.errs[0]
1136
        l.errs = l.errs[1:]
1137
        return
1138
}
1139
 
1140
func (l *errorListener) Close() error {
1141
        return nil
1142
}
1143
 
1144
func (l *errorListener) Addr() net.Addr {
1145
        return dummyAddr("test-address")
1146
}
1147
 
1148
func TestAcceptMaxFds(t *testing.T) {
1149
        log.SetOutput(ioutil.Discard) // is noisy otherwise
1150
        defer log.SetOutput(os.Stderr)
1151
 
1152
        ln := &errorListener{[]error{
1153
                &net.OpError{
1154
                        Op:  "accept",
1155
                        Err: syscall.EMFILE,
1156
                }}}
1157
        err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
1158
        if err != io.EOF {
1159
                t.Errorf("got error %v, want EOF", err)
1160
        }
1161
}
1162
 
1163
func BenchmarkClientServer(b *testing.B) {
1164
        b.StopTimer()
1165
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1166
                fmt.Fprintf(rw, "Hello world.\n")
1167
        }))
1168
        defer ts.Close()
1169
        b.StartTimer()
1170
 
1171
        for i := 0; i < b.N; i++ {
1172
                res, err := Get(ts.URL)
1173
                if err != nil {
1174
                        b.Fatal("Get:", err)
1175
                }
1176
                all, err := ioutil.ReadAll(res.Body)
1177
                if err != nil {
1178
                        b.Fatal("ReadAll:", err)
1179
                }
1180
                body := string(all)
1181
                if body != "Hello world.\n" {
1182
                        b.Fatal("Got body:", body)
1183
                }
1184
        }
1185
 
1186
        b.StopTimer()
1187
}

powered by: WebSVN 2.1.0

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