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
31 type oneConnListener struct {
35 func (l *oneConnListener) Accept() (c net.Conn, err error) {
46 func (l *oneConnListener) Close() error {
50 func (l *oneConnListener) Addr() net.Addr {
51 return dummyAddr("test-address")
54 func (a dummyAddr) Network() string {
58 func (a dummyAddr) String() string {
62 type testConn struct {
67 func (c *testConn) Read(b []byte) (int, error) {
68 return c.readBuf.Read(b)
71 func (c *testConn) Write(b []byte) (int, error) {
72 return c.writeBuf.Write(b)
75 func (c *testConn) Close() error {
79 func (c *testConn) LocalAddr() net.Addr {
80 return dummyAddr("local-addr")
83 func (c *testConn) RemoteAddr() net.Addr {
84 return dummyAddr("remote-addr")
87 func (c *testConn) SetDeadline(t time.Time) error {
91 func (c *testConn) SetReadDeadline(t time.Time) error {
95 func (c *testConn) SetWriteDeadline(t time.Time) error {
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" +
105 "Content-Length: 11\r\n" +
111 ch := make(chan *Request)
112 servech := make(chan error)
113 listener := &oneConnListener{conn}
114 handler := func(res ResponseWriter, req *Request) {
120 servech <- Serve(listener, HandlerFunc(handler))
126 t.Fatal("Got nil first request.")
128 if req.Method != "POST" {
129 t.Errorf("For request #1's method, got %q; expected %q",
135 t.Fatal("Got nil first request.")
137 if req.Method != "POST" {
138 t.Errorf("For request #2's method, got %q; expected %q",
142 if serveerr := <-servech; serveerr != io.EOF {
143 t.Errorf("Serve returned %q; expected EOF", serveerr)
147 type stringHandler string
149 func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
150 w.Header().Set("Result", string(s))
153 var handlers = []struct {
158 {"/someDir/", "someDir"},
159 {"someHost.com/someDir/", "someHost.com/someDir"},
162 var vtests = []struct {
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"},
173 func TestHostHandlers(t *testing.T) {
174 for _, h := range handlers {
175 Handle(h.pattern, stringHandler(h.msg))
177 ts := httptest.NewServer(nil)
180 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
185 cc := httputil.NewClientConn(conn, nil)
186 for _, vt := range vtests {
189 if req.URL, err = url.Parse(vt.url); err != nil {
190 t.Errorf("cannot parse url: %v", err)
193 if err := cc.Write(&req); err != nil {
194 t.Errorf("writing request: %v", err)
197 r, err := cc.Read(&req)
199 t.Errorf("reading response: %v", err)
202 s := r.Header.Get("Result")
203 if s != vt.expected {
204 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
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")))
218 resp := httptest.NewRecorder()
220 mux.ServeHTTP(resp, req)
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)
227 if code, expected := resp.Code, StatusMovedPermanently; code != expected {
228 t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
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")
238 t.Fatalf("listen error: %v", err)
240 addr, _ := l.Addr().(*net.TCPAddr)
243 handler := HandlerFunc(func(res ResponseWriter, req *Request) {
245 fmt.Fprintf(res, "req=%d", reqNum)
248 server := &Server{Handler: handler, ReadTimeout: 250 * time.Millisecond, WriteTimeout: 250 * time.Millisecond}
251 url := fmt.Sprintf("http://%s/", addr)
253 // Hit the HTTP server successfully.
254 tr := &Transport{DisableKeepAlives: true} // they interfere with this test
255 c := &Client{Transport: tr}
258 t.Fatalf("http Get #1: %v", err)
260 got, _ := ioutil.ReadAll(r.Body)
262 if string(got) != expected {
263 t.Errorf("Unexpected response for request #1; got %q; expected %q",
264 string(got), expected)
267 // Slow client that should timeout.
269 conn, err := net.Dial("tcp", addr.String())
271 t.Fatalf("Dial: %v", err)
273 buf := make([]byte, 1)
274 n, err := conn.Read(buf)
275 latency := time.Now().Sub(t1)
276 if n != 0 || err != io.EOF {
277 t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
279 if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
280 t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
283 // Hit the HTTP server successfully again, verifying that the
284 // previous slow connection didn't run our handler. (that we
285 // get "req=2", not "req=3")
288 t.Fatalf("http Get #2: %v", err)
290 got, _ = ioutil.ReadAll(r.Body)
292 if string(got) != expected {
293 t.Errorf("Get #2 got %q, want %q", string(got), expected)
299 // TestIdentityResponse verifies that a handler can unset
300 func TestIdentityResponse(t *testing.T) {
301 handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
302 rw.Header().Set("Content-Length", "3")
303 rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
305 case req.FormValue("overwrite") == "1":
306 _, err := rw.Write([]byte("foo TOO LONG"))
307 if err != ErrContentLength {
308 t.Errorf("expected ErrContentLength; got %v", err)
310 case req.FormValue("underwrite") == "1":
311 rw.Header().Set("Content-Length", "500")
312 rw.Write([]byte("too short"))
314 rw.Write([]byte("foo"))
318 ts := httptest.NewServer(handler)
321 // Note: this relies on the assumption (which is true) that
322 // Get sends HTTP/1.1 or greater requests. Otherwise the
323 // server wouldn't have the choice to send back chunked
325 for _, te := range []string{"", "identity"} {
326 url := ts.URL + "/?te=" + te
329 t.Fatalf("error with Get of %s: %v", url, err)
331 if cl, expected := res.ContentLength, int64(3); cl != expected {
332 t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
334 if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
335 t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
337 if tl, expected := len(res.TransferEncoding), 0; tl != expected {
338 t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
339 url, expected, tl, res.TransferEncoding)
344 // Verify that ErrContentLength is returned
345 url := ts.URL + "/?overwrite=1"
348 t.Fatalf("error with Get of %s: %v", url, err)
350 // Verify that the connection is closed when the declared Content-Length
351 // is larger than what the handler wrote.
352 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
354 t.Fatalf("error dialing: %v", err)
356 _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
358 t.Fatalf("error writing: %v", err)
361 // The ReadAll will hang for a failing test, so use a Timer to
363 goTimeout(t, 2*time.Second, func() {
364 got, _ := ioutil.ReadAll(conn)
365 expectedSuffix := "\r\n\r\ntoo short"
366 if !strings.HasSuffix(string(got), expectedSuffix) {
367 t.Errorf("Expected output to end with %q; got response body %q",
368 expectedSuffix, string(got))
373 func testTcpConnectionCloses(t *testing.T, req string, h Handler) {
374 s := httptest.NewServer(h)
377 conn, err := net.Dial("tcp", s.Listener.Addr().String())
379 t.Fatal("dial error:", err)
383 _, err = fmt.Fprint(conn, req)
385 t.Fatal("print error:", err)
388 r := bufio.NewReader(conn)
389 res, err := ReadResponse(r, &Request{Method: "GET"})
391 t.Fatal("ReadResponse error:", err)
394 didReadAll := make(chan bool, 1)
397 case <-time.After(5 * time.Second):
398 t.Error("body not closed after 5s")
404 _, err = ioutil.ReadAll(r)
406 t.Fatal("read error:", err)
411 t.Errorf("Response.Close = false; want true")
415 // TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
416 func TestServeHTTP10Close(t *testing.T) {
417 testTcpConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
418 ServeFile(w, r, "testdata/file")
422 // TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
423 // even for HTTP/1.1 requests.
424 func TestHandlersCanSetConnectionClose11(t *testing.T) {
425 testTcpConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
426 w.Header().Set("Connection", "close")
430 func TestHandlersCanSetConnectionClose10(t *testing.T) {
431 testTcpConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
432 w.Header().Set("Connection", "close")
436 func TestSetsRemoteAddr(t *testing.T) {
437 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
438 fmt.Fprintf(w, "%s", r.RemoteAddr)
442 res, err := Get(ts.URL)
444 t.Fatalf("Get error: %v", err)
446 body, err := ioutil.ReadAll(res.Body)
448 t.Fatalf("ReadAll error: %v", err)
451 if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
452 t.Fatalf("Expected local addr; got %q", ip)
456 func TestChunkedResponseHeaders(t *testing.T) {
457 log.SetOutput(ioutil.Discard) // is noisy otherwise
458 defer log.SetOutput(os.Stderr)
460 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
461 w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
462 fmt.Fprintf(w, "I am a chunked response.")
466 res, err := Get(ts.URL)
468 t.Fatalf("Get error: %v", err)
470 if g, e := res.ContentLength, int64(-1); g != e {
471 t.Errorf("expected ContentLength of %d; got %d", e, g)
473 if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
474 t.Errorf("expected TransferEncoding of %v; got %v", e, g)
476 if _, haveCL := res.Header["Content-Length"]; haveCL {
477 t.Errorf("Unexpected Content-Length")
481 // Test304Responses verifies that 304s don't declare that they're
482 // chunking in their response headers and aren't allowed to produce
484 func Test304Responses(t *testing.T) {
485 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
486 w.WriteHeader(StatusNotModified)
487 _, err := w.Write([]byte("illegal body"))
488 if err != ErrBodyNotAllowed {
489 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
493 res, err := Get(ts.URL)
497 if len(res.TransferEncoding) > 0 {
498 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
500 body, err := ioutil.ReadAll(res.Body)
505 t.Errorf("got unexpected body %q", string(body))
509 // TestHeadResponses verifies that responses to HEAD requests don't
510 // declare that they're chunking in their response headers, aren't
511 // allowed to produce output, and don't set a Content-Type since
512 // the real type of the body data cannot be inferred.
513 func TestHeadResponses(t *testing.T) {
514 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
515 _, err := w.Write([]byte("Ignored body"))
516 if err != ErrBodyNotAllowed {
517 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
520 // Also exercise the ReaderFrom path
521 _, err = io.Copy(w, strings.NewReader("Ignored body"))
522 if err != ErrBodyNotAllowed {
523 t.Errorf("on Copy, expected ErrBodyNotAllowed, got %v", err)
527 res, err := Head(ts.URL)
531 if len(res.TransferEncoding) > 0 {
532 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
534 ct := res.Header.Get("Content-Type")
536 t.Errorf("expected no Content-Type; got %s", ct)
538 body, err := ioutil.ReadAll(res.Body)
543 t.Errorf("got unexpected body %q", string(body))
547 func TestTLSHandshakeTimeout(t *testing.T) {
548 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
549 ts.Config.ReadTimeout = 250 * time.Millisecond
552 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
554 t.Fatalf("Dial: %v", err)
557 goTimeout(t, 10*time.Second, func() {
559 n, err := conn.Read(buf[:])
560 if err == nil || n != 0 {
561 t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
566 func TestTLSServer(t *testing.T) {
567 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
569 w.Header().Set("X-TLS-Set", "true")
570 if r.TLS.HandshakeComplete {
571 w.Header().Set("X-TLS-HandshakeComplete", "true")
577 // Connect an idle TCP connection to this server before we run
578 // our real tests. This idle connection used to block forever
579 // in the TLS handshake, preventing future connections from
580 // being accepted. It may prevent future accidental blocking
582 idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
584 t.Fatalf("Dial: %v", err)
586 defer idleConn.Close()
587 goTimeout(t, 10*time.Second, func() {
588 if !strings.HasPrefix(ts.URL, "https://") {
589 t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
592 noVerifyTransport := &Transport{
593 TLSClientConfig: &tls.Config{
594 InsecureSkipVerify: true,
597 client := &Client{Transport: noVerifyTransport}
598 res, err := client.Get(ts.URL)
604 t.Errorf("got nil Response")
607 defer res.Body.Close()
608 if res.Header.Get("X-TLS-Set") != "true" {
609 t.Errorf("expected X-TLS-Set response header")
612 if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
613 t.Errorf("expected X-TLS-HandshakeComplete header")
618 type serverExpectTest struct {
619 contentLength int // of request body
620 expectation string // e.g. "100-continue"
621 readBody bool // whether handler should read the body (if false, sends StatusUnauthorized)
622 expectedResponse string // expected substring in first line of http response
625 var serverExpectTests = []serverExpectTest{
626 // Normal 100-continues, case-insensitive.
627 {100, "100-continue", true, "100 Continue"},
628 {100, "100-cOntInUE", true, "100 Continue"},
631 {100, "", true, "200 OK"},
633 // 100-continue but requesting client to deny us,
634 // so it never reads the body.
635 {100, "100-continue", false, "401 Unauthorized"},
636 // Likewise without 100-continue:
637 {100, "", false, "401 Unauthorized"},
639 // Non-standard expectations are failures
640 {0, "a-pony", false, "417 Expectation Failed"},
642 // Expect-100 requested but no body
643 {0, "100-continue", true, "400 Bad Request"},
646 // Tests that the server responds to the "Expect" request header
648 func TestServerExpect(t *testing.T) {
649 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
650 // Note using r.FormValue("readbody") because for POST
651 // requests that would read from r.Body, which we only
652 // conditionally want to do.
653 if strings.Contains(r.URL.RawQuery, "readbody=true") {
654 ioutil.ReadAll(r.Body)
655 w.Write([]byte("Hi"))
657 w.WriteHeader(StatusUnauthorized)
662 runTest := func(test serverExpectTest) {
663 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
665 t.Fatalf("Dial: %v", err)
668 sendf := func(format string, args ...interface{}) {
669 _, err := fmt.Fprintf(conn, format, args...)
671 t.Fatalf("On test %#v, error writing %q: %v", test, format, err)
675 sendf("POST /?readbody=%v HTTP/1.1\r\n"+
676 "Connection: close\r\n"+
677 "Content-Length: %d\r\n"+
678 "Expect: %s\r\nHost: foo\r\n\r\n",
679 test.readBody, test.contentLength, test.expectation)
680 if test.contentLength > 0 && strings.ToLower(test.expectation) != "100-continue" {
681 body := strings.Repeat("A", test.contentLength)
685 bufr := bufio.NewReader(conn)
686 line, err := bufr.ReadString('\n')
688 t.Fatalf("ReadString: %v", err)
690 if !strings.Contains(line, test.expectedResponse) {
691 t.Errorf("for test %#v got first line=%q", test, line)
695 for _, test := range serverExpectTests {
700 // Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
701 // should consume client request bodies that a handler didn't read.
702 func TestServerUnreadRequestBodyLittle(t *testing.T) {
703 conn := new(testConn)
704 body := strings.Repeat("x", 100<<10)
705 conn.readBuf.Write([]byte(fmt.Sprintf(
706 "POST / HTTP/1.1\r\n"+
708 "Content-Length: %d\r\n"+
710 conn.readBuf.Write([]byte(body))
712 done := make(chan bool)
714 ls := &oneConnListener{conn}
715 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
717 if conn.readBuf.Len() < len(body)/2 {
718 t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
721 if g, e := conn.readBuf.Len(), 0; g != e {
722 t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
724 if c := rw.Header().Get("Connection"); c != "" {
725 t.Errorf(`Connection header = %q; want ""`, c)
731 // Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
732 // should ignore client request bodies that a handler didn't read
733 // and close the connection.
734 func TestServerUnreadRequestBodyLarge(t *testing.T) {
735 conn := new(testConn)
736 body := strings.Repeat("x", 1<<20)
737 conn.readBuf.Write([]byte(fmt.Sprintf(
738 "POST / HTTP/1.1\r\n"+
740 "Content-Length: %d\r\n"+
742 conn.readBuf.Write([]byte(body))
744 done := make(chan bool)
746 ls := &oneConnListener{conn}
747 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
749 if conn.readBuf.Len() < len(body)/2 {
750 t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
753 if conn.readBuf.Len() < len(body)/2 {
754 t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
756 if c := rw.Header().Get("Connection"); c != "close" {
757 t.Errorf(`Connection header = %q; want "close"`, c)
763 func TestTimeoutHandler(t *testing.T) {
764 sendHi := make(chan bool, 1)
765 writeErrors := make(chan error, 1)
766 sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
768 _, werr := w.Write([]byte("hi"))
771 timeout := make(chan time.Time, 1) // write to this to force timeouts
772 ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
775 // Succeed without timing out:
777 res, err := Get(ts.URL)
781 if g, e := res.StatusCode, StatusOK; g != e {
782 t.Errorf("got res.StatusCode %d; expected %d", g, e)
784 body, _ := ioutil.ReadAll(res.Body)
785 if g, e := string(body), "hi"; g != e {
786 t.Errorf("got body %q; expected %q", g, e)
788 if g := <-writeErrors; g != nil {
789 t.Errorf("got unexpected Write error on first request: %v", g)
793 timeout <- time.Time{}
794 res, err = Get(ts.URL)
798 if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
799 t.Errorf("got res.StatusCode %d; expected %d", g, e)
801 body, _ = ioutil.ReadAll(res.Body)
802 if !strings.Contains(string(body), "<title>Timeout</title>") {
803 t.Errorf("expected timeout body; got %q", string(body))
806 // Now make the previously-timed out handler speak again,
807 // which verifies the panic is handled:
809 if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
810 t.Errorf("expected Write error of %v; got %v", e, g)
814 // Verifies we don't path.Clean() on the wrong parts in redirects.
815 func TestRedirectMunging(t *testing.T) {
816 req, _ := NewRequest("GET", "http://example.com/", nil)
818 resp := httptest.NewRecorder()
819 Redirect(resp, req, "/foo?next=http://bar.com/", 302)
820 if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
821 t.Errorf("Location header was %q; want %q", g, e)
824 resp = httptest.NewRecorder()
825 Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
826 if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
827 t.Errorf("Location header was %q; want %q", g, e)
831 // TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
832 // when there is no body (either because the method doesn't permit a body, or an
833 // explicit Content-Length of zero is present), then the transport can re-use the
834 // connection immediately. But when it re-uses the connection, it typically closes
835 // the previous request's body, which is not optimal for zero-lengthed bodies,
836 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
837 func TestZeroLengthPostAndResponse(t *testing.T) {
838 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
839 all, err := ioutil.ReadAll(r.Body)
841 t.Fatalf("handler ReadAll: %v", err)
844 t.Errorf("handler got %d bytes; expected 0", len(all))
846 rw.Header().Set("Content-Length", "0")
850 req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
854 req.ContentLength = 0
856 var resp [5]*Response
857 for i := range resp {
858 resp[i], err = DefaultClient.Do(req)
860 t.Fatalf("client post #%d: %v", i, err)
864 for i := range resp {
865 all, err := ioutil.ReadAll(resp[i].Body)
867 t.Fatalf("req #%d: client ReadAll: %v", i, err)
870 t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
875 func TestHandlerPanic(t *testing.T) {
876 testHandlerPanic(t, false)
879 func TestHandlerPanicWithHijack(t *testing.T) {
880 testHandlerPanic(t, true)
883 func testHandlerPanic(t *testing.T, withHijack bool) {
884 // Unlike the other tests that set the log output to ioutil.Discard
885 // to quiet the output, this test uses a pipe. The pipe serves three
888 // 1) The log.Print from the http server (generated by the caught
889 // panic) will go to the pipe instead of stderr, making the
892 // 2) We read from the pipe to verify that the handler
893 // actually caught the panic and logged something.
895 // 3) The blocking Read call prevents this TestHandlerPanic
896 // function from exiting before the HTTP server handler
897 // finishes crashing. If this text function exited too
898 // early (and its defer log.SetOutput(os.Stderr) ran),
899 // then the crash output could spill into the next test.
902 defer log.SetOutput(os.Stderr)
904 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
906 rwc, _, err := w.(Hijacker).Hijack()
908 t.Logf("unexpected error: %v", err)
912 panic("intentional death for testing")
916 // Do a blocking read on the log output pipe so its logging
917 // doesn't bleed into the next test. But wait only 5 seconds
919 done := make(chan bool, 1)
921 buf := make([]byte, 4<<10)
922 _, err := pr.Read(buf)
930 _, err := Get(ts.URL)
932 t.Logf("expected an error")
938 case <-time.After(5 * time.Second):
939 t.Fatal("expected server handler to log an error")
943 func TestNoDate(t *testing.T) {
944 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
945 w.Header()["Date"] = nil
948 res, err := Get(ts.URL)
952 _, present := res.Header["Date"]
954 t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
958 func TestStripPrefix(t *testing.T) {
959 h := HandlerFunc(func(w ResponseWriter, r *Request) {
960 w.Header().Set("X-Path", r.URL.Path)
962 ts := httptest.NewServer(StripPrefix("/foo", h))
965 res, err := Get(ts.URL + "/foo/bar")
969 if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
970 t.Errorf("test 1: got %s, want %s", g, e)
973 res, err = Get(ts.URL + "/bar")
977 if g, e := res.StatusCode, 404; g != e {
978 t.Errorf("test 2: got status %v, want %v", g, e)
982 func TestRequestLimit(t *testing.T) {
983 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
984 t.Fatalf("didn't expect to get request in Handler")
987 req, _ := NewRequest("GET", ts.URL, nil)
988 var bytesPerHeader = len("header12345: val12345\r\n")
989 for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
990 req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
992 res, err := DefaultClient.Do(req)
994 // Some HTTP clients may fail on this undefined behavior (server replying and
995 // closing the connection while the request is still being written), but
996 // we do support it (at least currently), so we expect a response below.
997 t.Fatalf("Do: %v", err)
999 if res.StatusCode != 413 {
1000 t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
1004 type neverEnding byte
1006 func (b neverEnding) Read(p []byte) (n int, err error) {
1013 type countReader struct {
1018 func (cr countReader) Read(p []byte) (n int, err error) {
1019 n, err = cr.r.Read(p)
1024 func TestRequestBodyLimit(t *testing.T) {
1025 const limit = 1 << 20
1026 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1027 r.Body = MaxBytesReader(w, r.Body, limit)
1028 n, err := io.Copy(ioutil.Discard, r.Body)
1030 t.Errorf("expected error from io.Copy")
1033 t.Errorf("io.Copy = %d, want %d", n, limit)
1038 nWritten := int64(0)
1039 req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), &nWritten}, limit*200))
1041 // Send the POST, but don't care it succeeds or not. The
1042 // remote side is going to reply and then close the TCP
1043 // connection, and HTTP doesn't really define if that's
1044 // allowed or not. Some HTTP clients will get the response
1045 // and some (like ours, currently) will complain that the
1046 // request write failed, without reading the response.
1048 // But that's okay, since what we're really testing is that
1049 // the remote side hung up on us before we wrote too much.
1050 _, _ = DefaultClient.Do(req)
1052 if nWritten > limit*100 {
1053 t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
1058 // TestClientWriteShutdown tests that if the client shuts down the write
1059 // side of their TCP connection, the server doesn't send a 400 Bad Request.
1060 func TestClientWriteShutdown(t *testing.T) {
1061 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
1063 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1065 t.Fatalf("Dial: %v", err)
1067 err = conn.(*net.TCPConn).CloseWrite()
1069 t.Fatalf("Dial: %v", err)
1071 donec := make(chan bool)
1074 bs, err := ioutil.ReadAll(conn)
1076 t.Fatalf("ReadAll: %v", err)
1080 t.Errorf("read %q from server; want nothing", got)
1085 case <-time.After(10 * time.Second):
1090 // Tests that chunked server responses that write 1 byte at a time are
1091 // buffered before chunk headers are added, not after chunk headers.
1092 func TestServerBufferedChunking(t *testing.T) {
1094 t.Logf("Skipping known broken test; see Issue 2357")
1097 conn := new(testConn)
1098 conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
1099 done := make(chan bool)
1100 ls := &oneConnListener{conn}
1101 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1103 rw.Header().Set("Content-Type", "text/plain") // prevent sniffing, which buffers
1104 rw.Write([]byte{'x'})
1105 rw.Write([]byte{'y'})
1106 rw.Write([]byte{'z'})
1109 if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
1110 t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
1111 conn.writeBuf.Bytes())
1115 // TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
1116 // request (both keep-alive), when a Handler never writes any
1117 // response, the net/http package adds a "Content-Length: 0" response
1119 func TestContentLengthZero(t *testing.T) {
1120 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
1123 for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
1124 conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1126 t.Fatalf("error dialing: %v", err)
1128 _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
1130 t.Fatalf("error writing: %v", err)
1132 req, _ := NewRequest("GET", "/", nil)
1133 res, err := ReadResponse(bufio.NewReader(conn), req)
1135 t.Fatalf("error reading response: %v", err)
1137 if te := res.TransferEncoding; len(te) > 0 {
1138 t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
1140 if cl := res.ContentLength; cl != 0 {
1141 t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
1147 // goTimeout runs f, failing t if f takes more than ns to complete.
1148 func goTimeout(t *testing.T, d time.Duration, f func()) {
1149 ch := make(chan bool, 2)
1150 timer := time.AfterFunc(d, func() {
1151 t.Errorf("Timeout expired after %v", d)
1156 defer func() { ch <- true }()
1162 type errorListener struct {
1166 func (l *errorListener) Accept() (c net.Conn, err error) {
1167 if len(l.errs) == 0 {
1175 func (l *errorListener) Close() error {
1179 func (l *errorListener) Addr() net.Addr {
1180 return dummyAddr("test-address")
1183 func TestAcceptMaxFds(t *testing.T) {
1184 log.SetOutput(ioutil.Discard) // is noisy otherwise
1185 defer log.SetOutput(os.Stderr)
1187 ln := &errorListener{[]error{
1190 Err: syscall.EMFILE,
1192 err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
1194 t.Errorf("got error %v, want EOF", err)
1198 func BenchmarkClientServer(b *testing.B) {
1200 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1201 fmt.Fprintf(rw, "Hello world.\n")
1206 for i := 0; i < b.N; i++ {
1207 res, err := Get(ts.URL)
1209 b.Fatal("Get:", err)
1211 all, err := ioutil.ReadAll(res.Body)
1213 b.Fatal("ReadAll:", err)
1216 if body != "Hello world.\n" {
1217 b.Fatal("Got body:", body)