1 // 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.
5 // End-to-end serving tests
36 type oneConnListener struct {
40 func (l *oneConnListener) Accept() (c net.Conn, err error) {
51 func (l *oneConnListener) Close() error {
55 func (l *oneConnListener) Addr() net.Addr {
56 return dummyAddr("test-address")
59 func (a dummyAddr) Network() string {
63 func (a dummyAddr) String() string {
67 type testConn struct {
70 closec chan bool // if non-nil, send value to it on close
73 func (c *testConn) Read(b []byte) (int, error) {
74 return c.readBuf.Read(b)
77 func (c *testConn) Write(b []byte) (int, error) {
78 return c.writeBuf.Write(b)
81 func (c *testConn) Close() error {
83 case c.closec <- true:
89 func (c *testConn) LocalAddr() net.Addr {
90 return dummyAddr("local-addr")
93 func (c *testConn) RemoteAddr() net.Addr {
94 return dummyAddr("remote-addr")
97 func (c *testConn) SetDeadline(t time.Time) error {
101 func (c *testConn) SetReadDeadline(t time.Time) error {
105 func (c *testConn) SetWriteDeadline(t time.Time) error {
109 func TestConsumingBodyOnNextConn(t *testing.T) {
110 conn := new(testConn)
111 for i := 0; i < 2; i++ {
112 conn.readBuf.Write([]byte(
113 "POST / HTTP/1.1\r\n" +
115 "Content-Length: 11\r\n" +
121 ch := make(chan *Request)
122 servech := make(chan error)
123 listener := &oneConnListener{conn}
124 handler := func(res ResponseWriter, req *Request) {
130 servech <- Serve(listener, HandlerFunc(handler))
136 t.Fatal("Got nil first request.")
138 if req.Method != "POST" {
139 t.Errorf("For request #1's method, got %q; expected %q",
145 t.Fatal("Got nil first request.")
147 if req.Method != "POST" {
148 t.Errorf("For request #2's method, got %q; expected %q",
152 if serveerr := <-servech; serveerr != io.EOF {
153 t.Errorf("Serve returned %q; expected EOF", serveerr)
157 type stringHandler string
159 func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
160 w.Header().Set("Result", string(s))
163 var handlers = []struct {
168 {"/someDir/", "someDir"},
169 {"someHost.com/someDir/", "someHost.com/someDir"},
172 var vtests = []struct {
176 {"http://localhost/someDir/apage", "someDir"},
177 {"http://localhost/otherDir/apage", "Default"},
178 {"http://someHost.com/someDir/apage", "someHost.com/someDir"},
179 {"http://otherHost.com/someDir/apage", "someDir"},
180 {"http://otherHost.com/aDir/apage", "Default"},
181 // redirections for trees
182 {"http://localhost/someDir", "/someDir/"},
183 {"http://someHost.com/someDir", "/someDir/"},
186 func TestHostHandlers(t *testing.T) {
188 for _, h := range handlers {
189 mux.Handle(h.pattern, stringHandler(h.msg))
191 ts := httptest.NewServer(mux)
194 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
199 cc := httputil.NewClientConn(conn, nil)
200 for _, vt := range vtests {
203 if req.URL, err = url.Parse(vt.url); err != nil {
204 t.Errorf("cannot parse url: %v", err)
207 if err := cc.Write(&req); err != nil {
208 t.Errorf("writing request: %v", err)
211 r, err := cc.Read(&req)
213 t.Errorf("reading response: %v", err)
216 switch r.StatusCode {
218 s := r.Header.Get("Result")
219 if s != vt.expected {
220 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
222 case StatusMovedPermanently:
223 s := r.Header.Get("Location")
224 if s != vt.expected {
225 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
228 t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode)
233 // Tests for http://code.google.com/p/go/issues/detail?id=900
234 func TestMuxRedirectLeadingSlashes(t *testing.T) {
235 paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
236 for _, path := range paths {
237 req, err := ReadRequest(bufio.NewReader(bytes.NewBufferString("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
242 resp := httptest.NewRecorder()
244 mux.ServeHTTP(resp, req)
246 if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected {
247 t.Errorf("Expected Location header set to %q; got %q", expected, loc)
251 if code, expected := resp.Code, StatusMovedPermanently; code != expected {
252 t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
258 func TestServerTimeouts(t *testing.T) {
259 // TODO(bradfitz): convert this to use httptest.Server
260 l, err := net.Listen("tcp", "127.0.0.1:0")
262 t.Fatalf("listen error: %v", err)
264 addr, _ := l.Addr().(*net.TCPAddr)
267 handler := HandlerFunc(func(res ResponseWriter, req *Request) {
269 fmt.Fprintf(res, "req=%d", reqNum)
272 server := &Server{Handler: handler, ReadTimeout: 250 * time.Millisecond, WriteTimeout: 250 * time.Millisecond}
275 url := fmt.Sprintf("http://%s/", addr)
277 // Hit the HTTP server successfully.
278 tr := &Transport{DisableKeepAlives: true} // they interfere with this test
279 c := &Client{Transport: tr}
282 t.Fatalf("http Get #1: %v", err)
284 got, _ := ioutil.ReadAll(r.Body)
286 if string(got) != expected {
287 t.Errorf("Unexpected response for request #1; got %q; expected %q",
288 string(got), expected)
291 // Slow client that should timeout.
293 conn, err := net.Dial("tcp", addr.String())
295 t.Fatalf("Dial: %v", err)
297 buf := make([]byte, 1)
298 n, err := conn.Read(buf)
299 latency := time.Now().Sub(t1)
300 if n != 0 || err != io.EOF {
301 t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
303 if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
304 t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
307 // Hit the HTTP server successfully again, verifying that the
308 // previous slow connection didn't run our handler. (that we
309 // get "req=2", not "req=3")
312 t.Fatalf("http Get #2: %v", err)
314 got, _ = ioutil.ReadAll(r.Body)
316 if string(got) != expected {
317 t.Errorf("Get #2 got %q, want %q", string(got), expected)
323 // TestIdentityResponse verifies that a handler can unset
324 func TestIdentityResponse(t *testing.T) {
325 handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
326 rw.Header().Set("Content-Length", "3")
327 rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
329 case req.FormValue("overwrite") == "1":
330 _, err := rw.Write([]byte("foo TOO LONG"))
331 if err != ErrContentLength {
332 t.Errorf("expected ErrContentLength; got %v", err)
334 case req.FormValue("underwrite") == "1":
335 rw.Header().Set("Content-Length", "500")
336 rw.Write([]byte("too short"))
338 rw.Write([]byte("foo"))
342 ts := httptest.NewServer(handler)
345 // Note: this relies on the assumption (which is true) that
346 // Get sends HTTP/1.1 or greater requests. Otherwise the
347 // server wouldn't have the choice to send back chunked
349 for _, te := range []string{"", "identity"} {
350 url := ts.URL + "/?te=" + te
353 t.Fatalf("error with Get of %s: %v", url, err)
355 if cl, expected := res.ContentLength, int64(3); cl != expected {
356 t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
358 if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
359 t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
361 if tl, expected := len(res.TransferEncoding), 0; tl != expected {
362 t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
363 url, expected, tl, res.TransferEncoding)
368 // Verify that ErrContentLength is returned
369 url := ts.URL + "/?overwrite=1"
372 t.Fatalf("error with Get of %s: %v", url, err)
374 // Verify that the connection is closed when the declared Content-Length
375 // is larger than what the handler wrote.
376 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
378 t.Fatalf("error dialing: %v", err)
380 _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
382 t.Fatalf("error writing: %v", err)
385 // The ReadAll will hang for a failing test, so use a Timer to
387 goTimeout(t, 2*time.Second, func() {
388 got, _ := ioutil.ReadAll(conn)
389 expectedSuffix := "\r\n\r\ntoo short"
390 if !strings.HasSuffix(string(got), expectedSuffix) {
391 t.Errorf("Expected output to end with %q; got response body %q",
392 expectedSuffix, string(got))
397 func testTCPConnectionCloses(t *testing.T, req string, h Handler) {
398 s := httptest.NewServer(h)
401 conn, err := net.Dial("tcp", s.Listener.Addr().String())
403 t.Fatal("dial error:", err)
407 _, err = fmt.Fprint(conn, req)
409 t.Fatal("print error:", err)
412 r := bufio.NewReader(conn)
413 res, err := ReadResponse(r, &Request{Method: "GET"})
415 t.Fatal("ReadResponse error:", err)
418 didReadAll := make(chan bool, 1)
421 case <-time.After(5 * time.Second):
422 t.Error("body not closed after 5s")
428 _, err = ioutil.ReadAll(r)
430 t.Fatal("read error:", err)
435 t.Errorf("Response.Close = false; want true")
439 // TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
440 func TestServeHTTP10Close(t *testing.T) {
441 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
442 ServeFile(w, r, "testdata/file")
446 // TestClientCanClose verifies that clients can also force a connection to close.
447 func TestClientCanClose(t *testing.T) {
448 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
453 // TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
454 // even for HTTP/1.1 requests.
455 func TestHandlersCanSetConnectionClose11(t *testing.T) {
456 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
457 w.Header().Set("Connection", "close")
461 func TestHandlersCanSetConnectionClose10(t *testing.T) {
462 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
463 w.Header().Set("Connection", "close")
467 func TestSetsRemoteAddr(t *testing.T) {
468 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
469 fmt.Fprintf(w, "%s", r.RemoteAddr)
473 res, err := Get(ts.URL)
475 t.Fatalf("Get error: %v", err)
477 body, err := ioutil.ReadAll(res.Body)
479 t.Fatalf("ReadAll error: %v", err)
482 if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
483 t.Fatalf("Expected local addr; got %q", ip)
487 func TestChunkedResponseHeaders(t *testing.T) {
488 log.SetOutput(ioutil.Discard) // is noisy otherwise
489 defer log.SetOutput(os.Stderr)
491 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
492 w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
494 fmt.Fprintf(w, "I am a chunked response.")
498 res, err := Get(ts.URL)
500 t.Fatalf("Get error: %v", err)
502 if g, e := res.ContentLength, int64(-1); g != e {
503 t.Errorf("expected ContentLength of %d; got %d", e, g)
505 if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
506 t.Errorf("expected TransferEncoding of %v; got %v", e, g)
508 if _, haveCL := res.Header["Content-Length"]; haveCL {
509 t.Errorf("Unexpected Content-Length")
513 // Test304Responses verifies that 304s don't declare that they're
514 // chunking in their response headers and aren't allowed to produce
516 func Test304Responses(t *testing.T) {
517 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
518 w.WriteHeader(StatusNotModified)
519 _, err := w.Write([]byte("illegal body"))
520 if err != ErrBodyNotAllowed {
521 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
525 res, err := Get(ts.URL)
529 if len(res.TransferEncoding) > 0 {
530 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
532 body, err := ioutil.ReadAll(res.Body)
537 t.Errorf("got unexpected body %q", string(body))
541 // TestHeadResponses verifies that responses to HEAD requests don't
542 // declare that they're chunking in their response headers, aren't
543 // allowed to produce output, and don't set a Content-Type since
544 // the real type of the body data cannot be inferred.
545 func TestHeadResponses(t *testing.T) {
546 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
547 _, err := w.Write([]byte("Ignored body"))
548 if err != ErrBodyNotAllowed {
549 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
552 // Also exercise the ReaderFrom path
553 _, err = io.Copy(w, strings.NewReader("Ignored body"))
554 if err != ErrBodyNotAllowed {
555 t.Errorf("on Copy, expected ErrBodyNotAllowed, got %v", err)
559 res, err := Head(ts.URL)
563 if len(res.TransferEncoding) > 0 {
564 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
566 ct := res.Header.Get("Content-Type")
568 t.Errorf("expected no Content-Type; got %s", ct)
570 body, err := ioutil.ReadAll(res.Body)
575 t.Errorf("got unexpected body %q", string(body))
579 func TestTLSHandshakeTimeout(t *testing.T) {
580 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
581 ts.Config.ReadTimeout = 250 * time.Millisecond
584 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
586 t.Fatalf("Dial: %v", err)
589 goTimeout(t, 10*time.Second, func() {
591 n, err := conn.Read(buf[:])
592 if err == nil || n != 0 {
593 t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
598 func TestTLSServer(t *testing.T) {
599 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
601 w.Header().Set("X-TLS-Set", "true")
602 if r.TLS.HandshakeComplete {
603 w.Header().Set("X-TLS-HandshakeComplete", "true")
609 // Connect an idle TCP connection to this server before we run
610 // our real tests. This idle connection used to block forever
611 // in the TLS handshake, preventing future connections from
612 // being accepted. It may prevent future accidental blocking
614 idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
616 t.Fatalf("Dial: %v", err)
618 defer idleConn.Close()
619 goTimeout(t, 10*time.Second, func() {
620 if !strings.HasPrefix(ts.URL, "https://") {
621 t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
624 noVerifyTransport := &Transport{
625 TLSClientConfig: &tls.Config{
626 InsecureSkipVerify: true,
629 client := &Client{Transport: noVerifyTransport}
630 res, err := client.Get(ts.URL)
636 t.Errorf("got nil Response")
639 defer res.Body.Close()
640 if res.Header.Get("X-TLS-Set") != "true" {
641 t.Errorf("expected X-TLS-Set response header")
644 if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
645 t.Errorf("expected X-TLS-HandshakeComplete header")
650 type serverExpectTest struct {
651 contentLength int // of request body
652 expectation string // e.g. "100-continue"
653 readBody bool // whether handler should read the body (if false, sends StatusUnauthorized)
654 expectedResponse string // expected substring in first line of http response
657 var serverExpectTests = []serverExpectTest{
658 // Normal 100-continues, case-insensitive.
659 {100, "100-continue", true, "100 Continue"},
660 {100, "100-cOntInUE", true, "100 Continue"},
663 {100, "", true, "200 OK"},
665 // 100-continue but requesting client to deny us,
666 // so it never reads the body.
667 {100, "100-continue", false, "401 Unauthorized"},
668 // Likewise without 100-continue:
669 {100, "", false, "401 Unauthorized"},
671 // Non-standard expectations are failures
672 {0, "a-pony", false, "417 Expectation Failed"},
674 // Expect-100 requested but no body
675 {0, "100-continue", true, "400 Bad Request"},
678 // Tests that the server responds to the "Expect" request header
680 func TestServerExpect(t *testing.T) {
681 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
682 // Note using r.FormValue("readbody") because for POST
683 // requests that would read from r.Body, which we only
684 // conditionally want to do.
685 if strings.Contains(r.URL.RawQuery, "readbody=true") {
686 ioutil.ReadAll(r.Body)
687 w.Write([]byte("Hi"))
689 w.WriteHeader(StatusUnauthorized)
694 runTest := func(test serverExpectTest) {
695 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
697 t.Fatalf("Dial: %v", err)
701 // Only send the body immediately if we're acting like an HTTP client
702 // that doesn't send 100-continue expectations.
703 writeBody := test.contentLength > 0 && strings.ToLower(test.expectation) != "100-continue"
706 _, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+
707 "Connection: close\r\n"+
708 "Content-Length: %d\r\n"+
709 "Expect: %s\r\nHost: foo\r\n\r\n",
710 test.readBody, test.contentLength, test.expectation)
712 t.Errorf("On test %#v, error writing request headers: %v", test, err)
716 body := strings.Repeat("A", test.contentLength)
717 _, err = fmt.Fprint(conn, body)
720 // Server likely already hung up on us.
721 // See larger comment below.
722 t.Logf("On test %#v, acceptable error writing request body: %v", test, err)
725 t.Errorf("On test %#v, error writing request body: %v", test, err)
729 bufr := bufio.NewReader(conn)
730 line, err := bufr.ReadString('\n')
732 if writeBody && !test.readBody {
733 // This is an acceptable failure due to a possible TCP race:
734 // We were still writing data and the server hung up on us. A TCP
735 // implementation may send a RST if our request body data was known
736 // to be lost, which may trigger our reads to fail.
737 // See RFC 1122 page 88.
738 t.Logf("On test %#v, acceptable error from ReadString: %v", test, err)
741 t.Fatalf("On test %#v, ReadString: %v", test, err)
743 if !strings.Contains(line, test.expectedResponse) {
744 t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse)
748 for _, test := range serverExpectTests {
753 // Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
754 // should consume client request bodies that a handler didn't read.
755 func TestServerUnreadRequestBodyLittle(t *testing.T) {
756 conn := new(testConn)
757 body := strings.Repeat("x", 100<<10)
758 conn.readBuf.Write([]byte(fmt.Sprintf(
759 "POST / HTTP/1.1\r\n"+
761 "Content-Length: %d\r\n"+
763 conn.readBuf.Write([]byte(body))
765 done := make(chan bool)
767 ls := &oneConnListener{conn}
768 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
770 if conn.readBuf.Len() < len(body)/2 {
771 t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
775 if g, e := conn.readBuf.Len(), 0; g != e {
776 t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
778 if c := rw.Header().Get("Connection"); c != "" {
779 t.Errorf(`Connection header = %q; want ""`, c)
785 // Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
786 // should ignore client request bodies that a handler didn't read
787 // and close the connection.
788 func TestServerUnreadRequestBodyLarge(t *testing.T) {
789 conn := new(testConn)
790 body := strings.Repeat("x", 1<<20)
791 conn.readBuf.Write([]byte(fmt.Sprintf(
792 "POST / HTTP/1.1\r\n"+
794 "Content-Length: %d\r\n"+
796 conn.readBuf.Write([]byte(body))
797 conn.closec = make(chan bool, 1)
799 ls := &oneConnListener{conn}
800 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
801 if conn.readBuf.Len() < len(body)/2 {
802 t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
806 if conn.readBuf.Len() < len(body)/2 {
807 t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
812 if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") {
813 t.Errorf("Expected a Connection: close header; got response: %s", res)
817 func TestTimeoutHandler(t *testing.T) {
818 sendHi := make(chan bool, 1)
819 writeErrors := make(chan error, 1)
820 sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
822 _, werr := w.Write([]byte("hi"))
825 timeout := make(chan time.Time, 1) // write to this to force timeouts
826 ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
829 // Succeed without timing out:
831 res, err := Get(ts.URL)
835 if g, e := res.StatusCode, StatusOK; g != e {
836 t.Errorf("got res.StatusCode %d; expected %d", g, e)
838 body, _ := ioutil.ReadAll(res.Body)
839 if g, e := string(body), "hi"; g != e {
840 t.Errorf("got body %q; expected %q", g, e)
842 if g := <-writeErrors; g != nil {
843 t.Errorf("got unexpected Write error on first request: %v", g)
847 timeout <- time.Time{}
848 res, err = Get(ts.URL)
852 if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
853 t.Errorf("got res.StatusCode %d; expected %d", g, e)
855 body, _ = ioutil.ReadAll(res.Body)
856 if !strings.Contains(string(body), "<title>Timeout</title>") {
857 t.Errorf("expected timeout body; got %q", string(body))
860 // Now make the previously-timed out handler speak again,
861 // which verifies the panic is handled:
863 if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
864 t.Errorf("expected Write error of %v; got %v", e, g)
868 // Verifies we don't path.Clean() on the wrong parts in redirects.
869 func TestRedirectMunging(t *testing.T) {
870 req, _ := NewRequest("GET", "http://example.com/", nil)
872 resp := httptest.NewRecorder()
873 Redirect(resp, req, "/foo?next=http://bar.com/", 302)
874 if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
875 t.Errorf("Location header was %q; want %q", g, e)
878 resp = httptest.NewRecorder()
879 Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
880 if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
881 t.Errorf("Location header was %q; want %q", g, e)
885 // TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
886 // when there is no body (either because the method doesn't permit a body, or an
887 // explicit Content-Length of zero is present), then the transport can re-use the
888 // connection immediately. But when it re-uses the connection, it typically closes
889 // the previous request's body, which is not optimal for zero-lengthed bodies,
890 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
891 func TestZeroLengthPostAndResponse(t *testing.T) {
892 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
893 all, err := ioutil.ReadAll(r.Body)
895 t.Fatalf("handler ReadAll: %v", err)
898 t.Errorf("handler got %d bytes; expected 0", len(all))
900 rw.Header().Set("Content-Length", "0")
904 req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
908 req.ContentLength = 0
910 var resp [5]*Response
911 for i := range resp {
912 resp[i], err = DefaultClient.Do(req)
914 t.Fatalf("client post #%d: %v", i, err)
918 for i := range resp {
919 all, err := ioutil.ReadAll(resp[i].Body)
921 t.Fatalf("req #%d: client ReadAll: %v", i, err)
924 t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
929 func TestHandlerPanicNil(t *testing.T) {
930 testHandlerPanic(t, false, nil)
933 func TestHandlerPanic(t *testing.T) {
934 testHandlerPanic(t, false, "intentional death for testing")
937 func TestHandlerPanicWithHijack(t *testing.T) {
938 testHandlerPanic(t, true, "intentional death for testing")
941 func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
942 // Unlike the other tests that set the log output to ioutil.Discard
943 // to quiet the output, this test uses a pipe. The pipe serves three
946 // 1) The log.Print from the http server (generated by the caught
947 // panic) will go to the pipe instead of stderr, making the
950 // 2) We read from the pipe to verify that the handler
951 // actually caught the panic and logged something.
953 // 3) The blocking Read call prevents this TestHandlerPanic
954 // function from exiting before the HTTP server handler
955 // finishes crashing. If this text function exited too
956 // early (and its defer log.SetOutput(os.Stderr) ran),
957 // then the crash output could spill into the next test.
960 defer log.SetOutput(os.Stderr)
962 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
964 rwc, _, err := w.(Hijacker).Hijack()
966 t.Logf("unexpected error: %v", err)
974 // Do a blocking read on the log output pipe so its logging
975 // doesn't bleed into the next test. But wait only 5 seconds
977 done := make(chan bool, 1)
979 buf := make([]byte, 4<<10)
980 _, err := pr.Read(buf)
988 _, err := Get(ts.URL)
990 t.Logf("expected an error")
993 if panicValue == nil {
1000 case <-time.After(5 * time.Second):
1001 t.Fatal("expected server handler to log an error")
1005 func TestNoDate(t *testing.T) {
1006 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1007 w.Header()["Date"] = nil
1010 res, err := Get(ts.URL)
1014 _, present := res.Header["Date"]
1016 t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
1020 func TestStripPrefix(t *testing.T) {
1021 h := HandlerFunc(func(w ResponseWriter, r *Request) {
1022 w.Header().Set("X-Path", r.URL.Path)
1024 ts := httptest.NewServer(StripPrefix("/foo", h))
1027 res, err := Get(ts.URL + "/foo/bar")
1031 if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
1032 t.Errorf("test 1: got %s, want %s", g, e)
1035 res, err = Get(ts.URL + "/bar")
1039 if g, e := res.StatusCode, 404; g != e {
1040 t.Errorf("test 2: got status %v, want %v", g, e)
1044 func TestRequestLimit(t *testing.T) {
1045 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1046 t.Fatalf("didn't expect to get request in Handler")
1049 req, _ := NewRequest("GET", ts.URL, nil)
1050 var bytesPerHeader = len("header12345: val12345\r\n")
1051 for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
1052 req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
1054 res, err := DefaultClient.Do(req)
1056 // Some HTTP clients may fail on this undefined behavior (server replying and
1057 // closing the connection while the request is still being written), but
1058 // we do support it (at least currently), so we expect a response below.
1059 t.Fatalf("Do: %v", err)
1061 if res.StatusCode != 413 {
1062 t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
1066 type neverEnding byte
1068 func (b neverEnding) Read(p []byte) (n int, err error) {
1075 type countReader struct {
1080 func (cr countReader) Read(p []byte) (n int, err error) {
1081 n, err = cr.r.Read(p)
1082 atomic.AddInt64(cr.n, int64(n))
1086 func TestRequestBodyLimit(t *testing.T) {
1087 const limit = 1 << 20
1088 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1089 r.Body = MaxBytesReader(w, r.Body, limit)
1090 n, err := io.Copy(ioutil.Discard, r.Body)
1092 t.Errorf("expected error from io.Copy")
1095 t.Errorf("io.Copy = %d, want %d", n, limit)
1100 nWritten := new(int64)
1101 req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200))
1103 // Send the POST, but don't care it succeeds or not. The
1104 // remote side is going to reply and then close the TCP
1105 // connection, and HTTP doesn't really define if that's
1106 // allowed or not. Some HTTP clients will get the response
1107 // and some (like ours, currently) will complain that the
1108 // request write failed, without reading the response.
1110 // But that's okay, since what we're really testing is that
1111 // the remote side hung up on us before we wrote too much.
1112 _, _ = DefaultClient.Do(req)
1114 if atomic.LoadInt64(nWritten) > limit*100 {
1115 t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
1120 // TestClientWriteShutdown tests that if the client shuts down the write
1121 // side of their TCP connection, the server doesn't send a 400 Bad Request.
1122 func TestClientWriteShutdown(t *testing.T) {
1123 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
1125 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1127 t.Fatalf("Dial: %v", err)
1129 err = conn.(*net.TCPConn).CloseWrite()
1131 t.Fatalf("Dial: %v", err)
1133 donec := make(chan bool)
1136 bs, err := ioutil.ReadAll(conn)
1138 t.Fatalf("ReadAll: %v", err)
1142 t.Errorf("read %q from server; want nothing", got)
1147 case <-time.After(10 * time.Second):
1152 // Tests that chunked server responses that write 1 byte at a time are
1153 // buffered before chunk headers are added, not after chunk headers.
1154 func TestServerBufferedChunking(t *testing.T) {
1155 conn := new(testConn)
1156 conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
1157 conn.closec = make(chan bool, 1)
1158 ls := &oneConnListener{conn}
1159 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1160 rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length
1161 rw.Write([]byte{'x'})
1162 rw.Write([]byte{'y'})
1163 rw.Write([]byte{'z'})
1166 if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
1167 t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
1168 conn.writeBuf.Bytes())
1172 // Tests that the server flushes its response headers out when it's
1173 // ignoring the response body and waits a bit before forcefully
1174 // closing the TCP connection, causing the client to get a RST.
1175 // See http://golang.org/issue/3595
1176 func TestServerGracefulClose(t *testing.T) {
1177 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1178 Error(w, "bye", StatusUnauthorized)
1182 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1187 const bodySize = 5 << 20
1188 req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize))
1189 for i := 0; i < bodySize; i++ {
1190 req = append(req, 'x')
1192 writeErr := make(chan error)
1194 _, err := conn.Write(req)
1197 br := bufio.NewReader(conn)
1200 line, err := br.ReadString('\n')
1205 t.Fatalf("ReadLine: %v", err)
1208 if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") {
1209 t.Errorf("Response line = %q; want a 401", line)
1212 // Wait for write to finish. This is a broken pipe on both
1213 // Darwin and Linux, but checking this isn't the point of
1218 func TestCaseSensitiveMethod(t *testing.T) {
1219 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1220 if r.Method != "get" {
1221 t.Errorf(`Got method %q; want "get"`, r.Method)
1225 req, _ := NewRequest("get", ts.URL, nil)
1226 res, err := DefaultClient.Do(req)
1234 // TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
1235 // request (both keep-alive), when a Handler never writes any
1236 // response, the net/http package adds a "Content-Length: 0" response
1238 func TestContentLengthZero(t *testing.T) {
1239 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
1242 for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
1243 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1245 t.Fatalf("error dialing: %v", err)
1247 _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
1249 t.Fatalf("error writing: %v", err)
1251 req, _ := NewRequest("GET", "/", nil)
1252 res, err := ReadResponse(bufio.NewReader(conn), req)
1254 t.Fatalf("error reading response: %v", err)
1256 if te := res.TransferEncoding; len(te) > 0 {
1257 t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
1259 if cl := res.ContentLength; cl != 0 {
1260 t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
1266 func TestCloseNotifier(t *testing.T) {
1267 gotReq := make(chan bool, 1)
1268 sawClose := make(chan bool, 1)
1269 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
1271 cc := rw.(CloseNotifier).CloseNotify()
1275 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1277 t.Fatalf("error dialing: %v", err)
1279 diec := make(chan bool)
1281 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n")
1295 case <-time.After(5 * time.Second):
1302 func TestOptions(t *testing.T) {
1303 uric := make(chan string, 2) // only expect 1, but leave space for 2
1304 mux := NewServeMux()
1305 mux.HandleFunc("/", func(w ResponseWriter, r *Request) {
1306 uric <- r.RequestURI
1308 ts := httptest.NewServer(mux)
1311 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1317 // An OPTIONS * request should succeed.
1318 _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
1322 br := bufio.NewReader(conn)
1323 res, err := ReadResponse(br, &Request{Method: "OPTIONS"})
1327 if res.StatusCode != 200 {
1328 t.Errorf("Got non-200 response to OPTIONS *: %#v", res)
1331 // A GET * request on a ServeMux should fail.
1332 _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
1336 res, err = ReadResponse(br, &Request{Method: "GET"})
1340 if res.StatusCode != 400 {
1341 t.Errorf("Got non-400 response to GET *: %#v", res)
1344 res, err = Get(ts.URL + "/second")
1349 if got := <-uric; got != "/second" {
1350 t.Errorf("Handler saw request for %q; want /second", got)
1354 // goTimeout runs f, failing t if f takes more than ns to complete.
1355 func goTimeout(t *testing.T, d time.Duration, f func()) {
1356 ch := make(chan bool, 2)
1357 timer := time.AfterFunc(d, func() {
1358 t.Errorf("Timeout expired after %v", d)
1363 defer func() { ch <- true }()
1369 type errorListener struct {
1373 func (l *errorListener) Accept() (c net.Conn, err error) {
1374 if len(l.errs) == 0 {
1382 func (l *errorListener) Close() error {
1386 func (l *errorListener) Addr() net.Addr {
1387 return dummyAddr("test-address")
1390 func TestAcceptMaxFds(t *testing.T) {
1391 log.SetOutput(ioutil.Discard) // is noisy otherwise
1392 defer log.SetOutput(os.Stderr)
1394 ln := &errorListener{[]error{
1397 Err: syscall.EMFILE,
1399 err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
1401 t.Errorf("got error %v, want EOF", err)
1405 func BenchmarkClientServer(b *testing.B) {
1407 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1408 fmt.Fprintf(rw, "Hello world.\n")
1413 for i := 0; i < b.N; i++ {
1414 res, err := Get(ts.URL)
1416 b.Fatal("Get:", err)
1418 all, err := ioutil.ReadAll(res.Body)
1420 b.Fatal("ReadAll:", err)
1423 if body != "Hello world.\n" {
1424 b.Fatal("Got body:", body)
1431 func BenchmarkClientServerParallel4(b *testing.B) {
1432 benchmarkClientServerParallel(b, 4)
1435 func BenchmarkClientServerParallel64(b *testing.B) {
1436 benchmarkClientServerParallel(b, 64)
1439 func benchmarkClientServerParallel(b *testing.B, conc int) {
1441 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1442 fmt.Fprintf(rw, "Hello world.\n")
1447 numProcs := runtime.GOMAXPROCS(-1) * conc
1448 var wg sync.WaitGroup
1451 for p := 0; p < numProcs; p++ {
1453 for atomic.AddInt32(&n, -1) >= 0 {
1454 res, err := Get(ts.URL)
1456 b.Logf("Get: %v", err)
1459 all, err := ioutil.ReadAll(res.Body)
1461 b.Logf("ReadAll: %v", err)
1465 if body != "Hello world.\n" {
1466 panic("Got body: " + body)
1475 // A benchmark for profiling the server without the HTTP client code.
1476 // The client code runs in a subprocess.
1480 // $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof
1481 // $ go tool pprof http.test http.prof
1483 func BenchmarkServer(b *testing.B) {
1484 // Child process mode;
1485 if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
1486 n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
1490 for i := 0; i < n; i++ {
1491 res, err := Get(url)
1493 log.Panicf("Get: %v", err)
1495 all, err := ioutil.ReadAll(res.Body)
1497 log.Panicf("ReadAll: %v", err)
1500 if body != "Hello world.\n" {
1501 log.Panicf("Got body: %q", body)
1508 var res = []byte("Hello world.\n")
1510 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1511 rw.Header().Set("Content-Type", "text/html; charset=utf-8")
1517 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
1518 cmd.Env = append([]string{
1519 fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
1520 fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
1522 out, err := cmd.CombinedOutput()
1524 b.Errorf("Test failure: %v, with output: %s", err, out)