Merge lp:~pedronis/ubuntu-push/http13client into lp:ubuntu-push

Proposed by Samuele Pedroni
Status: Merged
Approved by: Samuele Pedroni
Approved revision: 92
Merged at revision: 82
Proposed branch: lp:~pedronis/ubuntu-push/http13client
Merge into: lp:ubuntu-push
Diff against target: 18096 lines (+17900/-0)
39 files modified
http13client/LICENSE (+27/-0)
http13client/Makefile (+37/-0)
http13client/_patches/empty_server.patch (+4719/-0)
http13client/_patches/fix_code.patch (+739/-0)
http13client/_patches/fix_status.patch (+118/-0)
http13client/_patches/fix_tests.patch (+1603/-0)
http13client/_patches/no_keepalive.patch (+11/-0)
http13client/_patches/no_serve_test_unsupported_bench.patch (+46/-0)
http13client/_patches/sync_pool.Rpatch (+172/-0)
http13client/_patches/tweak_doc_go.patch (+43/-0)
http13client/_using.txt (+5/-0)
http13client/chunked.go (+203/-0)
http13client/chunked_test.go (+159/-0)
http13client/client.go (+480/-0)
http13client/client_test.go (+879/-0)
http13client/cookie.go (+313/-0)
http13client/cookie_test.go (+304/-0)
http13client/doc.go (+56/-0)
http13client/export_test.go (+62/-0)
http13client/header.go (+49/-0)
http13client/header_test.go (+213/-0)
http13client/lex.go (+96/-0)
http13client/lex_test.go (+31/-0)
http13client/npn_test.go (+119/-0)
http13client/proxy_test.go (+81/-0)
http13client/readrequest_test.go (+332/-0)
http13client/request.go (+865/-0)
http13client/request_test.go (+571/-0)
http13client/requestwrite_test.go (+566/-0)
http13client/response.go (+244/-0)
http13client/response_test.go (+629/-0)
http13client/responsewrite_test.go (+111/-0)
http13client/serve_test.go (+58/-0)
http13client/server.go (+68/-0)
http13client/transfer.go (+699/-0)
http13client/transfer_test.go (+64/-0)
http13client/transport.go (+1137/-0)
http13client/transport_test.go (+1894/-0)
http13client/z_last_test.go (+97/-0)
To merge this branch: bzr merge lp:~pedronis/ubuntu-push/http13client
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Review via email: mp+211919@code.launchpad.net

Commit message

vendor the go 1.3 development net/http bits which properly/better support timeouts for requests; see _using.txt and Makefile for the recipe in http13client

Description of the change

vendor the go 1.3 development net/http bits which properly/better support timeouts for requests,

added as a http13client package directory (package still named http, though typically it would be imported as http13)

_using.txt records the starting point,

the Makefile and _patches directory captures the required massaging

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) wrote :

I think you just stole the "Biggest diff evar" trophy from me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'http13client'
=== added file 'http13client/LICENSE'
--- http13client/LICENSE 1970-01-01 00:00:00 +0000
+++ http13client/LICENSE 2014-03-20 12:26:55 +0000
@@ -0,0 +1,27 @@
1Copyright (c) 2012 The Go Authors. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6
7 * Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the
12distribution.
13 * Neither the name of Google Inc. nor the names of its
14contributors may be used to endorse or promote products derived from
15this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028
=== added file 'http13client/Makefile'
--- http13client/Makefile 1970-01-01 00:00:00 +0000
+++ http13client/Makefile 2014-03-20 12:26:55 +0000
@@ -0,0 +1,37 @@
1# help massage and extract from go development 1.3 net/http the client bits
2
3grab:
4 cp $(GOCHECKOUT)/src/pkg/net/http/*.go .
5 cp $(GOCHECKOUT)/LICENSE .
6 mkdir -p httptest
7 mkdir -p httputil
8 mkdir -p testdata
9 cp $(GOCHECKOUT)/src/pkg/net/http/httptest/*.go httptest
10 cp $(GOCHECKOUT)/src/pkg/net//http/httputil/*.go httputil
11 cp $(GOCHECKOUT)/src/pkg/net/http/testdata/* testdata
12 hg -R $(GOCHECKOUT) summary > _using.txt
13
14full-prepare:
15 patch -R -p5 < _patches/sync_pool.Rpatch
16 patch -p1 < _patches/no_keepalive.patch
17 sed -i -e 's+"net/http"+"launchpad.net/ubuntu-push/http13client"+' *.go httptest/*.go httputil/*.go
18 sed -i -e 's+"net/http/+"launchpad.net/ubuntu-push/http13client/+' *.go httptest/*.go httputil/*.go
19 patch -p1 < _patches/no_serve_test_unsupported_bench.patch
20
21prune:
22 rm -rf example_test.go filetransport*.go fs*.go race.go range_test.go \
23 sniff*.go httptest httputil testdata triv.go jar.go status.go
24 sed -i -e 's+"launchpad.net/ubuntu-push/http13client/+"net/http/+' *.go
25
26fix:
27 patch -p1 < _patches/empty_server.patch
28 patch -p1 < _patches/fix_tests.patch
29 patch -p1 < _patches/fix_code.patch
30 patch -p1 < _patches/fix_status.patch
31 patch -p1 < _patches/tweak_doc_go.patch
32 go fmt
33
34wipe:
35 rm -rf *.go httptest httputil testdata
36
37.PHONY: grab full-prepare prune fix wipe
038
=== added directory 'http13client/_patches'
=== added file 'http13client/_patches/empty_server.patch'
--- http13client/_patches/empty_server.patch 1970-01-01 00:00:00 +0000
+++ http13client/_patches/empty_server.patch 2014-03-20 12:26:55 +0000
@@ -0,0 +1,4719 @@
1=== modified file 'http13client/serve_test.go'
2--- http13client/serve_test.go 2014-03-19 21:38:56 +0000
3+++ http13client/serve_test.go 2014-03-19 22:27:37 +0000
4@@ -2,60 +2,15 @@
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file.
7
8-// End-to-end serving tests
9-
10 package http_test
11
12 import (
13- "bufio"
14- "bytes"
15- "crypto/tls"
16- "errors"
17- "fmt"
18 "io"
19- "io/ioutil"
20- "log"
21 "net"
22- . "launchpad.net/ubuntu-push/http13client"
23- "net/http/httptest"
24- "net/http/httputil"
25- "net/url"
26- "os"
27- "os/exec"
28- "reflect"
29- "runtime"
30- "strconv"
31- "strings"
32- "sync"
33- "sync/atomic"
34- "syscall"
35- "testing"
36 "time"
37 )
38
39 type dummyAddr string
40-type oneConnListener struct {
41- conn net.Conn
42-}
43-
44-func (l *oneConnListener) Accept() (c net.Conn, err error) {
45- c = l.conn
46- if c == nil {
47- err = io.EOF
48- return
49- }
50- err = nil
51- l.conn = nil
52- return
53-}
54-
55-func (l *oneConnListener) Close() error {
56- return nil
57-}
58-
59-func (l *oneConnListener) Addr() net.Addr {
60- return dummyAddr("test-address")
61-}
62
63 func (a dummyAddr) Network() string {
64 return string(a)
65@@ -93,1289 +48,6 @@
66 return nil
67 }
68
69-type testConn struct {
70- readBuf bytes.Buffer
71- writeBuf bytes.Buffer
72- closec chan bool // if non-nil, send value to it on close
73- noopConn
74-}
75-
76-func (c *testConn) Read(b []byte) (int, error) {
77- return c.readBuf.Read(b)
78-}
79-
80-func (c *testConn) Write(b []byte) (int, error) {
81- return c.writeBuf.Write(b)
82-}
83-
84-func (c *testConn) Close() error {
85- select {
86- case c.closec <- true:
87- default:
88- }
89- return nil
90-}
91-
92-// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters,
93-// ending in \r\n\r\n
94-func reqBytes(req string) []byte {
95- return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n")
96-}
97-
98-type handlerTest struct {
99- handler Handler
100-}
101-
102-func newHandlerTest(h Handler) handlerTest {
103- return handlerTest{h}
104-}
105-
106-func (ht handlerTest) rawResponse(req string) string {
107- reqb := reqBytes(req)
108- var output bytes.Buffer
109- conn := &rwTestConn{
110- Reader: bytes.NewReader(reqb),
111- Writer: &output,
112- closec: make(chan bool, 1),
113- }
114- ln := &oneConnListener{conn: conn}
115- go Serve(ln, ht.handler)
116- <-conn.closec
117- return output.String()
118-}
119-
120-func TestConsumingBodyOnNextConn(t *testing.T) {
121- conn := new(testConn)
122- for i := 0; i < 2; i++ {
123- conn.readBuf.Write([]byte(
124- "POST / HTTP/1.1\r\n" +
125- "Host: test\r\n" +
126- "Content-Length: 11\r\n" +
127- "\r\n" +
128- "foo=1&bar=1"))
129- }
130-
131- reqNum := 0
132- ch := make(chan *Request)
133- servech := make(chan error)
134- listener := &oneConnListener{conn}
135- handler := func(res ResponseWriter, req *Request) {
136- reqNum++
137- ch <- req
138- }
139-
140- go func() {
141- servech <- Serve(listener, HandlerFunc(handler))
142- }()
143-
144- var req *Request
145- req = <-ch
146- if req == nil {
147- t.Fatal("Got nil first request.")
148- }
149- if req.Method != "POST" {
150- t.Errorf("For request #1's method, got %q; expected %q",
151- req.Method, "POST")
152- }
153-
154- req = <-ch
155- if req == nil {
156- t.Fatal("Got nil first request.")
157- }
158- if req.Method != "POST" {
159- t.Errorf("For request #2's method, got %q; expected %q",
160- req.Method, "POST")
161- }
162-
163- if serveerr := <-servech; serveerr != io.EOF {
164- t.Errorf("Serve returned %q; expected EOF", serveerr)
165- }
166-}
167-
168-type stringHandler string
169-
170-func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
171- w.Header().Set("Result", string(s))
172-}
173-
174-var handlers = []struct {
175- pattern string
176- msg string
177-}{
178- {"/", "Default"},
179- {"/someDir/", "someDir"},
180- {"someHost.com/someDir/", "someHost.com/someDir"},
181-}
182-
183-var vtests = []struct {
184- url string
185- expected string
186-}{
187- {"http://localhost/someDir/apage", "someDir"},
188- {"http://localhost/otherDir/apage", "Default"},
189- {"http://someHost.com/someDir/apage", "someHost.com/someDir"},
190- {"http://otherHost.com/someDir/apage", "someDir"},
191- {"http://otherHost.com/aDir/apage", "Default"},
192- // redirections for trees
193- {"http://localhost/someDir", "/someDir/"},
194- {"http://someHost.com/someDir", "/someDir/"},
195-}
196-
197-func TestHostHandlers(t *testing.T) {
198- defer afterTest(t)
199- mux := NewServeMux()
200- for _, h := range handlers {
201- mux.Handle(h.pattern, stringHandler(h.msg))
202- }
203- ts := httptest.NewServer(mux)
204- defer ts.Close()
205-
206- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
207- if err != nil {
208- t.Fatal(err)
209- }
210- defer conn.Close()
211- cc := httputil.NewClientConn(conn, nil)
212- for _, vt := range vtests {
213- var r *Response
214- var req Request
215- if req.URL, err = url.Parse(vt.url); err != nil {
216- t.Errorf("cannot parse url: %v", err)
217- continue
218- }
219- if err := cc.Write(&req); err != nil {
220- t.Errorf("writing request: %v", err)
221- continue
222- }
223- r, err := cc.Read(&req)
224- if err != nil {
225- t.Errorf("reading response: %v", err)
226- continue
227- }
228- switch r.StatusCode {
229- case StatusOK:
230- s := r.Header.Get("Result")
231- if s != vt.expected {
232- t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
233- }
234- case StatusMovedPermanently:
235- s := r.Header.Get("Location")
236- if s != vt.expected {
237- t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
238- }
239- default:
240- t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode)
241- }
242- }
243-}
244-
245-var serveMuxRegister = []struct {
246- pattern string
247- h Handler
248-}{
249- {"/dir/", serve(200)},
250- {"/search", serve(201)},
251- {"codesearch.google.com/search", serve(202)},
252- {"codesearch.google.com/", serve(203)},
253- {"example.com/", HandlerFunc(checkQueryStringHandler)},
254-}
255-
256-// serve returns a handler that sends a response with the given code.
257-func serve(code int) HandlerFunc {
258- return func(w ResponseWriter, r *Request) {
259- w.WriteHeader(code)
260- }
261-}
262-
263-// checkQueryStringHandler checks if r.URL.RawQuery has the same value
264-// as the URL excluding the scheme and the query string and sends 200
265-// response code if it is, 500 otherwise.
266-func checkQueryStringHandler(w ResponseWriter, r *Request) {
267- u := *r.URL
268- u.Scheme = "http"
269- u.Host = r.Host
270- u.RawQuery = ""
271- if "http://"+r.URL.RawQuery == u.String() {
272- w.WriteHeader(200)
273- } else {
274- w.WriteHeader(500)
275- }
276-}
277-
278-var serveMuxTests = []struct {
279- method string
280- host string
281- path string
282- code int
283- pattern string
284-}{
285- {"GET", "google.com", "/", 404, ""},
286- {"GET", "google.com", "/dir", 301, "/dir/"},
287- {"GET", "google.com", "/dir/", 200, "/dir/"},
288- {"GET", "google.com", "/dir/file", 200, "/dir/"},
289- {"GET", "google.com", "/search", 201, "/search"},
290- {"GET", "google.com", "/search/", 404, ""},
291- {"GET", "google.com", "/search/foo", 404, ""},
292- {"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"},
293- {"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"},
294- {"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"},
295- {"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"},
296- {"GET", "images.google.com", "/search", 201, "/search"},
297- {"GET", "images.google.com", "/search/", 404, ""},
298- {"GET", "images.google.com", "/search/foo", 404, ""},
299- {"GET", "google.com", "/../search", 301, "/search"},
300- {"GET", "google.com", "/dir/..", 301, ""},
301- {"GET", "google.com", "/dir/..", 301, ""},
302- {"GET", "google.com", "/dir/./file", 301, "/dir/"},
303-
304- // The /foo -> /foo/ redirect applies to CONNECT requests
305- // but the path canonicalization does not.
306- {"CONNECT", "google.com", "/dir", 301, "/dir/"},
307- {"CONNECT", "google.com", "/../search", 404, ""},
308- {"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
309- {"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
310- {"CONNECT", "google.com", "/dir/./file", 200, "/dir/"},
311-}
312-
313-func TestServeMuxHandler(t *testing.T) {
314- mux := NewServeMux()
315- for _, e := range serveMuxRegister {
316- mux.Handle(e.pattern, e.h)
317- }
318-
319- for _, tt := range serveMuxTests {
320- r := &Request{
321- Method: tt.method,
322- Host: tt.host,
323- URL: &url.URL{
324- Path: tt.path,
325- },
326- }
327- h, pattern := mux.Handler(r)
328- rr := httptest.NewRecorder()
329- h.ServeHTTP(rr, r)
330- if pattern != tt.pattern || rr.Code != tt.code {
331- t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern)
332- }
333- }
334-}
335-
336-var serveMuxTests2 = []struct {
337- method string
338- host string
339- url string
340- code int
341- redirOk bool
342-}{
343- {"GET", "google.com", "/", 404, false},
344- {"GET", "example.com", "/test/?example.com/test/", 200, false},
345- {"GET", "example.com", "test/?example.com/test/", 200, true},
346-}
347-
348-// TestServeMuxHandlerRedirects tests that automatic redirects generated by
349-// mux.Handler() shouldn't clear the request's query string.
350-func TestServeMuxHandlerRedirects(t *testing.T) {
351- mux := NewServeMux()
352- for _, e := range serveMuxRegister {
353- mux.Handle(e.pattern, e.h)
354- }
355-
356- for _, tt := range serveMuxTests2 {
357- tries := 1
358- turl := tt.url
359- for tries > 0 {
360- u, e := url.Parse(turl)
361- if e != nil {
362- t.Fatal(e)
363- }
364- r := &Request{
365- Method: tt.method,
366- Host: tt.host,
367- URL: u,
368- }
369- h, _ := mux.Handler(r)
370- rr := httptest.NewRecorder()
371- h.ServeHTTP(rr, r)
372- if rr.Code != 301 {
373- if rr.Code != tt.code {
374- t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code)
375- }
376- break
377- }
378- if !tt.redirOk {
379- t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url)
380- break
381- }
382- turl = rr.HeaderMap.Get("Location")
383- tries--
384- }
385- if tries < 0 {
386- t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url)
387- }
388- }
389-}
390-
391-// Tests for http://code.google.com/p/go/issues/detail?id=900
392-func TestMuxRedirectLeadingSlashes(t *testing.T) {
393- paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
394- for _, path := range paths {
395- req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
396- if err != nil {
397- t.Errorf("%s", err)
398- }
399- mux := NewServeMux()
400- resp := httptest.NewRecorder()
401-
402- mux.ServeHTTP(resp, req)
403-
404- if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected {
405- t.Errorf("Expected Location header set to %q; got %q", expected, loc)
406- return
407- }
408-
409- if code, expected := resp.Code, StatusMovedPermanently; code != expected {
410- t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
411- return
412- }
413- }
414-}
415-
416-func TestServerTimeouts(t *testing.T) {
417- if runtime.GOOS == "plan9" {
418- t.Skip("skipping test; see http://golang.org/issue/7237")
419- }
420- defer afterTest(t)
421- reqNum := 0
422- ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
423- reqNum++
424- fmt.Fprintf(res, "req=%d", reqNum)
425- }))
426- ts.Config.ReadTimeout = 250 * time.Millisecond
427- ts.Config.WriteTimeout = 250 * time.Millisecond
428- ts.Start()
429- defer ts.Close()
430-
431- // Hit the HTTP server successfully.
432- tr := &Transport{DisableKeepAlives: true} // they interfere with this test
433- defer tr.CloseIdleConnections()
434- c := &Client{Transport: tr}
435- r, err := c.Get(ts.URL)
436- if err != nil {
437- t.Fatalf("http Get #1: %v", err)
438- }
439- got, _ := ioutil.ReadAll(r.Body)
440- expected := "req=1"
441- if string(got) != expected {
442- t.Errorf("Unexpected response for request #1; got %q; expected %q",
443- string(got), expected)
444- }
445-
446- // Slow client that should timeout.
447- t1 := time.Now()
448- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
449- if err != nil {
450- t.Fatalf("Dial: %v", err)
451- }
452- buf := make([]byte, 1)
453- n, err := conn.Read(buf)
454- latency := time.Since(t1)
455- if n != 0 || err != io.EOF {
456- t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
457- }
458- if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
459- t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
460- }
461-
462- // Hit the HTTP server successfully again, verifying that the
463- // previous slow connection didn't run our handler. (that we
464- // get "req=2", not "req=3")
465- r, err = Get(ts.URL)
466- if err != nil {
467- t.Fatalf("http Get #2: %v", err)
468- }
469- got, _ = ioutil.ReadAll(r.Body)
470- expected = "req=2"
471- if string(got) != expected {
472- t.Errorf("Get #2 got %q, want %q", string(got), expected)
473- }
474-
475- if !testing.Short() {
476- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
477- if err != nil {
478- t.Fatalf("Dial: %v", err)
479- }
480- defer conn.Close()
481- go io.Copy(ioutil.Discard, conn)
482- for i := 0; i < 5; i++ {
483- _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"))
484- if err != nil {
485- t.Fatalf("on write %d: %v", i, err)
486- }
487- time.Sleep(ts.Config.ReadTimeout / 2)
488- }
489- }
490-}
491-
492-// golang.org/issue/4741 -- setting only a write timeout that triggers
493-// shouldn't cause a handler to block forever on reads (next HTTP
494-// request) that will never happen.
495-func TestOnlyWriteTimeout(t *testing.T) {
496- if runtime.GOOS == "plan9" {
497- t.Skip("skipping test; see http://golang.org/issue/7237")
498- }
499- defer afterTest(t)
500- var conn net.Conn
501- var afterTimeoutErrc = make(chan error, 1)
502- ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) {
503- buf := make([]byte, 512<<10)
504- _, err := w.Write(buf)
505- if err != nil {
506- t.Errorf("handler Write error: %v", err)
507- return
508- }
509- conn.SetWriteDeadline(time.Now().Add(-30 * time.Second))
510- _, err = w.Write(buf)
511- afterTimeoutErrc <- err
512- }))
513- ts.Listener = trackLastConnListener{ts.Listener, &conn}
514- ts.Start()
515- defer ts.Close()
516-
517- tr := &Transport{DisableKeepAlives: false}
518- defer tr.CloseIdleConnections()
519- c := &Client{Transport: tr}
520-
521- errc := make(chan error)
522- go func() {
523- res, err := c.Get(ts.URL)
524- if err != nil {
525- errc <- err
526- return
527- }
528- _, err = io.Copy(ioutil.Discard, res.Body)
529- errc <- err
530- }()
531- select {
532- case err := <-errc:
533- if err == nil {
534- t.Errorf("expected an error from Get request")
535- }
536- case <-time.After(5 * time.Second):
537- t.Fatal("timeout waiting for Get error")
538- }
539- if err := <-afterTimeoutErrc; err == nil {
540- t.Error("expected write error after timeout")
541- }
542-}
543-
544-// trackLastConnListener tracks the last net.Conn that was accepted.
545-type trackLastConnListener struct {
546- net.Listener
547- last *net.Conn // destination
548-}
549-
550-func (l trackLastConnListener) Accept() (c net.Conn, err error) {
551- c, err = l.Listener.Accept()
552- *l.last = c
553- return
554-}
555-
556-// TestIdentityResponse verifies that a handler can unset
557-func TestIdentityResponse(t *testing.T) {
558- defer afterTest(t)
559- handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
560- rw.Header().Set("Content-Length", "3")
561- rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
562- switch {
563- case req.FormValue("overwrite") == "1":
564- _, err := rw.Write([]byte("foo TOO LONG"))
565- if err != ErrContentLength {
566- t.Errorf("expected ErrContentLength; got %v", err)
567- }
568- case req.FormValue("underwrite") == "1":
569- rw.Header().Set("Content-Length", "500")
570- rw.Write([]byte("too short"))
571- default:
572- rw.Write([]byte("foo"))
573- }
574- })
575-
576- ts := httptest.NewServer(handler)
577- defer ts.Close()
578-
579- // Note: this relies on the assumption (which is true) that
580- // Get sends HTTP/1.1 or greater requests. Otherwise the
581- // server wouldn't have the choice to send back chunked
582- // responses.
583- for _, te := range []string{"", "identity"} {
584- url := ts.URL + "/?te=" + te
585- res, err := Get(url)
586- if err != nil {
587- t.Fatalf("error with Get of %s: %v", url, err)
588- }
589- if cl, expected := res.ContentLength, int64(3); cl != expected {
590- t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
591- }
592- if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
593- t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
594- }
595- if tl, expected := len(res.TransferEncoding), 0; tl != expected {
596- t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
597- url, expected, tl, res.TransferEncoding)
598- }
599- res.Body.Close()
600- }
601-
602- // Verify that ErrContentLength is returned
603- url := ts.URL + "/?overwrite=1"
604- res, err := Get(url)
605- if err != nil {
606- t.Fatalf("error with Get of %s: %v", url, err)
607- }
608- res.Body.Close()
609-
610- // Verify that the connection is closed when the declared Content-Length
611- // is larger than what the handler wrote.
612- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
613- if err != nil {
614- t.Fatalf("error dialing: %v", err)
615- }
616- _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
617- if err != nil {
618- t.Fatalf("error writing: %v", err)
619- }
620-
621- // The ReadAll will hang for a failing test, so use a Timer to
622- // fail explicitly.
623- goTimeout(t, 2*time.Second, func() {
624- got, _ := ioutil.ReadAll(conn)
625- expectedSuffix := "\r\n\r\ntoo short"
626- if !strings.HasSuffix(string(got), expectedSuffix) {
627- t.Errorf("Expected output to end with %q; got response body %q",
628- expectedSuffix, string(got))
629- }
630- })
631-}
632-
633-func testTCPConnectionCloses(t *testing.T, req string, h Handler) {
634- defer afterTest(t)
635- s := httptest.NewServer(h)
636- defer s.Close()
637-
638- conn, err := net.Dial("tcp", s.Listener.Addr().String())
639- if err != nil {
640- t.Fatal("dial error:", err)
641- }
642- defer conn.Close()
643-
644- _, err = fmt.Fprint(conn, req)
645- if err != nil {
646- t.Fatal("print error:", err)
647- }
648-
649- r := bufio.NewReader(conn)
650- res, err := ReadResponse(r, &Request{Method: "GET"})
651- if err != nil {
652- t.Fatal("ReadResponse error:", err)
653- }
654-
655- didReadAll := make(chan bool, 1)
656- go func() {
657- select {
658- case <-time.After(5 * time.Second):
659- t.Error("body not closed after 5s")
660- return
661- case <-didReadAll:
662- }
663- }()
664-
665- _, err = ioutil.ReadAll(r)
666- if err != nil {
667- t.Fatal("read error:", err)
668- }
669- didReadAll <- true
670-
671- if !res.Close {
672- t.Errorf("Response.Close = false; want true")
673- }
674-}
675-
676-// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
677-func TestServeHTTP10Close(t *testing.T) {
678- testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
679- ServeFile(w, r, "testdata/file")
680- }))
681-}
682-
683-// TestClientCanClose verifies that clients can also force a connection to close.
684-func TestClientCanClose(t *testing.T) {
685- testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
686- // Nothing.
687- }))
688-}
689-
690-// TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
691-// even for HTTP/1.1 requests.
692-func TestHandlersCanSetConnectionClose11(t *testing.T) {
693- testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
694- w.Header().Set("Connection", "close")
695- }))
696-}
697-
698-func TestHandlersCanSetConnectionClose10(t *testing.T) {
699- testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
700- w.Header().Set("Connection", "close")
701- }))
702-}
703-
704-func TestSetsRemoteAddr(t *testing.T) {
705- defer afterTest(t)
706- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
707- fmt.Fprintf(w, "%s", r.RemoteAddr)
708- }))
709- defer ts.Close()
710-
711- res, err := Get(ts.URL)
712- if err != nil {
713- t.Fatalf("Get error: %v", err)
714- }
715- body, err := ioutil.ReadAll(res.Body)
716- if err != nil {
717- t.Fatalf("ReadAll error: %v", err)
718- }
719- ip := string(body)
720- if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
721- t.Fatalf("Expected local addr; got %q", ip)
722- }
723-}
724-
725-func TestChunkedResponseHeaders(t *testing.T) {
726- defer afterTest(t)
727- log.SetOutput(ioutil.Discard) // is noisy otherwise
728- defer log.SetOutput(os.Stderr)
729-
730- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
731- w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
732- w.(Flusher).Flush()
733- fmt.Fprintf(w, "I am a chunked response.")
734- }))
735- defer ts.Close()
736-
737- res, err := Get(ts.URL)
738- if err != nil {
739- t.Fatalf("Get error: %v", err)
740- }
741- defer res.Body.Close()
742- if g, e := res.ContentLength, int64(-1); g != e {
743- t.Errorf("expected ContentLength of %d; got %d", e, g)
744- }
745- if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
746- t.Errorf("expected TransferEncoding of %v; got %v", e, g)
747- }
748- if _, haveCL := res.Header["Content-Length"]; haveCL {
749- t.Errorf("Unexpected Content-Length")
750- }
751-}
752-
753-// Test304Responses verifies that 304s don't declare that they're
754-// chunking in their response headers and aren't allowed to produce
755-// output.
756-func Test304Responses(t *testing.T) {
757- defer afterTest(t)
758- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
759- w.WriteHeader(StatusNotModified)
760- _, err := w.Write([]byte("illegal body"))
761- if err != ErrBodyNotAllowed {
762- t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
763- }
764- }))
765- defer ts.Close()
766- res, err := Get(ts.URL)
767- if err != nil {
768- t.Error(err)
769- }
770- if len(res.TransferEncoding) > 0 {
771- t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
772- }
773- body, err := ioutil.ReadAll(res.Body)
774- if err != nil {
775- t.Error(err)
776- }
777- if len(body) > 0 {
778- t.Errorf("got unexpected body %q", string(body))
779- }
780-}
781-
782-// TestHeadResponses verifies that all MIME type sniffing and Content-Length
783-// counting of GET requests also happens on HEAD requests.
784-func TestHeadResponses(t *testing.T) {
785- defer afterTest(t)
786- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
787- _, err := w.Write([]byte("<html>"))
788- if err != nil {
789- t.Errorf("ResponseWriter.Write: %v", err)
790- }
791-
792- // Also exercise the ReaderFrom path
793- _, err = io.Copy(w, strings.NewReader("789a"))
794- if err != nil {
795- t.Errorf("Copy(ResponseWriter, ...): %v", err)
796- }
797- }))
798- defer ts.Close()
799- res, err := Head(ts.URL)
800- if err != nil {
801- t.Error(err)
802- }
803- if len(res.TransferEncoding) > 0 {
804- t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
805- }
806- if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" {
807- t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct)
808- }
809- if v := res.ContentLength; v != 10 {
810- t.Errorf("Content-Length: %d; want 10", v)
811- }
812- body, err := ioutil.ReadAll(res.Body)
813- if err != nil {
814- t.Error(err)
815- }
816- if len(body) > 0 {
817- t.Errorf("got unexpected body %q", string(body))
818- }
819-}
820-
821-func TestTLSHandshakeTimeout(t *testing.T) {
822- if runtime.GOOS == "plan9" {
823- t.Skip("skipping test; see http://golang.org/issue/7237")
824- }
825- defer afterTest(t)
826- ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
827- errc := make(chanWriter, 10) // but only expecting 1
828- ts.Config.ReadTimeout = 250 * time.Millisecond
829- ts.Config.ErrorLog = log.New(errc, "", 0)
830- ts.StartTLS()
831- defer ts.Close()
832- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
833- if err != nil {
834- t.Fatalf("Dial: %v", err)
835- }
836- defer conn.Close()
837- goTimeout(t, 10*time.Second, func() {
838- var buf [1]byte
839- n, err := conn.Read(buf[:])
840- if err == nil || n != 0 {
841- t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
842- }
843- })
844- select {
845- case v := <-errc:
846- if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") {
847- t.Errorf("expected a TLS handshake timeout error; got %q", v)
848- }
849- case <-time.After(5 * time.Second):
850- t.Errorf("timeout waiting for logged error")
851- }
852-}
853-
854-func TestTLSServer(t *testing.T) {
855- defer afterTest(t)
856- ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
857- if r.TLS != nil {
858- w.Header().Set("X-TLS-Set", "true")
859- if r.TLS.HandshakeComplete {
860- w.Header().Set("X-TLS-HandshakeComplete", "true")
861- }
862- }
863- }))
864- ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
865- defer ts.Close()
866-
867- // Connect an idle TCP connection to this server before we run
868- // our real tests. This idle connection used to block forever
869- // in the TLS handshake, preventing future connections from
870- // being accepted. It may prevent future accidental blocking
871- // in newConn.
872- idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
873- if err != nil {
874- t.Fatalf("Dial: %v", err)
875- }
876- defer idleConn.Close()
877- goTimeout(t, 10*time.Second, func() {
878- if !strings.HasPrefix(ts.URL, "https://") {
879- t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
880- return
881- }
882- noVerifyTransport := &Transport{
883- TLSClientConfig: &tls.Config{
884- InsecureSkipVerify: true,
885- },
886- }
887- client := &Client{Transport: noVerifyTransport}
888- res, err := client.Get(ts.URL)
889- if err != nil {
890- t.Error(err)
891- return
892- }
893- if res == nil {
894- t.Errorf("got nil Response")
895- return
896- }
897- defer res.Body.Close()
898- if res.Header.Get("X-TLS-Set") != "true" {
899- t.Errorf("expected X-TLS-Set response header")
900- return
901- }
902- if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
903- t.Errorf("expected X-TLS-HandshakeComplete header")
904- }
905- })
906-}
907-
908-type serverExpectTest struct {
909- contentLength int // of request body
910- expectation string // e.g. "100-continue"
911- readBody bool // whether handler should read the body (if false, sends StatusUnauthorized)
912- expectedResponse string // expected substring in first line of http response
913-}
914-
915-var serverExpectTests = []serverExpectTest{
916- // Normal 100-continues, case-insensitive.
917- {100, "100-continue", true, "100 Continue"},
918- {100, "100-cOntInUE", true, "100 Continue"},
919-
920- // No 100-continue.
921- {100, "", true, "200 OK"},
922-
923- // 100-continue but requesting client to deny us,
924- // so it never reads the body.
925- {100, "100-continue", false, "401 Unauthorized"},
926- // Likewise without 100-continue:
927- {100, "", false, "401 Unauthorized"},
928-
929- // Non-standard expectations are failures
930- {0, "a-pony", false, "417 Expectation Failed"},
931-
932- // Expect-100 requested but no body
933- {0, "100-continue", true, "400 Bad Request"},
934-}
935-
936-// Tests that the server responds to the "Expect" request header
937-// correctly.
938-func TestServerExpect(t *testing.T) {
939- defer afterTest(t)
940- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
941- // Note using r.FormValue("readbody") because for POST
942- // requests that would read from r.Body, which we only
943- // conditionally want to do.
944- if strings.Contains(r.URL.RawQuery, "readbody=true") {
945- ioutil.ReadAll(r.Body)
946- w.Write([]byte("Hi"))
947- } else {
948- w.WriteHeader(StatusUnauthorized)
949- }
950- }))
951- defer ts.Close()
952-
953- runTest := func(test serverExpectTest) {
954- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
955- if err != nil {
956- t.Fatalf("Dial: %v", err)
957- }
958- defer conn.Close()
959-
960- // Only send the body immediately if we're acting like an HTTP client
961- // that doesn't send 100-continue expectations.
962- writeBody := test.contentLength > 0 && strings.ToLower(test.expectation) != "100-continue"
963-
964- go func() {
965- _, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+
966- "Connection: close\r\n"+
967- "Content-Length: %d\r\n"+
968- "Expect: %s\r\nHost: foo\r\n\r\n",
969- test.readBody, test.contentLength, test.expectation)
970- if err != nil {
971- t.Errorf("On test %#v, error writing request headers: %v", test, err)
972- return
973- }
974- if writeBody {
975- body := strings.Repeat("A", test.contentLength)
976- _, err = fmt.Fprint(conn, body)
977- if err != nil {
978- if !test.readBody {
979- // Server likely already hung up on us.
980- // See larger comment below.
981- t.Logf("On test %#v, acceptable error writing request body: %v", test, err)
982- return
983- }
984- t.Errorf("On test %#v, error writing request body: %v", test, err)
985- }
986- }
987- }()
988- bufr := bufio.NewReader(conn)
989- line, err := bufr.ReadString('\n')
990- if err != nil {
991- if writeBody && !test.readBody {
992- // This is an acceptable failure due to a possible TCP race:
993- // We were still writing data and the server hung up on us. A TCP
994- // implementation may send a RST if our request body data was known
995- // to be lost, which may trigger our reads to fail.
996- // See RFC 1122 page 88.
997- t.Logf("On test %#v, acceptable error from ReadString: %v", test, err)
998- return
999- }
1000- t.Fatalf("On test %#v, ReadString: %v", test, err)
1001- }
1002- if !strings.Contains(line, test.expectedResponse) {
1003- t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse)
1004- }
1005- }
1006-
1007- for _, test := range serverExpectTests {
1008- runTest(test)
1009- }
1010-}
1011-
1012-// Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
1013-// should consume client request bodies that a handler didn't read.
1014-func TestServerUnreadRequestBodyLittle(t *testing.T) {
1015- conn := new(testConn)
1016- body := strings.Repeat("x", 100<<10)
1017- conn.readBuf.Write([]byte(fmt.Sprintf(
1018- "POST / HTTP/1.1\r\n"+
1019- "Host: test\r\n"+
1020- "Content-Length: %d\r\n"+
1021- "\r\n", len(body))))
1022- conn.readBuf.Write([]byte(body))
1023-
1024- done := make(chan bool)
1025-
1026- ls := &oneConnListener{conn}
1027- go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1028- defer close(done)
1029- if conn.readBuf.Len() < len(body)/2 {
1030- t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
1031- }
1032- rw.WriteHeader(200)
1033- rw.(Flusher).Flush()
1034- if g, e := conn.readBuf.Len(), 0; g != e {
1035- t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
1036- }
1037- if c := rw.Header().Get("Connection"); c != "" {
1038- t.Errorf(`Connection header = %q; want ""`, c)
1039- }
1040- }))
1041- <-done
1042-}
1043-
1044-// Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
1045-// should ignore client request bodies that a handler didn't read
1046-// and close the connection.
1047-func TestServerUnreadRequestBodyLarge(t *testing.T) {
1048- conn := new(testConn)
1049- body := strings.Repeat("x", 1<<20)
1050- conn.readBuf.Write([]byte(fmt.Sprintf(
1051- "POST / HTTP/1.1\r\n"+
1052- "Host: test\r\n"+
1053- "Content-Length: %d\r\n"+
1054- "\r\n", len(body))))
1055- conn.readBuf.Write([]byte(body))
1056- conn.closec = make(chan bool, 1)
1057-
1058- ls := &oneConnListener{conn}
1059- go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1060- if conn.readBuf.Len() < len(body)/2 {
1061- t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
1062- }
1063- rw.WriteHeader(200)
1064- rw.(Flusher).Flush()
1065- if conn.readBuf.Len() < len(body)/2 {
1066- t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
1067- }
1068- }))
1069- <-conn.closec
1070-
1071- if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") {
1072- t.Errorf("Expected a Connection: close header; got response: %s", res)
1073- }
1074-}
1075-
1076-func TestTimeoutHandler(t *testing.T) {
1077- defer afterTest(t)
1078- sendHi := make(chan bool, 1)
1079- writeErrors := make(chan error, 1)
1080- sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
1081- <-sendHi
1082- _, werr := w.Write([]byte("hi"))
1083- writeErrors <- werr
1084- })
1085- timeout := make(chan time.Time, 1) // write to this to force timeouts
1086- ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
1087- defer ts.Close()
1088-
1089- // Succeed without timing out:
1090- sendHi <- true
1091- res, err := Get(ts.URL)
1092- if err != nil {
1093- t.Error(err)
1094- }
1095- if g, e := res.StatusCode, StatusOK; g != e {
1096- t.Errorf("got res.StatusCode %d; expected %d", g, e)
1097- }
1098- body, _ := ioutil.ReadAll(res.Body)
1099- if g, e := string(body), "hi"; g != e {
1100- t.Errorf("got body %q; expected %q", g, e)
1101- }
1102- if g := <-writeErrors; g != nil {
1103- t.Errorf("got unexpected Write error on first request: %v", g)
1104- }
1105-
1106- // Times out:
1107- timeout <- time.Time{}
1108- res, err = Get(ts.URL)
1109- if err != nil {
1110- t.Error(err)
1111- }
1112- if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
1113- t.Errorf("got res.StatusCode %d; expected %d", g, e)
1114- }
1115- body, _ = ioutil.ReadAll(res.Body)
1116- if !strings.Contains(string(body), "<title>Timeout</title>") {
1117- t.Errorf("expected timeout body; got %q", string(body))
1118- }
1119-
1120- // Now make the previously-timed out handler speak again,
1121- // which verifies the panic is handled:
1122- sendHi <- true
1123- if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
1124- t.Errorf("expected Write error of %v; got %v", e, g)
1125- }
1126-}
1127-
1128-// Verifies we don't path.Clean() on the wrong parts in redirects.
1129-func TestRedirectMunging(t *testing.T) {
1130- req, _ := NewRequest("GET", "http://example.com/", nil)
1131-
1132- resp := httptest.NewRecorder()
1133- Redirect(resp, req, "/foo?next=http://bar.com/", 302)
1134- if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
1135- t.Errorf("Location header was %q; want %q", g, e)
1136- }
1137-
1138- resp = httptest.NewRecorder()
1139- Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
1140- if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
1141- t.Errorf("Location header was %q; want %q", g, e)
1142- }
1143-}
1144-
1145-func TestRedirectBadPath(t *testing.T) {
1146- // This used to crash. It's not valid input (bad path), but it
1147- // shouldn't crash.
1148- rr := httptest.NewRecorder()
1149- req := &Request{
1150- Method: "GET",
1151- URL: &url.URL{
1152- Scheme: "http",
1153- Path: "not-empty-but-no-leading-slash", // bogus
1154- },
1155- }
1156- Redirect(rr, req, "", 304)
1157- if rr.Code != 304 {
1158- t.Errorf("Code = %d; want 304", rr.Code)
1159- }
1160-}
1161-
1162-// TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
1163-// when there is no body (either because the method doesn't permit a body, or an
1164-// explicit Content-Length of zero is present), then the transport can re-use the
1165-// connection immediately. But when it re-uses the connection, it typically closes
1166-// the previous request's body, which is not optimal for zero-lengthed bodies,
1167-// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
1168-func TestZeroLengthPostAndResponse(t *testing.T) {
1169- defer afterTest(t)
1170- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
1171- all, err := ioutil.ReadAll(r.Body)
1172- if err != nil {
1173- t.Fatalf("handler ReadAll: %v", err)
1174- }
1175- if len(all) != 0 {
1176- t.Errorf("handler got %d bytes; expected 0", len(all))
1177- }
1178- rw.Header().Set("Content-Length", "0")
1179- }))
1180- defer ts.Close()
1181-
1182- req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
1183- if err != nil {
1184- t.Fatal(err)
1185- }
1186- req.ContentLength = 0
1187-
1188- var resp [5]*Response
1189- for i := range resp {
1190- resp[i], err = DefaultClient.Do(req)
1191- if err != nil {
1192- t.Fatalf("client post #%d: %v", i, err)
1193- }
1194- }
1195-
1196- for i := range resp {
1197- all, err := ioutil.ReadAll(resp[i].Body)
1198- if err != nil {
1199- t.Fatalf("req #%d: client ReadAll: %v", i, err)
1200- }
1201- if len(all) != 0 {
1202- t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
1203- }
1204- }
1205-}
1206-
1207-func TestHandlerPanicNil(t *testing.T) {
1208- testHandlerPanic(t, false, nil)
1209-}
1210-
1211-func TestHandlerPanic(t *testing.T) {
1212- testHandlerPanic(t, false, "intentional death for testing")
1213-}
1214-
1215-func TestHandlerPanicWithHijack(t *testing.T) {
1216- testHandlerPanic(t, true, "intentional death for testing")
1217-}
1218-
1219-func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
1220- defer afterTest(t)
1221- // Unlike the other tests that set the log output to ioutil.Discard
1222- // to quiet the output, this test uses a pipe. The pipe serves three
1223- // purposes:
1224- //
1225- // 1) The log.Print from the http server (generated by the caught
1226- // panic) will go to the pipe instead of stderr, making the
1227- // output quiet.
1228- //
1229- // 2) We read from the pipe to verify that the handler
1230- // actually caught the panic and logged something.
1231- //
1232- // 3) The blocking Read call prevents this TestHandlerPanic
1233- // function from exiting before the HTTP server handler
1234- // finishes crashing. If this text function exited too
1235- // early (and its defer log.SetOutput(os.Stderr) ran),
1236- // then the crash output could spill into the next test.
1237- pr, pw := io.Pipe()
1238- log.SetOutput(pw)
1239- defer log.SetOutput(os.Stderr)
1240- defer pw.Close()
1241-
1242- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1243- if withHijack {
1244- rwc, _, err := w.(Hijacker).Hijack()
1245- if err != nil {
1246- t.Logf("unexpected error: %v", err)
1247- }
1248- defer rwc.Close()
1249- }
1250- panic(panicValue)
1251- }))
1252- defer ts.Close()
1253-
1254- // Do a blocking read on the log output pipe so its logging
1255- // doesn't bleed into the next test. But wait only 5 seconds
1256- // for it.
1257- done := make(chan bool, 1)
1258- go func() {
1259- buf := make([]byte, 4<<10)
1260- _, err := pr.Read(buf)
1261- pr.Close()
1262- if err != nil && err != io.EOF {
1263- t.Error(err)
1264- }
1265- done <- true
1266- }()
1267-
1268- _, err := Get(ts.URL)
1269- if err == nil {
1270- t.Logf("expected an error")
1271- }
1272-
1273- if panicValue == nil {
1274- return
1275- }
1276-
1277- select {
1278- case <-done:
1279- return
1280- case <-time.After(5 * time.Second):
1281- t.Fatal("expected server handler to log an error")
1282- }
1283-}
1284-
1285-func TestNoDate(t *testing.T) {
1286- defer afterTest(t)
1287- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1288- w.Header()["Date"] = nil
1289- }))
1290- defer ts.Close()
1291- res, err := Get(ts.URL)
1292- if err != nil {
1293- t.Fatal(err)
1294- }
1295- _, present := res.Header["Date"]
1296- if present {
1297- t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
1298- }
1299-}
1300-
1301-func TestStripPrefix(t *testing.T) {
1302- defer afterTest(t)
1303- h := HandlerFunc(func(w ResponseWriter, r *Request) {
1304- w.Header().Set("X-Path", r.URL.Path)
1305- })
1306- ts := httptest.NewServer(StripPrefix("/foo", h))
1307- defer ts.Close()
1308-
1309- res, err := Get(ts.URL + "/foo/bar")
1310- if err != nil {
1311- t.Fatal(err)
1312- }
1313- if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
1314- t.Errorf("test 1: got %s, want %s", g, e)
1315- }
1316- res.Body.Close()
1317-
1318- res, err = Get(ts.URL + "/bar")
1319- if err != nil {
1320- t.Fatal(err)
1321- }
1322- if g, e := res.StatusCode, 404; g != e {
1323- t.Errorf("test 2: got status %v, want %v", g, e)
1324- }
1325- res.Body.Close()
1326-}
1327-
1328-func TestRequestLimit(t *testing.T) {
1329- defer afterTest(t)
1330- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1331- t.Fatalf("didn't expect to get request in Handler")
1332- }))
1333- defer ts.Close()
1334- req, _ := NewRequest("GET", ts.URL, nil)
1335- var bytesPerHeader = len("header12345: val12345\r\n")
1336- for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
1337- req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
1338- }
1339- res, err := DefaultClient.Do(req)
1340- if err != nil {
1341- // Some HTTP clients may fail on this undefined behavior (server replying and
1342- // closing the connection while the request is still being written), but
1343- // we do support it (at least currently), so we expect a response below.
1344- t.Fatalf("Do: %v", err)
1345- }
1346- defer res.Body.Close()
1347- if res.StatusCode != 413 {
1348- t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
1349- }
1350-}
1351-
1352 type neverEnding byte
1353
1354 func (b neverEnding) Read(p []byte) (n int, err error) {
1355@@ -1384,1344 +56,3 @@
1356 }
1357 return len(p), nil
1358 }
1359-
1360-type countReader struct {
1361- r io.Reader
1362- n *int64
1363-}
1364-
1365-func (cr countReader) Read(p []byte) (n int, err error) {
1366- n, err = cr.r.Read(p)
1367- atomic.AddInt64(cr.n, int64(n))
1368- return
1369-}
1370-
1371-func TestRequestBodyLimit(t *testing.T) {
1372- defer afterTest(t)
1373- const limit = 1 << 20
1374- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1375- r.Body = MaxBytesReader(w, r.Body, limit)
1376- n, err := io.Copy(ioutil.Discard, r.Body)
1377- if err == nil {
1378- t.Errorf("expected error from io.Copy")
1379- }
1380- if n != limit {
1381- t.Errorf("io.Copy = %d, want %d", n, limit)
1382- }
1383- }))
1384- defer ts.Close()
1385-
1386- nWritten := new(int64)
1387- req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200))
1388-
1389- // Send the POST, but don't care it succeeds or not. The
1390- // remote side is going to reply and then close the TCP
1391- // connection, and HTTP doesn't really define if that's
1392- // allowed or not. Some HTTP clients will get the response
1393- // and some (like ours, currently) will complain that the
1394- // request write failed, without reading the response.
1395- //
1396- // But that's okay, since what we're really testing is that
1397- // the remote side hung up on us before we wrote too much.
1398- _, _ = DefaultClient.Do(req)
1399-
1400- if atomic.LoadInt64(nWritten) > limit*100 {
1401- t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
1402- limit, nWritten)
1403- }
1404-}
1405-
1406-// TestClientWriteShutdown tests that if the client shuts down the write
1407-// side of their TCP connection, the server doesn't send a 400 Bad Request.
1408-func TestClientWriteShutdown(t *testing.T) {
1409- if runtime.GOOS == "plan9" {
1410- t.Skip("skipping test; see http://golang.org/issue/7237")
1411- }
1412- defer afterTest(t)
1413- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
1414- defer ts.Close()
1415- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1416- if err != nil {
1417- t.Fatalf("Dial: %v", err)
1418- }
1419- err = conn.(*net.TCPConn).CloseWrite()
1420- if err != nil {
1421- t.Fatalf("Dial: %v", err)
1422- }
1423- donec := make(chan bool)
1424- go func() {
1425- defer close(donec)
1426- bs, err := ioutil.ReadAll(conn)
1427- if err != nil {
1428- t.Fatalf("ReadAll: %v", err)
1429- }
1430- got := string(bs)
1431- if got != "" {
1432- t.Errorf("read %q from server; want nothing", got)
1433- }
1434- }()
1435- select {
1436- case <-donec:
1437- case <-time.After(10 * time.Second):
1438- t.Fatalf("timeout")
1439- }
1440-}
1441-
1442-// Tests that chunked server responses that write 1 byte at a time are
1443-// buffered before chunk headers are added, not after chunk headers.
1444-func TestServerBufferedChunking(t *testing.T) {
1445- conn := new(testConn)
1446- conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
1447- conn.closec = make(chan bool, 1)
1448- ls := &oneConnListener{conn}
1449- go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
1450- rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length
1451- rw.Write([]byte{'x'})
1452- rw.Write([]byte{'y'})
1453- rw.Write([]byte{'z'})
1454- }))
1455- <-conn.closec
1456- if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
1457- t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
1458- conn.writeBuf.Bytes())
1459- }
1460-}
1461-
1462-// Tests that the server flushes its response headers out when it's
1463-// ignoring the response body and waits a bit before forcefully
1464-// closing the TCP connection, causing the client to get a RST.
1465-// See http://golang.org/issue/3595
1466-func TestServerGracefulClose(t *testing.T) {
1467- defer afterTest(t)
1468- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1469- Error(w, "bye", StatusUnauthorized)
1470- }))
1471- defer ts.Close()
1472-
1473- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1474- if err != nil {
1475- t.Fatal(err)
1476- }
1477- defer conn.Close()
1478- const bodySize = 5 << 20
1479- req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize))
1480- for i := 0; i < bodySize; i++ {
1481- req = append(req, 'x')
1482- }
1483- writeErr := make(chan error)
1484- go func() {
1485- _, err := conn.Write(req)
1486- writeErr <- err
1487- }()
1488- br := bufio.NewReader(conn)
1489- lineNum := 0
1490- for {
1491- line, err := br.ReadString('\n')
1492- if err == io.EOF {
1493- break
1494- }
1495- if err != nil {
1496- t.Fatalf("ReadLine: %v", err)
1497- }
1498- lineNum++
1499- if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") {
1500- t.Errorf("Response line = %q; want a 401", line)
1501- }
1502- }
1503- // Wait for write to finish. This is a broken pipe on both
1504- // Darwin and Linux, but checking this isn't the point of
1505- // the test.
1506- <-writeErr
1507-}
1508-
1509-func TestCaseSensitiveMethod(t *testing.T) {
1510- defer afterTest(t)
1511- ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
1512- if r.Method != "get" {
1513- t.Errorf(`Got method %q; want "get"`, r.Method)
1514- }
1515- }))
1516- defer ts.Close()
1517- req, _ := NewRequest("get", ts.URL, nil)
1518- res, err := DefaultClient.Do(req)
1519- if err != nil {
1520- t.Error(err)
1521- return
1522- }
1523- res.Body.Close()
1524-}
1525-
1526-// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
1527-// request (both keep-alive), when a Handler never writes any
1528-// response, the net/http package adds a "Content-Length: 0" response
1529-// header.
1530-func TestContentLengthZero(t *testing.T) {
1531- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
1532- defer ts.Close()
1533-
1534- for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
1535- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1536- if err != nil {
1537- t.Fatalf("error dialing: %v", err)
1538- }
1539- _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
1540- if err != nil {
1541- t.Fatalf("error writing: %v", err)
1542- }
1543- req, _ := NewRequest("GET", "/", nil)
1544- res, err := ReadResponse(bufio.NewReader(conn), req)
1545- if err != nil {
1546- t.Fatalf("error reading response: %v", err)
1547- }
1548- if te := res.TransferEncoding; len(te) > 0 {
1549- t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
1550- }
1551- if cl := res.ContentLength; cl != 0 {
1552- t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
1553- }
1554- conn.Close()
1555- }
1556-}
1557-
1558-func TestCloseNotifier(t *testing.T) {
1559- defer afterTest(t)
1560- gotReq := make(chan bool, 1)
1561- sawClose := make(chan bool, 1)
1562- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
1563- gotReq <- true
1564- cc := rw.(CloseNotifier).CloseNotify()
1565- <-cc
1566- sawClose <- true
1567- }))
1568- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1569- if err != nil {
1570- t.Fatalf("error dialing: %v", err)
1571- }
1572- diec := make(chan bool)
1573- go func() {
1574- _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n")
1575- if err != nil {
1576- t.Fatal(err)
1577- }
1578- <-diec
1579- conn.Close()
1580- }()
1581-For:
1582- for {
1583- select {
1584- case <-gotReq:
1585- diec <- true
1586- case <-sawClose:
1587- break For
1588- case <-time.After(5 * time.Second):
1589- t.Fatal("timeout")
1590- }
1591- }
1592- ts.Close()
1593-}
1594-
1595-func TestCloseNotifierChanLeak(t *testing.T) {
1596- defer afterTest(t)
1597- req := reqBytes("GET / HTTP/1.0\nHost: golang.org")
1598- for i := 0; i < 20; i++ {
1599- var output bytes.Buffer
1600- conn := &rwTestConn{
1601- Reader: bytes.NewReader(req),
1602- Writer: &output,
1603- closec: make(chan bool, 1),
1604- }
1605- ln := &oneConnListener{conn: conn}
1606- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
1607- // Ignore the return value and never read from
1608- // it, testing that we don't leak goroutines
1609- // on the sending side:
1610- _ = rw.(CloseNotifier).CloseNotify()
1611- })
1612- go Serve(ln, handler)
1613- <-conn.closec
1614- }
1615-}
1616-
1617-func TestOptions(t *testing.T) {
1618- uric := make(chan string, 2) // only expect 1, but leave space for 2
1619- mux := NewServeMux()
1620- mux.HandleFunc("/", func(w ResponseWriter, r *Request) {
1621- uric <- r.RequestURI
1622- })
1623- ts := httptest.NewServer(mux)
1624- defer ts.Close()
1625-
1626- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1627- if err != nil {
1628- t.Fatal(err)
1629- }
1630- defer conn.Close()
1631-
1632- // An OPTIONS * request should succeed.
1633- _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
1634- if err != nil {
1635- t.Fatal(err)
1636- }
1637- br := bufio.NewReader(conn)
1638- res, err := ReadResponse(br, &Request{Method: "OPTIONS"})
1639- if err != nil {
1640- t.Fatal(err)
1641- }
1642- if res.StatusCode != 200 {
1643- t.Errorf("Got non-200 response to OPTIONS *: %#v", res)
1644- }
1645-
1646- // A GET * request on a ServeMux should fail.
1647- _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
1648- if err != nil {
1649- t.Fatal(err)
1650- }
1651- res, err = ReadResponse(br, &Request{Method: "GET"})
1652- if err != nil {
1653- t.Fatal(err)
1654- }
1655- if res.StatusCode != 400 {
1656- t.Errorf("Got non-400 response to GET *: %#v", res)
1657- }
1658-
1659- res, err = Get(ts.URL + "/second")
1660- if err != nil {
1661- t.Fatal(err)
1662- }
1663- res.Body.Close()
1664- if got := <-uric; got != "/second" {
1665- t.Errorf("Handler saw request for %q; want /second", got)
1666- }
1667-}
1668-
1669-// Tests regarding the ordering of Write, WriteHeader, Header, and
1670-// Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the
1671-// (*response).header to the wire. In Go 1.1, the actual wire flush is
1672-// delayed, so we could maybe tack on a Content-Length and better
1673-// Content-Type after we see more (or all) of the output. To preserve
1674-// compatibility with Go 1, we need to be careful to track which
1675-// headers were live at the time of WriteHeader, so we write the same
1676-// ones, even if the handler modifies them (~erroneously) after the
1677-// first Write.
1678-func TestHeaderToWire(t *testing.T) {
1679- tests := []struct {
1680- name string
1681- handler func(ResponseWriter, *Request)
1682- check func(output string) error
1683- }{
1684- {
1685- name: "write without Header",
1686- handler: func(rw ResponseWriter, r *Request) {
1687- rw.Write([]byte("hello world"))
1688- },
1689- check: func(got string) error {
1690- if !strings.Contains(got, "Content-Length:") {
1691- return errors.New("no content-length")
1692- }
1693- if !strings.Contains(got, "Content-Type: text/plain") {
1694- return errors.New("no content-length")
1695- }
1696- return nil
1697- },
1698- },
1699- {
1700- name: "Header mutation before write",
1701- handler: func(rw ResponseWriter, r *Request) {
1702- h := rw.Header()
1703- h.Set("Content-Type", "some/type")
1704- rw.Write([]byte("hello world"))
1705- h.Set("Too-Late", "bogus")
1706- },
1707- check: func(got string) error {
1708- if !strings.Contains(got, "Content-Length:") {
1709- return errors.New("no content-length")
1710- }
1711- if !strings.Contains(got, "Content-Type: some/type") {
1712- return errors.New("wrong content-type")
1713- }
1714- if strings.Contains(got, "Too-Late") {
1715- return errors.New("don't want too-late header")
1716- }
1717- return nil
1718- },
1719- },
1720- {
1721- name: "write then useless Header mutation",
1722- handler: func(rw ResponseWriter, r *Request) {
1723- rw.Write([]byte("hello world"))
1724- rw.Header().Set("Too-Late", "Write already wrote headers")
1725- },
1726- check: func(got string) error {
1727- if strings.Contains(got, "Too-Late") {
1728- return errors.New("header appeared from after WriteHeader")
1729- }
1730- return nil
1731- },
1732- },
1733- {
1734- name: "flush then write",
1735- handler: func(rw ResponseWriter, r *Request) {
1736- rw.(Flusher).Flush()
1737- rw.Write([]byte("post-flush"))
1738- rw.Header().Set("Too-Late", "Write already wrote headers")
1739- },
1740- check: func(got string) error {
1741- if !strings.Contains(got, "Transfer-Encoding: chunked") {
1742- return errors.New("not chunked")
1743- }
1744- if strings.Contains(got, "Too-Late") {
1745- return errors.New("header appeared from after WriteHeader")
1746- }
1747- return nil
1748- },
1749- },
1750- {
1751- name: "header then flush",
1752- handler: func(rw ResponseWriter, r *Request) {
1753- rw.Header().Set("Content-Type", "some/type")
1754- rw.(Flusher).Flush()
1755- rw.Write([]byte("post-flush"))
1756- rw.Header().Set("Too-Late", "Write already wrote headers")
1757- },
1758- check: func(got string) error {
1759- if !strings.Contains(got, "Transfer-Encoding: chunked") {
1760- return errors.New("not chunked")
1761- }
1762- if strings.Contains(got, "Too-Late") {
1763- return errors.New("header appeared from after WriteHeader")
1764- }
1765- if !strings.Contains(got, "Content-Type: some/type") {
1766- return errors.New("wrong content-length")
1767- }
1768- return nil
1769- },
1770- },
1771- {
1772- name: "sniff-on-first-write content-type",
1773- handler: func(rw ResponseWriter, r *Request) {
1774- rw.Write([]byte("<html><head></head><body>some html</body></html>"))
1775- rw.Header().Set("Content-Type", "x/wrong")
1776- },
1777- check: func(got string) error {
1778- if !strings.Contains(got, "Content-Type: text/html") {
1779- return errors.New("wrong content-length; want html")
1780- }
1781- return nil
1782- },
1783- },
1784- {
1785- name: "explicit content-type wins",
1786- handler: func(rw ResponseWriter, r *Request) {
1787- rw.Header().Set("Content-Type", "some/type")
1788- rw.Write([]byte("<html><head></head><body>some html</body></html>"))
1789- },
1790- check: func(got string) error {
1791- if !strings.Contains(got, "Content-Type: some/type") {
1792- return errors.New("wrong content-length; want html")
1793- }
1794- return nil
1795- },
1796- },
1797- {
1798- name: "empty handler",
1799- handler: func(rw ResponseWriter, r *Request) {
1800- },
1801- check: func(got string) error {
1802- if !strings.Contains(got, "Content-Type: text/plain") {
1803- return errors.New("wrong content-length; want text/plain")
1804- }
1805- if !strings.Contains(got, "Content-Length: 0") {
1806- return errors.New("want 0 content-length")
1807- }
1808- return nil
1809- },
1810- },
1811- {
1812- name: "only Header, no write",
1813- handler: func(rw ResponseWriter, r *Request) {
1814- rw.Header().Set("Some-Header", "some-value")
1815- },
1816- check: func(got string) error {
1817- if !strings.Contains(got, "Some-Header") {
1818- return errors.New("didn't get header")
1819- }
1820- return nil
1821- },
1822- },
1823- {
1824- name: "WriteHeader call",
1825- handler: func(rw ResponseWriter, r *Request) {
1826- rw.WriteHeader(404)
1827- rw.Header().Set("Too-Late", "some-value")
1828- },
1829- check: func(got string) error {
1830- if !strings.Contains(got, "404") {
1831- return errors.New("wrong status")
1832- }
1833- if strings.Contains(got, "Some-Header") {
1834- return errors.New("shouldn't have seen Too-Late")
1835- }
1836- return nil
1837- },
1838- },
1839- }
1840- for _, tc := range tests {
1841- ht := newHandlerTest(HandlerFunc(tc.handler))
1842- got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org")
1843- if err := tc.check(got); err != nil {
1844- t.Errorf("%s: %v\nGot response:\n%s", tc.name, err, got)
1845- }
1846- }
1847-}
1848-
1849-// goTimeout runs f, failing t if f takes more than ns to complete.
1850-func goTimeout(t *testing.T, d time.Duration, f func()) {
1851- ch := make(chan bool, 2)
1852- timer := time.AfterFunc(d, func() {
1853- t.Errorf("Timeout expired after %v", d)
1854- ch <- true
1855- })
1856- defer timer.Stop()
1857- go func() {
1858- defer func() { ch <- true }()
1859- f()
1860- }()
1861- <-ch
1862-}
1863-
1864-type errorListener struct {
1865- errs []error
1866-}
1867-
1868-func (l *errorListener) Accept() (c net.Conn, err error) {
1869- if len(l.errs) == 0 {
1870- return nil, io.EOF
1871- }
1872- err = l.errs[0]
1873- l.errs = l.errs[1:]
1874- return
1875-}
1876-
1877-func (l *errorListener) Close() error {
1878- return nil
1879-}
1880-
1881-func (l *errorListener) Addr() net.Addr {
1882- return dummyAddr("test-address")
1883-}
1884-
1885-func TestAcceptMaxFds(t *testing.T) {
1886- log.SetOutput(ioutil.Discard) // is noisy otherwise
1887- defer log.SetOutput(os.Stderr)
1888-
1889- ln := &errorListener{[]error{
1890- &net.OpError{
1891- Op: "accept",
1892- Err: syscall.EMFILE,
1893- }}}
1894- err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
1895- if err != io.EOF {
1896- t.Errorf("got error %v, want EOF", err)
1897- }
1898-}
1899-
1900-func TestWriteAfterHijack(t *testing.T) {
1901- req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
1902- var buf bytes.Buffer
1903- wrotec := make(chan bool, 1)
1904- conn := &rwTestConn{
1905- Reader: bytes.NewReader(req),
1906- Writer: &buf,
1907- closec: make(chan bool, 1),
1908- }
1909- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
1910- conn, bufrw, err := rw.(Hijacker).Hijack()
1911- if err != nil {
1912- t.Error(err)
1913- return
1914- }
1915- go func() {
1916- bufrw.Write([]byte("[hijack-to-bufw]"))
1917- bufrw.Flush()
1918- conn.Write([]byte("[hijack-to-conn]"))
1919- conn.Close()
1920- wrotec <- true
1921- }()
1922- })
1923- ln := &oneConnListener{conn: conn}
1924- go Serve(ln, handler)
1925- <-conn.closec
1926- <-wrotec
1927- if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w {
1928- t.Errorf("wrote %q; want %q", g, w)
1929- }
1930-}
1931-
1932-func TestDoubleHijack(t *testing.T) {
1933- req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
1934- var buf bytes.Buffer
1935- conn := &rwTestConn{
1936- Reader: bytes.NewReader(req),
1937- Writer: &buf,
1938- closec: make(chan bool, 1),
1939- }
1940- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
1941- conn, _, err := rw.(Hijacker).Hijack()
1942- if err != nil {
1943- t.Error(err)
1944- return
1945- }
1946- _, _, err = rw.(Hijacker).Hijack()
1947- if err == nil {
1948- t.Errorf("got err = nil; want err != nil")
1949- }
1950- conn.Close()
1951- })
1952- ln := &oneConnListener{conn: conn}
1953- go Serve(ln, handler)
1954- <-conn.closec
1955-}
1956-
1957-// http://code.google.com/p/go/issues/detail?id=5955
1958-// Note that this does not test the "request too large"
1959-// exit path from the http server. This is intentional;
1960-// not sending Connection: close is just a minor wire
1961-// optimization and is pointless if dealing with a
1962-// badly behaved client.
1963-func TestHTTP10ConnectionHeader(t *testing.T) {
1964- defer afterTest(t)
1965-
1966- mux := NewServeMux()
1967- mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {}))
1968- ts := httptest.NewServer(mux)
1969- defer ts.Close()
1970-
1971- // net/http uses HTTP/1.1 for requests, so write requests manually
1972- tests := []struct {
1973- req string // raw http request
1974- expect []string // expected Connection header(s)
1975- }{
1976- {
1977- req: "GET / HTTP/1.0\r\n\r\n",
1978- expect: nil,
1979- },
1980- {
1981- req: "OPTIONS * HTTP/1.0\r\n\r\n",
1982- expect: nil,
1983- },
1984- {
1985- req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n",
1986- expect: []string{"keep-alive"},
1987- },
1988- }
1989-
1990- for _, tt := range tests {
1991- conn, err := net.Dial("tcp", ts.Listener.Addr().String())
1992- if err != nil {
1993- t.Fatal("dial err:", err)
1994- }
1995-
1996- _, err = fmt.Fprint(conn, tt.req)
1997- if err != nil {
1998- t.Fatal("conn write err:", err)
1999- }
2000-
2001- resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"})
2002- if err != nil {
2003- t.Fatal("ReadResponse err:", err)
2004- }
2005- conn.Close()
2006- resp.Body.Close()
2007-
2008- got := resp.Header["Connection"]
2009- if !reflect.DeepEqual(got, tt.expect) {
2010- t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect)
2011- }
2012- }
2013-}
2014-
2015-// See golang.org/issue/5660
2016-func TestServerReaderFromOrder(t *testing.T) {
2017- defer afterTest(t)
2018- pr, pw := io.Pipe()
2019- const size = 3 << 20
2020- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
2021- rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
2022- done := make(chan bool)
2023- go func() {
2024- io.Copy(rw, pr)
2025- close(done)
2026- }()
2027- time.Sleep(25 * time.Millisecond) // give Copy a chance to break things
2028- n, err := io.Copy(ioutil.Discard, req.Body)
2029- if err != nil {
2030- t.Errorf("handler Copy: %v", err)
2031- return
2032- }
2033- if n != size {
2034- t.Errorf("handler Copy = %d; want %d", n, size)
2035- }
2036- pw.Write([]byte("hi"))
2037- pw.Close()
2038- <-done
2039- }))
2040- defer ts.Close()
2041-
2042- req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size))
2043- if err != nil {
2044- t.Fatal(err)
2045- }
2046- res, err := DefaultClient.Do(req)
2047- if err != nil {
2048- t.Fatal(err)
2049- }
2050- all, err := ioutil.ReadAll(res.Body)
2051- if err != nil {
2052- t.Fatal(err)
2053- }
2054- res.Body.Close()
2055- if string(all) != "hi" {
2056- t.Errorf("Body = %q; want hi", all)
2057- }
2058-}
2059-
2060-// Issue 6157, Issue 6685
2061-func TestCodesPreventingContentTypeAndBody(t *testing.T) {
2062- for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} {
2063- ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
2064- if r.URL.Path == "/header" {
2065- w.Header().Set("Content-Length", "123")
2066- }
2067- w.WriteHeader(code)
2068- if r.URL.Path == "/more" {
2069- w.Write([]byte("stuff"))
2070- }
2071- }))
2072- for _, req := range []string{
2073- "GET / HTTP/1.0",
2074- "GET /header HTTP/1.0",
2075- "GET /more HTTP/1.0",
2076- "GET / HTTP/1.1",
2077- "GET /header HTTP/1.1",
2078- "GET /more HTTP/1.1",
2079- } {
2080- got := ht.rawResponse(req)
2081- wantStatus := fmt.Sprintf("%d %s", code, StatusText(code))
2082- if !strings.Contains(got, wantStatus) {
2083- t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, req, got)
2084- } else if strings.Contains(got, "Content-Length") {
2085- t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got)
2086- } else if strings.Contains(got, "stuff") {
2087- t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got)
2088- }
2089- }
2090- }
2091-}
2092-
2093-// Issue 6995
2094-// A server Handler can receive a Request, and then turn around and
2095-// give a copy of that Request.Body out to the Transport (e.g. any
2096-// proxy). So then two people own that Request.Body (both the server
2097-// and the http client), and both think they can close it on failure.
2098-// Therefore, all incoming server requests Bodies need to be thread-safe.
2099-func TestTransportAndServerSharedBodyRace(t *testing.T) {
2100- defer afterTest(t)
2101-
2102- const bodySize = 1 << 20
2103-
2104- unblockBackend := make(chan bool)
2105- backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
2106- io.CopyN(rw, req.Body, bodySize/2)
2107- <-unblockBackend
2108- }))
2109- defer backend.Close()
2110-
2111- backendRespc := make(chan *Response, 1)
2112- proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
2113- if req.RequestURI == "/foo" {
2114- rw.Write([]byte("bar"))
2115- return
2116- }
2117- req2, _ := NewRequest("POST", backend.URL, req.Body)
2118- req2.ContentLength = bodySize
2119-
2120- bresp, err := DefaultClient.Do(req2)
2121- if err != nil {
2122- t.Errorf("Proxy outbound request: %v", err)
2123- return
2124- }
2125- _, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/4)
2126- if err != nil {
2127- t.Errorf("Proxy copy error: %v", err)
2128- return
2129- }
2130- backendRespc <- bresp // to close later
2131-
2132- // Try to cause a race: Both the DefaultTransport and the proxy handler's Server
2133- // will try to read/close req.Body (aka req2.Body)
2134- DefaultTransport.(*Transport).CancelRequest(req2)
2135- rw.Write([]byte("OK"))
2136- }))
2137- defer proxy.Close()
2138-
2139- req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize))
2140- res, err := DefaultClient.Do(req)
2141- if err != nil {
2142- t.Fatalf("Original request: %v", err)
2143- }
2144-
2145- // Cleanup, so we don't leak goroutines.
2146- res.Body.Close()
2147- close(unblockBackend)
2148- (<-backendRespc).Body.Close()
2149-}
2150-
2151-// Test that a hanging Request.Body.Read from another goroutine can't
2152-// cause the Handler goroutine's Request.Body.Close to block.
2153-func TestRequestBodyCloseDoesntBlock(t *testing.T) {
2154- t.Skipf("Skipping known issue; see golang.org/issue/7121")
2155- if testing.Short() {
2156- t.Skip("skipping in -short mode")
2157- }
2158- defer afterTest(t)
2159-
2160- readErrCh := make(chan error, 1)
2161- errCh := make(chan error, 2)
2162-
2163- server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
2164- go func(body io.Reader) {
2165- _, err := body.Read(make([]byte, 100))
2166- readErrCh <- err
2167- }(req.Body)
2168- time.Sleep(500 * time.Millisecond)
2169- }))
2170- defer server.Close()
2171-
2172- closeConn := make(chan bool)
2173- defer close(closeConn)
2174- go func() {
2175- conn, err := net.Dial("tcp", server.Listener.Addr().String())
2176- if err != nil {
2177- errCh <- err
2178- return
2179- }
2180- defer conn.Close()
2181- _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n"))
2182- if err != nil {
2183- errCh <- err
2184- return
2185- }
2186- // And now just block, making the server block on our
2187- // 100000 bytes of body that will never arrive.
2188- <-closeConn
2189- }()
2190- select {
2191- case err := <-readErrCh:
2192- if err == nil {
2193- t.Error("Read was nil. Expected error.")
2194- }
2195- case err := <-errCh:
2196- t.Error(err)
2197- case <-time.After(5 * time.Second):
2198- t.Error("timeout")
2199- }
2200-}
2201-
2202-func TestResponseWriterWriteStringAllocs(t *testing.T) {
2203- ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
2204- if r.URL.Path == "/s" {
2205- io.WriteString(w, "Hello world")
2206- } else {
2207- w.Write([]byte("Hello world"))
2208- }
2209- }))
2210- before := testing.AllocsPerRun(50, func() { ht.rawResponse("GET / HTTP/1.0") })
2211- after := testing.AllocsPerRun(50, func() { ht.rawResponse("GET /s HTTP/1.0") })
2212- if int(after) >= int(before) {
2213- t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before)
2214- }
2215-}
2216-
2217-func TestAppendTime(t *testing.T) {
2218- var b [len(TimeFormat)]byte
2219- t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60))
2220- res := ExportAppendTime(b[:0], t1)
2221- t2, err := ParseTime(string(res))
2222- if err != nil {
2223- t.Fatalf("Error parsing time: %s", err)
2224- }
2225- if !t1.Equal(t2) {
2226- t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res))
2227- }
2228-}
2229-
2230-func TestServerConnState(t *testing.T) {
2231- defer afterTest(t)
2232- handler := map[string]func(w ResponseWriter, r *Request){
2233- "/": func(w ResponseWriter, r *Request) {
2234- fmt.Fprintf(w, "Hello.")
2235- },
2236- "/close": func(w ResponseWriter, r *Request) {
2237- w.Header().Set("Connection", "close")
2238- fmt.Fprintf(w, "Hello.")
2239- },
2240- "/hijack": func(w ResponseWriter, r *Request) {
2241- c, _, _ := w.(Hijacker).Hijack()
2242- c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
2243- c.Close()
2244- },
2245- "/hijack-panic": func(w ResponseWriter, r *Request) {
2246- c, _, _ := w.(Hijacker).Hijack()
2247- c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
2248- c.Close()
2249- panic("intentional panic")
2250- },
2251- }
2252- ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
2253- handler[r.URL.Path](w, r)
2254- }))
2255- defer ts.Close()
2256-
2257- var mu sync.Mutex // guard stateLog and connID
2258- var stateLog = map[int][]ConnState{}
2259- var connID = map[net.Conn]int{}
2260-
2261- ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
2262- ts.Config.ConnState = func(c net.Conn, state ConnState) {
2263- if c == nil {
2264- t.Error("nil conn seen in state %s", state)
2265- return
2266- }
2267- mu.Lock()
2268- defer mu.Unlock()
2269- id, ok := connID[c]
2270- if !ok {
2271- id = len(connID) + 1
2272- connID[c] = id
2273- }
2274- stateLog[id] = append(stateLog[id], state)
2275- }
2276- ts.Start()
2277-
2278- mustGet(t, ts.URL+"/")
2279- mustGet(t, ts.URL+"/close")
2280-
2281- mustGet(t, ts.URL+"/")
2282- mustGet(t, ts.URL+"/", "Connection", "close")
2283-
2284- mustGet(t, ts.URL+"/hijack")
2285- mustGet(t, ts.URL+"/hijack-panic")
2286-
2287- // New->Closed
2288- {
2289- c, err := net.Dial("tcp", ts.Listener.Addr().String())
2290- if err != nil {
2291- t.Fatal(err)
2292- }
2293- c.Close()
2294- }
2295-
2296- // New->Active->Closed
2297- {
2298- c, err := net.Dial("tcp", ts.Listener.Addr().String())
2299- if err != nil {
2300- t.Fatal(err)
2301- }
2302- if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil {
2303- t.Fatal(err)
2304- }
2305- c.Close()
2306- }
2307-
2308- // New->Idle->Closed
2309- {
2310- c, err := net.Dial("tcp", ts.Listener.Addr().String())
2311- if err != nil {
2312- t.Fatal(err)
2313- }
2314- if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil {
2315- t.Fatal(err)
2316- }
2317- res, err := ReadResponse(bufio.NewReader(c), nil)
2318- if err != nil {
2319- t.Fatal(err)
2320- }
2321- if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
2322- t.Fatal(err)
2323- }
2324- c.Close()
2325- }
2326-
2327- want := map[int][]ConnState{
2328- 1: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed},
2329- 2: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed},
2330- 3: []ConnState{StateNew, StateActive, StateHijacked},
2331- 4: []ConnState{StateNew, StateActive, StateHijacked},
2332- 5: []ConnState{StateNew, StateClosed},
2333- 6: []ConnState{StateNew, StateActive, StateClosed},
2334- 7: []ConnState{StateNew, StateActive, StateIdle, StateClosed},
2335- }
2336- logString := func(m map[int][]ConnState) string {
2337- var b bytes.Buffer
2338- for id, l := range m {
2339- fmt.Fprintf(&b, "Conn %d: ", id)
2340- for _, s := range l {
2341- fmt.Fprintf(&b, "%s ", s)
2342- }
2343- b.WriteString("\n")
2344- }
2345- return b.String()
2346- }
2347-
2348- for i := 0; i < 5; i++ {
2349- time.Sleep(time.Duration(i) * 50 * time.Millisecond)
2350- mu.Lock()
2351- match := reflect.DeepEqual(stateLog, want)
2352- mu.Unlock()
2353- if match {
2354- return
2355- }
2356- }
2357-
2358- mu.Lock()
2359- t.Errorf("Unexpected events.\nGot log: %s\n Want: %s\n", logString(stateLog), logString(want))
2360- mu.Unlock()
2361-}
2362-
2363-func mustGet(t *testing.T, url string, headers ...string) {
2364- req, err := NewRequest("GET", url, nil)
2365- if err != nil {
2366- t.Fatal(err)
2367- }
2368- for len(headers) > 0 {
2369- req.Header.Add(headers[0], headers[1])
2370- headers = headers[2:]
2371- }
2372- res, err := DefaultClient.Do(req)
2373- if err != nil {
2374- t.Errorf("Error fetching %s: %v", url, err)
2375- return
2376- }
2377- _, err = ioutil.ReadAll(res.Body)
2378- defer res.Body.Close()
2379- if err != nil {
2380- t.Errorf("Error reading %s: %v", url, err)
2381- }
2382-}
2383-
2384-func TestServerKeepAlivesEnabled(t *testing.T) {
2385- defer afterTest(t)
2386- ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
2387- ts.Config.SetKeepAlivesEnabled(false)
2388- ts.Start()
2389- defer ts.Close()
2390- res, err := Get(ts.URL)
2391- if err != nil {
2392- t.Fatal(err)
2393- }
2394- defer res.Body.Close()
2395- if !res.Close {
2396- t.Errorf("Body.Close == false; want true")
2397- }
2398-}
2399-
2400-func TestServerConnStateNew(t *testing.T) {
2401- sawNew := false // if the test is buggy, we'll race on this variable.
2402- srv := &Server{
2403- ConnState: func(c net.Conn, state ConnState) {
2404- if state == StateNew {
2405- sawNew = true // testing that this write isn't racy
2406- }
2407- },
2408- Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant
2409- }
2410- srv.Serve(&oneConnListener{
2411- conn: &rwTestConn{
2412- Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"),
2413- Writer: ioutil.Discard,
2414- },
2415- })
2416- if !sawNew { // testing that this read isn't racy
2417- t.Error("StateNew not seen")
2418- }
2419-}
2420-
2421-func BenchmarkClientServer(b *testing.B) {
2422- b.ReportAllocs()
2423- b.StopTimer()
2424- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
2425- fmt.Fprintf(rw, "Hello world.\n")
2426- }))
2427- defer ts.Close()
2428- b.StartTimer()
2429-
2430- for i := 0; i < b.N; i++ {
2431- res, err := Get(ts.URL)
2432- if err != nil {
2433- b.Fatal("Get:", err)
2434- }
2435- all, err := ioutil.ReadAll(res.Body)
2436- res.Body.Close()
2437- if err != nil {
2438- b.Fatal("ReadAll:", err)
2439- }
2440- body := string(all)
2441- if body != "Hello world.\n" {
2442- b.Fatal("Got body:", body)
2443- }
2444- }
2445-
2446- b.StopTimer()
2447-}
2448-
2449-// A benchmark for profiling the server without the HTTP client code.
2450-// The client code runs in a subprocess.
2451-//
2452-// For use like:
2453-// $ go test -c
2454-// $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof
2455-// $ go tool pprof http.test http.prof
2456-// (pprof) web
2457-func BenchmarkServer(b *testing.B) {
2458- b.ReportAllocs()
2459- // Child process mode;
2460- if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
2461- n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
2462- if err != nil {
2463- panic(err)
2464- }
2465- for i := 0; i < n; i++ {
2466- res, err := Get(url)
2467- if err != nil {
2468- log.Panicf("Get: %v", err)
2469- }
2470- all, err := ioutil.ReadAll(res.Body)
2471- res.Body.Close()
2472- if err != nil {
2473- log.Panicf("ReadAll: %v", err)
2474- }
2475- body := string(all)
2476- if body != "Hello world.\n" {
2477- log.Panicf("Got body: %q", body)
2478- }
2479- }
2480- os.Exit(0)
2481- return
2482- }
2483-
2484- var res = []byte("Hello world.\n")
2485- b.StopTimer()
2486- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
2487- rw.Header().Set("Content-Type", "text/html; charset=utf-8")
2488- rw.Write(res)
2489- }))
2490- defer ts.Close()
2491- b.StartTimer()
2492-
2493- cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
2494- cmd.Env = append([]string{
2495- fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
2496- fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
2497- }, os.Environ()...)
2498- out, err := cmd.CombinedOutput()
2499- if err != nil {
2500- b.Errorf("Test failure: %v, with output: %s", err, out)
2501- }
2502-}
2503-
2504-func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) {
2505- b.ReportAllocs()
2506- req := reqBytes(`GET / HTTP/1.0
2507-Host: golang.org
2508-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2509-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
2510-Accept-Encoding: gzip,deflate,sdch
2511-Accept-Language: en-US,en;q=0.8
2512-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
2513-`)
2514- res := []byte("Hello world!\n")
2515-
2516- conn := &testConn{
2517- // testConn.Close will not push into the channel
2518- // if it's full.
2519- closec: make(chan bool, 1),
2520- }
2521- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
2522- rw.Header().Set("Content-Type", "text/html; charset=utf-8")
2523- rw.Write(res)
2524- })
2525- ln := new(oneConnListener)
2526- for i := 0; i < b.N; i++ {
2527- conn.readBuf.Reset()
2528- conn.writeBuf.Reset()
2529- conn.readBuf.Write(req)
2530- ln.conn = conn
2531- Serve(ln, handler)
2532- <-conn.closec
2533- }
2534-}
2535-
2536-// repeatReader reads content count times, then EOFs.
2537-type repeatReader struct {
2538- content []byte
2539- count int
2540- off int
2541-}
2542-
2543-func (r *repeatReader) Read(p []byte) (n int, err error) {
2544- if r.count <= 0 {
2545- return 0, io.EOF
2546- }
2547- n = copy(p, r.content[r.off:])
2548- r.off += n
2549- if r.off == len(r.content) {
2550- r.count--
2551- r.off = 0
2552- }
2553- return
2554-}
2555-
2556-func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) {
2557- b.ReportAllocs()
2558-
2559- req := reqBytes(`GET / HTTP/1.1
2560-Host: golang.org
2561-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2562-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
2563-Accept-Encoding: gzip,deflate,sdch
2564-Accept-Language: en-US,en;q=0.8
2565-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
2566-`)
2567- res := []byte("Hello world!\n")
2568-
2569- conn := &rwTestConn{
2570- Reader: &repeatReader{content: req, count: b.N},
2571- Writer: ioutil.Discard,
2572- closec: make(chan bool, 1),
2573- }
2574- handled := 0
2575- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
2576- handled++
2577- rw.Header().Set("Content-Type", "text/html; charset=utf-8")
2578- rw.Write(res)
2579- })
2580- ln := &oneConnListener{conn: conn}
2581- go Serve(ln, handler)
2582- <-conn.closec
2583- if b.N != handled {
2584- b.Errorf("b.N=%d but handled %d", b.N, handled)
2585- }
2586-}
2587-
2588-// same as above, but representing the most simple possible request
2589-// and handler. Notably: the handler does not call rw.Header().
2590-func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) {
2591- b.ReportAllocs()
2592-
2593- req := reqBytes(`GET / HTTP/1.1
2594-Host: golang.org
2595-`)
2596- res := []byte("Hello world!\n")
2597-
2598- conn := &rwTestConn{
2599- Reader: &repeatReader{content: req, count: b.N},
2600- Writer: ioutil.Discard,
2601- closec: make(chan bool, 1),
2602- }
2603- handled := 0
2604- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
2605- handled++
2606- rw.Write(res)
2607- })
2608- ln := &oneConnListener{conn: conn}
2609- go Serve(ln, handler)
2610- <-conn.closec
2611- if b.N != handled {
2612- b.Errorf("b.N=%d but handled %d", b.N, handled)
2613- }
2614-}
2615-
2616-const someResponse = "<html>some response</html>"
2617-
2618-// A Response that's just no bigger than 2KB, the buffer-before-chunking threshold.
2619-var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse))
2620-
2621-// Both Content-Type and Content-Length set. Should be no buffering.
2622-func BenchmarkServerHandlerTypeLen(b *testing.B) {
2623- benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
2624- w.Header().Set("Content-Type", "text/html")
2625- w.Header().Set("Content-Length", strconv.Itoa(len(response)))
2626- w.Write(response)
2627- }))
2628-}
2629-
2630-// A Content-Type is set, but no length. No sniffing, but will count the Content-Length.
2631-func BenchmarkServerHandlerNoLen(b *testing.B) {
2632- benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
2633- w.Header().Set("Content-Type", "text/html")
2634- w.Write(response)
2635- }))
2636-}
2637-
2638-// A Content-Length is set, but the Content-Type will be sniffed.
2639-func BenchmarkServerHandlerNoType(b *testing.B) {
2640- benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
2641- w.Header().Set("Content-Length", strconv.Itoa(len(response)))
2642- w.Write(response)
2643- }))
2644-}
2645-
2646-// Neither a Content-Type or Content-Length, so sniffed and counted.
2647-func BenchmarkServerHandlerNoHeader(b *testing.B) {
2648- benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
2649- w.Write(response)
2650- }))
2651-}
2652-
2653-func benchmarkHandler(b *testing.B, h Handler) {
2654- b.ReportAllocs()
2655- req := reqBytes(`GET / HTTP/1.1
2656-Host: golang.org
2657-`)
2658- conn := &rwTestConn{
2659- Reader: &repeatReader{content: req, count: b.N},
2660- Writer: ioutil.Discard,
2661- closec: make(chan bool, 1),
2662- }
2663- handled := 0
2664- handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
2665- handled++
2666- h.ServeHTTP(rw, r)
2667- })
2668- ln := &oneConnListener{conn: conn}
2669- go Serve(ln, handler)
2670- <-conn.closec
2671- if b.N != handled {
2672- b.Errorf("b.N=%d but handled %d", b.N, handled)
2673- }
2674-}
2675-
2676-func BenchmarkServerHijack(b *testing.B) {
2677- b.ReportAllocs()
2678- req := reqBytes(`GET / HTTP/1.1
2679-Host: golang.org
2680-`)
2681- h := HandlerFunc(func(w ResponseWriter, r *Request) {
2682- conn, _, err := w.(Hijacker).Hijack()
2683- if err != nil {
2684- panic(err)
2685- }
2686- conn.Close()
2687- })
2688- conn := &rwTestConn{
2689- Writer: ioutil.Discard,
2690- closec: make(chan bool, 1),
2691- }
2692- ln := &oneConnListener{conn: conn}
2693- for i := 0; i < b.N; i++ {
2694- conn.Reader = bytes.NewReader(req)
2695- ln.conn = conn
2696- Serve(ln, h)
2697- <-conn.closec
2698- }
2699-}
2700
2701=== modified file 'http13client/server.go'
2702--- http13client/server.go 2014-03-19 20:20:19 +0000
2703+++ http13client/server.go 2014-03-19 22:27:37 +0000
2704@@ -2,1984 +2,17 @@
2705 // Use of this source code is governed by a BSD-style
2706 // license that can be found in the LICENSE file.
2707
2708-// HTTP server. See RFC 2616.
2709-
2710 package http
2711
2712 import (
2713- "bufio"
2714- "crypto/tls"
2715- "errors"
2716 "fmt"
2717 "io"
2718 "io/ioutil"
2719 "log"
2720 "net"
2721- "net/url"
2722- "os"
2723- "path"
2724- "runtime"
2725- "strconv"
2726 "strings"
2727 "sync"
2728- "sync/atomic"
2729- "time"
2730-)
2731-
2732-// Errors introduced by the HTTP server.
2733-var (
2734- ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
2735- ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
2736- ErrHijacked = errors.New("Conn has been hijacked")
2737- ErrContentLength = errors.New("Conn.Write wrote more than the declared Content-Length")
2738-)
2739-
2740-// Objects implementing the Handler interface can be
2741-// registered to serve a particular path or subtree
2742-// in the HTTP server.
2743-//
2744-// ServeHTTP should write reply headers and data to the ResponseWriter
2745-// and then return. Returning signals that the request is finished
2746-// and that the HTTP server can move on to the next request on
2747-// the connection.
2748-type Handler interface {
2749- ServeHTTP(ResponseWriter, *Request)
2750-}
2751-
2752-// A ResponseWriter interface is used by an HTTP handler to
2753-// construct an HTTP response.
2754-type ResponseWriter interface {
2755- // Header returns the header map that will be sent by WriteHeader.
2756- // Changing the header after a call to WriteHeader (or Write) has
2757- // no effect.
2758- Header() Header
2759-
2760- // Write writes the data to the connection as part of an HTTP reply.
2761- // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
2762- // before writing the data. If the Header does not contain a
2763- // Content-Type line, Write adds a Content-Type set to the result of passing
2764- // the initial 512 bytes of written data to DetectContentType.
2765- Write([]byte) (int, error)
2766-
2767- // WriteHeader sends an HTTP response header with status code.
2768- // If WriteHeader is not called explicitly, the first call to Write
2769- // will trigger an implicit WriteHeader(http.StatusOK).
2770- // Thus explicit calls to WriteHeader are mainly used to
2771- // send error codes.
2772- WriteHeader(int)
2773-}
2774-
2775-// The Flusher interface is implemented by ResponseWriters that allow
2776-// an HTTP handler to flush buffered data to the client.
2777-//
2778-// Note that even for ResponseWriters that support Flush,
2779-// if the client is connected through an HTTP proxy,
2780-// the buffered data may not reach the client until the response
2781-// completes.
2782-type Flusher interface {
2783- // Flush sends any buffered data to the client.
2784- Flush()
2785-}
2786-
2787-// The Hijacker interface is implemented by ResponseWriters that allow
2788-// an HTTP handler to take over the connection.
2789-type Hijacker interface {
2790- // Hijack lets the caller take over the connection.
2791- // After a call to Hijack(), the HTTP server library
2792- // will not do anything else with the connection.
2793- // It becomes the caller's responsibility to manage
2794- // and close the connection.
2795- Hijack() (net.Conn, *bufio.ReadWriter, error)
2796-}
2797-
2798-// The CloseNotifier interface is implemented by ResponseWriters which
2799-// allow detecting when the underlying connection has gone away.
2800-//
2801-// This mechanism can be used to cancel long operations on the server
2802-// if the client has disconnected before the response is ready.
2803-type CloseNotifier interface {
2804- // CloseNotify returns a channel that receives a single value
2805- // when the client connection has gone away.
2806- CloseNotify() <-chan bool
2807-}
2808-
2809-// A conn represents the server side of an HTTP connection.
2810-type conn struct {
2811- remoteAddr string // network address of remote side
2812- server *Server // the Server on which the connection arrived
2813- rwc net.Conn // i/o connection
2814- sr liveSwitchReader // where the LimitReader reads from; usually the rwc
2815- lr *io.LimitedReader // io.LimitReader(sr)
2816- buf *bufio.ReadWriter // buffered(lr,rwc), reading from bufio->limitReader->sr->rwc
2817- tlsState *tls.ConnectionState // or nil when not using TLS
2818-
2819- mu sync.Mutex // guards the following
2820- clientGone bool // if client has disconnected mid-request
2821- closeNotifyc chan bool // made lazily
2822- hijackedv bool // connection has been hijacked by handler
2823-}
2824-
2825-func (c *conn) hijacked() bool {
2826- c.mu.Lock()
2827- defer c.mu.Unlock()
2828- return c.hijackedv
2829-}
2830-
2831-func (c *conn) hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
2832- c.mu.Lock()
2833- defer c.mu.Unlock()
2834- if c.hijackedv {
2835- return nil, nil, ErrHijacked
2836- }
2837- if c.closeNotifyc != nil {
2838- return nil, nil, errors.New("http: Hijack is incompatible with use of CloseNotifier")
2839- }
2840- c.hijackedv = true
2841- rwc = c.rwc
2842- buf = c.buf
2843- c.rwc = nil
2844- c.buf = nil
2845- c.setState(rwc, StateHijacked)
2846- return
2847-}
2848-
2849-func (c *conn) closeNotify() <-chan bool {
2850- c.mu.Lock()
2851- defer c.mu.Unlock()
2852- if c.closeNotifyc == nil {
2853- c.closeNotifyc = make(chan bool, 1)
2854- if c.hijackedv {
2855- // to obey the function signature, even though
2856- // it'll never receive a value.
2857- return c.closeNotifyc
2858- }
2859- pr, pw := io.Pipe()
2860-
2861- readSource := c.sr.r
2862- c.sr.Lock()
2863- c.sr.r = pr
2864- c.sr.Unlock()
2865- go func() {
2866- _, err := io.Copy(pw, readSource)
2867- if err == nil {
2868- err = io.EOF
2869- }
2870- pw.CloseWithError(err)
2871- c.noteClientGone()
2872- }()
2873- }
2874- return c.closeNotifyc
2875-}
2876-
2877-func (c *conn) noteClientGone() {
2878- c.mu.Lock()
2879- defer c.mu.Unlock()
2880- if c.closeNotifyc != nil && !c.clientGone {
2881- c.closeNotifyc <- true
2882- }
2883- c.clientGone = true
2884-}
2885-
2886-// A switchReader can have its Reader changed at runtime.
2887-// It's not safe for concurrent Reads and switches.
2888-type switchReader struct {
2889- io.Reader
2890-}
2891-
2892-// A switchWriter can have its Writer changed at runtime.
2893-// It's not safe for concurrent Writes and switches.
2894-type switchWriter struct {
2895- io.Writer
2896-}
2897-
2898-// A liveSwitchReader is a switchReader that's safe for concurrent
2899-// reads and switches, if its mutex is held.
2900-type liveSwitchReader struct {
2901- sync.Mutex
2902- r io.Reader
2903-}
2904-
2905-func (sr *liveSwitchReader) Read(p []byte) (n int, err error) {
2906- sr.Lock()
2907- r := sr.r
2908- sr.Unlock()
2909- return r.Read(p)
2910-}
2911-
2912-// This should be >= 512 bytes for DetectContentType,
2913-// but otherwise it's somewhat arbitrary.
2914-const bufferBeforeChunkingSize = 2048
2915-
2916-// chunkWriter writes to a response's conn buffer, and is the writer
2917-// wrapped by the response.bufw buffered writer.
2918-//
2919-// chunkWriter also is responsible for finalizing the Header, including
2920-// conditionally setting the Content-Type and setting a Content-Length
2921-// in cases where the handler's final output is smaller than the buffer
2922-// size. It also conditionally adds chunk headers, when in chunking mode.
2923-//
2924-// See the comment above (*response).Write for the entire write flow.
2925-type chunkWriter struct {
2926- res *response
2927-
2928- // header is either nil or a deep clone of res.handlerHeader
2929- // at the time of res.WriteHeader, if res.WriteHeader is
2930- // called and extra buffering is being done to calculate
2931- // Content-Type and/or Content-Length.
2932- header Header
2933-
2934- // wroteHeader tells whether the header's been written to "the
2935- // wire" (or rather: w.conn.buf). this is unlike
2936- // (*response).wroteHeader, which tells only whether it was
2937- // logically written.
2938- wroteHeader bool
2939-
2940- // set by the writeHeader method:
2941- chunking bool // using chunked transfer encoding for reply body
2942-}
2943-
2944-var (
2945- crlf = []byte("\r\n")
2946- colonSpace = []byte(": ")
2947-)
2948-
2949-func (cw *chunkWriter) Write(p []byte) (n int, err error) {
2950- if !cw.wroteHeader {
2951- cw.writeHeader(p)
2952- }
2953- if cw.res.req.Method == "HEAD" {
2954- // Eat writes.
2955- return len(p), nil
2956- }
2957- if cw.chunking {
2958- _, err = fmt.Fprintf(cw.res.conn.buf, "%x\r\n", len(p))
2959- if err != nil {
2960- cw.res.conn.rwc.Close()
2961- return
2962- }
2963- }
2964- n, err = cw.res.conn.buf.Write(p)
2965- if cw.chunking && err == nil {
2966- _, err = cw.res.conn.buf.Write(crlf)
2967- }
2968- if err != nil {
2969- cw.res.conn.rwc.Close()
2970- }
2971- return
2972-}
2973-
2974-func (cw *chunkWriter) flush() {
2975- if !cw.wroteHeader {
2976- cw.writeHeader(nil)
2977- }
2978- cw.res.conn.buf.Flush()
2979-}
2980-
2981-func (cw *chunkWriter) close() {
2982- if !cw.wroteHeader {
2983- cw.writeHeader(nil)
2984- }
2985- if cw.chunking {
2986- // zero EOF chunk, trailer key/value pairs (currently
2987- // unsupported in Go's server), followed by a blank
2988- // line.
2989- cw.res.conn.buf.WriteString("0\r\n\r\n")
2990- }
2991-}
2992-
2993-// A response represents the server side of an HTTP response.
2994-type response struct {
2995- conn *conn
2996- req *Request // request for this response
2997- wroteHeader bool // reply header has been (logically) written
2998- wroteContinue bool // 100 Continue response was written
2999-
3000- w *bufio.Writer // buffers output in chunks to chunkWriter
3001- cw chunkWriter
3002- sw *switchWriter // of the bufio.Writer, for return to putBufioWriter
3003-
3004- // handlerHeader is the Header that Handlers get access to,
3005- // which may be retained and mutated even after WriteHeader.
3006- // handlerHeader is copied into cw.header at WriteHeader
3007- // time, and privately mutated thereafter.
3008- handlerHeader Header
3009- calledHeader bool // handler accessed handlerHeader via Header
3010-
3011- written int64 // number of bytes written in body
3012- contentLength int64 // explicitly-declared Content-Length; or -1
3013- status int // status code passed to WriteHeader
3014-
3015- // close connection after this reply. set on request and
3016- // updated after response from handler if there's a
3017- // "Connection: keep-alive" response header and a
3018- // Content-Length.
3019- closeAfterReply bool
3020-
3021- // requestBodyLimitHit is set by requestTooLarge when
3022- // maxBytesReader hits its max size. It is checked in
3023- // WriteHeader, to make sure we don't consume the
3024- // remaining request body to try to advance to the next HTTP
3025- // request. Instead, when this is set, we stop reading
3026- // subsequent requests on this connection and stop reading
3027- // input from it.
3028- requestBodyLimitHit bool
3029-
3030- handlerDone bool // set true when the handler exits
3031-
3032- // Buffers for Date and Content-Length
3033- dateBuf [len(TimeFormat)]byte
3034- clenBuf [10]byte
3035-}
3036-
3037-// requestTooLarge is called by maxBytesReader when too much input has
3038-// been read from the client.
3039-func (w *response) requestTooLarge() {
3040- w.closeAfterReply = true
3041- w.requestBodyLimitHit = true
3042- if !w.wroteHeader {
3043- w.Header().Set("Connection", "close")
3044- }
3045-}
3046-
3047-// needsSniff reports whether a Content-Type still needs to be sniffed.
3048-func (w *response) needsSniff() bool {
3049- _, haveType := w.handlerHeader["Content-Type"]
3050- return !w.cw.wroteHeader && !haveType && w.written < sniffLen
3051-}
3052-
3053-// writerOnly hides an io.Writer value's optional ReadFrom method
3054-// from io.Copy.
3055-type writerOnly struct {
3056- io.Writer
3057-}
3058-
3059-func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
3060- switch v := src.(type) {
3061- case *os.File:
3062- fi, err := v.Stat()
3063- if err != nil {
3064- return false, err
3065- }
3066- return fi.Mode().IsRegular(), nil
3067- case *io.LimitedReader:
3068- return srcIsRegularFile(v.R)
3069- default:
3070- return
3071- }
3072-}
3073-
3074-// ReadFrom is here to optimize copying from an *os.File regular file
3075-// to a *net.TCPConn with sendfile.
3076-func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
3077- // Our underlying w.conn.rwc is usually a *TCPConn (with its
3078- // own ReadFrom method). If not, or if our src isn't a regular
3079- // file, just fall back to the normal copy method.
3080- rf, ok := w.conn.rwc.(io.ReaderFrom)
3081- regFile, err := srcIsRegularFile(src)
3082- if err != nil {
3083- return 0, err
3084- }
3085- if !ok || !regFile {
3086- return io.Copy(writerOnly{w}, src)
3087- }
3088-
3089- // sendfile path:
3090-
3091- if !w.wroteHeader {
3092- w.WriteHeader(StatusOK)
3093- }
3094-
3095- if w.needsSniff() {
3096- n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
3097- n += n0
3098- if err != nil {
3099- return n, err
3100- }
3101- }
3102-
3103- w.w.Flush() // get rid of any previous writes
3104- w.cw.flush() // make sure Header is written; flush data to rwc
3105-
3106- // Now that cw has been flushed, its chunking field is guaranteed initialized.
3107- if !w.cw.chunking && w.bodyAllowed() {
3108- n0, err := rf.ReadFrom(src)
3109- n += n0
3110- w.written += n0
3111- return n, err
3112- }
3113-
3114- n0, err := io.Copy(writerOnly{w}, src)
3115- n += n0
3116- return n, err
3117-}
3118-
3119-// noLimit is an effective infinite upper bound for io.LimitedReader
3120-const noLimit int64 = (1 << 63) - 1
3121-
3122-// debugServerConnections controls whether all server connections are wrapped
3123-// with a verbose logging wrapper.
3124-const debugServerConnections = false
3125-
3126-// Create new connection from rwc.
3127-func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
3128- c = new(conn)
3129- c.remoteAddr = rwc.RemoteAddr().String()
3130- c.server = srv
3131- c.rwc = rwc
3132- if debugServerConnections {
3133- c.rwc = newLoggingConn("server", c.rwc)
3134- }
3135- c.sr = liveSwitchReader{r: c.rwc}
3136- c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader)
3137- br := newBufioReader(c.lr)
3138- bw := newBufioWriterSize(c.rwc, 4<<10)
3139- c.buf = bufio.NewReadWriter(br, bw)
3140- return c, nil
3141-}
3142-
3143-// TODO: use a sync.Cache instead
3144-var (
3145- bufioReaderCache = make(chan *bufio.Reader, 4)
3146- bufioWriterCache2k = make(chan *bufio.Writer, 4)
3147- bufioWriterCache4k = make(chan *bufio.Writer, 4)
3148-)
3149-
3150-func bufioWriterCache(size int) chan *bufio.Writer {
3151- switch size {
3152- case 2 << 10:
3153- return bufioWriterCache2k
3154- case 4 << 10:
3155- return bufioWriterCache4k
3156- }
3157- return nil
3158-}
3159-
3160-func newBufioReader(r io.Reader) *bufio.Reader {
3161- select {
3162- case p := <-bufioReaderCache:
3163- p.Reset(r)
3164- return p
3165- default:
3166- return bufio.NewReader(r)
3167- }
3168-}
3169-
3170-func putBufioReader(br *bufio.Reader) {
3171- br.Reset(nil)
3172- select {
3173- case bufioReaderCache <- br:
3174- default:
3175- }
3176-}
3177-
3178-func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
3179- select {
3180- case p := <-bufioWriterCache(size):
3181- p.Reset(w)
3182- return p
3183- default:
3184- return bufio.NewWriterSize(w, size)
3185- }
3186-}
3187-
3188-func putBufioWriter(bw *bufio.Writer) {
3189- bw.Reset(nil)
3190- select {
3191- case bufioWriterCache(bw.Available()) <- bw:
3192- default:
3193- }
3194-}
3195-
3196-// DefaultMaxHeaderBytes is the maximum permitted size of the headers
3197-// in an HTTP request.
3198-// This can be overridden by setting Server.MaxHeaderBytes.
3199-const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
3200-
3201-func (srv *Server) maxHeaderBytes() int {
3202- if srv.MaxHeaderBytes > 0 {
3203- return srv.MaxHeaderBytes
3204- }
3205- return DefaultMaxHeaderBytes
3206-}
3207-
3208-func (srv *Server) initialLimitedReaderSize() int64 {
3209- return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
3210-}
3211-
3212-// wrapper around io.ReaderCloser which on first read, sends an
3213-// HTTP/1.1 100 Continue header
3214-type expectContinueReader struct {
3215- resp *response
3216- readCloser io.ReadCloser
3217- closed bool
3218-}
3219-
3220-func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
3221- if ecr.closed {
3222- return 0, ErrBodyReadAfterClose
3223- }
3224- if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() {
3225- ecr.resp.wroteContinue = true
3226- ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
3227- ecr.resp.conn.buf.Flush()
3228- }
3229- return ecr.readCloser.Read(p)
3230-}
3231-
3232-func (ecr *expectContinueReader) Close() error {
3233- ecr.closed = true
3234- return ecr.readCloser.Close()
3235-}
3236-
3237-// TimeFormat is the time format to use with
3238-// time.Parse and time.Time.Format when parsing
3239-// or generating times in HTTP headers.
3240-// It is like time.RFC1123 but hard codes GMT as the time zone.
3241-const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
3242-
3243-// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
3244-func appendTime(b []byte, t time.Time) []byte {
3245- const days = "SunMonTueWedThuFriSat"
3246- const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
3247-
3248- t = t.UTC()
3249- yy, mm, dd := t.Date()
3250- hh, mn, ss := t.Clock()
3251- day := days[3*t.Weekday():]
3252- mon := months[3*(mm-1):]
3253-
3254- return append(b,
3255- day[0], day[1], day[2], ',', ' ',
3256- byte('0'+dd/10), byte('0'+dd%10), ' ',
3257- mon[0], mon[1], mon[2], ' ',
3258- byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
3259- byte('0'+hh/10), byte('0'+hh%10), ':',
3260- byte('0'+mn/10), byte('0'+mn%10), ':',
3261- byte('0'+ss/10), byte('0'+ss%10), ' ',
3262- 'G', 'M', 'T')
3263-}
3264-
3265-var errTooLarge = errors.New("http: request too large")
3266-
3267-// Read next request from connection.
3268-func (c *conn) readRequest() (w *response, err error) {
3269- if c.hijacked() {
3270- return nil, ErrHijacked
3271- }
3272-
3273- if d := c.server.ReadTimeout; d != 0 {
3274- c.rwc.SetReadDeadline(time.Now().Add(d))
3275- }
3276- if d := c.server.WriteTimeout; d != 0 {
3277- defer func() {
3278- c.rwc.SetWriteDeadline(time.Now().Add(d))
3279- }()
3280- }
3281-
3282- c.lr.N = c.server.initialLimitedReaderSize()
3283- var req *Request
3284- if req, err = ReadRequest(c.buf.Reader); err != nil {
3285- if c.lr.N == 0 {
3286- return nil, errTooLarge
3287- }
3288- return nil, err
3289- }
3290- c.lr.N = noLimit
3291-
3292- req.RemoteAddr = c.remoteAddr
3293- req.TLS = c.tlsState
3294-
3295- w = &response{
3296- conn: c,
3297- req: req,
3298- handlerHeader: make(Header),
3299- contentLength: -1,
3300- }
3301- w.cw.res = w
3302- w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
3303- return w, nil
3304-}
3305-
3306-func (w *response) Header() Header {
3307- if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
3308- // Accessing the header between logically writing it
3309- // and physically writing it means we need to allocate
3310- // a clone to snapshot the logically written state.
3311- w.cw.header = w.handlerHeader.clone()
3312- }
3313- w.calledHeader = true
3314- return w.handlerHeader
3315-}
3316-
3317-// maxPostHandlerReadBytes is the max number of Request.Body bytes not
3318-// consumed by a handler that the server will read from the client
3319-// in order to keep a connection alive. If there are more bytes than
3320-// this then the server to be paranoid instead sends a "Connection:
3321-// close" response.
3322-//
3323-// This number is approximately what a typical machine's TCP buffer
3324-// size is anyway. (if we have the bytes on the machine, we might as
3325-// well read them)
3326-const maxPostHandlerReadBytes = 256 << 10
3327-
3328-func (w *response) WriteHeader(code int) {
3329- if w.conn.hijacked() {
3330- w.conn.server.logf("http: response.WriteHeader on hijacked connection")
3331- return
3332- }
3333- if w.wroteHeader {
3334- w.conn.server.logf("http: multiple response.WriteHeader calls")
3335- return
3336- }
3337- w.wroteHeader = true
3338- w.status = code
3339-
3340- if w.calledHeader && w.cw.header == nil {
3341- w.cw.header = w.handlerHeader.clone()
3342- }
3343-
3344- if cl := w.handlerHeader.get("Content-Length"); cl != "" {
3345- v, err := strconv.ParseInt(cl, 10, 64)
3346- if err == nil && v >= 0 {
3347- w.contentLength = v
3348- } else {
3349- w.conn.server.logf("http: invalid Content-Length of %q", cl)
3350- w.handlerHeader.Del("Content-Length")
3351- }
3352- }
3353-}
3354-
3355-// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
3356-// This type is used to avoid extra allocations from cloning and/or populating
3357-// the response Header map and all its 1-element slices.
3358-type extraHeader struct {
3359- contentType string
3360- connection string
3361- transferEncoding string
3362- date []byte // written if not nil
3363- contentLength []byte // written if not nil
3364-}
3365-
3366-// Sorted the same as extraHeader.Write's loop.
3367-var extraHeaderKeys = [][]byte{
3368- []byte("Content-Type"),
3369- []byte("Connection"),
3370- []byte("Transfer-Encoding"),
3371-}
3372-
3373-var (
3374- headerContentLength = []byte("Content-Length: ")
3375- headerDate = []byte("Date: ")
3376-)
3377-
3378-// Write writes the headers described in h to w.
3379-//
3380-// This method has a value receiver, despite the somewhat large size
3381-// of h, because it prevents an allocation. The escape analysis isn't
3382-// smart enough to realize this function doesn't mutate h.
3383-func (h extraHeader) Write(w *bufio.Writer) {
3384- if h.date != nil {
3385- w.Write(headerDate)
3386- w.Write(h.date)
3387- w.Write(crlf)
3388- }
3389- if h.contentLength != nil {
3390- w.Write(headerContentLength)
3391- w.Write(h.contentLength)
3392- w.Write(crlf)
3393- }
3394- for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
3395- if v != "" {
3396- w.Write(extraHeaderKeys[i])
3397- w.Write(colonSpace)
3398- w.WriteString(v)
3399- w.Write(crlf)
3400- }
3401- }
3402-}
3403-
3404-// writeHeader finalizes the header sent to the client and writes it
3405-// to cw.res.conn.buf.
3406-//
3407-// p is not written by writeHeader, but is the first chunk of the body
3408-// that will be written. It is sniffed for a Content-Type if none is
3409-// set explicitly. It's also used to set the Content-Length, if the
3410-// total body size was small and the handler has already finished
3411-// running.
3412-func (cw *chunkWriter) writeHeader(p []byte) {
3413- if cw.wroteHeader {
3414- return
3415- }
3416- cw.wroteHeader = true
3417-
3418- w := cw.res
3419- keepAlivesEnabled := w.conn.server.doKeepAlives()
3420- isHEAD := w.req.Method == "HEAD"
3421-
3422- // header is written out to w.conn.buf below. Depending on the
3423- // state of the handler, we either own the map or not. If we
3424- // don't own it, the exclude map is created lazily for
3425- // WriteSubset to remove headers. The setHeader struct holds
3426- // headers we need to add.
3427- header := cw.header
3428- owned := header != nil
3429- if !owned {
3430- header = w.handlerHeader
3431- }
3432- var excludeHeader map[string]bool
3433- delHeader := func(key string) {
3434- if owned {
3435- header.Del(key)
3436- return
3437- }
3438- if _, ok := header[key]; !ok {
3439- return
3440- }
3441- if excludeHeader == nil {
3442- excludeHeader = make(map[string]bool)
3443- }
3444- excludeHeader[key] = true
3445- }
3446- var setHeader extraHeader
3447-
3448- // If the handler is done but never sent a Content-Length
3449- // response header and this is our first (and last) write, set
3450- // it, even to zero. This helps HTTP/1.0 clients keep their
3451- // "keep-alive" connections alive.
3452- // Exceptions: 304/204/1xx responses never get Content-Length, and if
3453- // it was a HEAD request, we don't know the difference between
3454- // 0 actual bytes and 0 bytes because the handler noticed it
3455- // was a HEAD request and chose not to write anything. So for
3456- // HEAD, the handler should either write the Content-Length or
3457- // write non-zero bytes. If it's actually 0 bytes and the
3458- // handler never looked at the Request.Method, we just don't
3459- // send a Content-Length header.
3460- if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
3461- w.contentLength = int64(len(p))
3462- setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
3463- }
3464-
3465- // If this was an HTTP/1.0 request with keep-alive and we sent a
3466- // Content-Length back, we can make this a keep-alive response ...
3467- if w.req.wantsHttp10KeepAlive() && keepAlivesEnabled {
3468- sentLength := header.get("Content-Length") != ""
3469- if sentLength && header.get("Connection") == "keep-alive" {
3470- w.closeAfterReply = false
3471- }
3472- }
3473-
3474- // Check for a explicit (and valid) Content-Length header.
3475- hasCL := w.contentLength != -1
3476-
3477- if w.req.wantsHttp10KeepAlive() && (isHEAD || hasCL) {
3478- _, connectionHeaderSet := header["Connection"]
3479- if !connectionHeaderSet {
3480- setHeader.connection = "keep-alive"
3481- }
3482- } else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() {
3483- w.closeAfterReply = true
3484- }
3485-
3486- if header.get("Connection") == "close" || !keepAlivesEnabled {
3487- w.closeAfterReply = true
3488- }
3489-
3490- // Per RFC 2616, we should consume the request body before
3491- // replying, if the handler hasn't already done so. But we
3492- // don't want to do an unbounded amount of reading here for
3493- // DoS reasons, so we only try up to a threshold.
3494- if w.req.ContentLength != 0 && !w.closeAfterReply {
3495- ecr, isExpecter := w.req.Body.(*expectContinueReader)
3496- if !isExpecter || ecr.resp.wroteContinue {
3497- n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
3498- if n >= maxPostHandlerReadBytes {
3499- w.requestTooLarge()
3500- delHeader("Connection")
3501- setHeader.connection = "close"
3502- } else {
3503- w.req.Body.Close()
3504- }
3505- }
3506- }
3507-
3508- code := w.status
3509- if !bodyAllowedForStatus(code) {
3510- // Must not have body.
3511- // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers"
3512- for _, k := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} {
3513- delHeader(k)
3514- }
3515- } else {
3516- // If no content type, apply sniffing algorithm to body.
3517- _, haveType := header["Content-Type"]
3518- if !haveType {
3519- setHeader.contentType = DetectContentType(p)
3520- }
3521- }
3522-
3523- if _, ok := header["Date"]; !ok {
3524- setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
3525- }
3526-
3527- te := header.get("Transfer-Encoding")
3528- hasTE := te != ""
3529- if hasCL && hasTE && te != "identity" {
3530- // TODO: return an error if WriteHeader gets a return parameter
3531- // For now just ignore the Content-Length.
3532- w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
3533- te, w.contentLength)
3534- delHeader("Content-Length")
3535- hasCL = false
3536- }
3537-
3538- if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
3539- // do nothing
3540- } else if code == StatusNoContent {
3541- delHeader("Transfer-Encoding")
3542- } else if hasCL {
3543- delHeader("Transfer-Encoding")
3544- } else if w.req.ProtoAtLeast(1, 1) {
3545- // HTTP/1.1 or greater: use chunked transfer encoding
3546- // to avoid closing the connection at EOF.
3547- // TODO: this blows away any custom or stacked Transfer-Encoding they
3548- // might have set. Deal with that as need arises once we have a valid
3549- // use case.
3550- cw.chunking = true
3551- setHeader.transferEncoding = "chunked"
3552- } else {
3553- // HTTP version < 1.1: cannot do chunked transfer
3554- // encoding and we don't know the Content-Length so
3555- // signal EOF by closing connection.
3556- w.closeAfterReply = true
3557- delHeader("Transfer-Encoding") // in case already set
3558- }
3559-
3560- // Cannot use Content-Length with non-identity Transfer-Encoding.
3561- if cw.chunking {
3562- delHeader("Content-Length")
3563- }
3564- if !w.req.ProtoAtLeast(1, 0) {
3565- return
3566- }
3567-
3568- if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) {
3569- delHeader("Connection")
3570- if w.req.ProtoAtLeast(1, 1) {
3571- setHeader.connection = "close"
3572- }
3573- }
3574-
3575- w.conn.buf.WriteString(statusLine(w.req, code))
3576- cw.header.WriteSubset(w.conn.buf, excludeHeader)
3577- setHeader.Write(w.conn.buf.Writer)
3578- w.conn.buf.Write(crlf)
3579-}
3580-
3581-// statusLines is a cache of Status-Line strings, keyed by code (for
3582-// HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a
3583-// map keyed by struct of two fields. This map's max size is bounded
3584-// by 2*len(statusText), two protocol types for each known official
3585-// status code in the statusText map.
3586-var (
3587- statusMu sync.RWMutex
3588- statusLines = make(map[int]string)
3589-)
3590-
3591-// statusLine returns a response Status-Line (RFC 2616 Section 6.1)
3592-// for the given request and response status code.
3593-func statusLine(req *Request, code int) string {
3594- // Fast path:
3595- key := code
3596- proto11 := req.ProtoAtLeast(1, 1)
3597- if !proto11 {
3598- key = -key
3599- }
3600- statusMu.RLock()
3601- line, ok := statusLines[key]
3602- statusMu.RUnlock()
3603- if ok {
3604- return line
3605- }
3606-
3607- // Slow path:
3608- proto := "HTTP/1.0"
3609- if proto11 {
3610- proto = "HTTP/1.1"
3611- }
3612- codestring := strconv.Itoa(code)
3613- text, ok := statusText[code]
3614- if !ok {
3615- text = "status code " + codestring
3616- }
3617- line = proto + " " + codestring + " " + text + "\r\n"
3618- if ok {
3619- statusMu.Lock()
3620- defer statusMu.Unlock()
3621- statusLines[key] = line
3622- }
3623- return line
3624-}
3625-
3626-// bodyAllowed returns true if a Write is allowed for this response type.
3627-// It's illegal to call this before the header has been flushed.
3628-func (w *response) bodyAllowed() bool {
3629- if !w.wroteHeader {
3630- panic("")
3631- }
3632- return bodyAllowedForStatus(w.status)
3633-}
3634-
3635-// The Life Of A Write is like this:
3636-//
3637-// Handler starts. No header has been sent. The handler can either
3638-// write a header, or just start writing. Writing before sending a header
3639-// sends an implicitly empty 200 OK header.
3640-//
3641-// If the handler didn't declare a Content-Length up front, we either
3642-// go into chunking mode or, if the handler finishes running before
3643-// the chunking buffer size, we compute a Content-Length and send that
3644-// in the header instead.
3645-//
3646-// Likewise, if the handler didn't set a Content-Type, we sniff that
3647-// from the initial chunk of output.
3648-//
3649-// The Writers are wired together like:
3650-//
3651-// 1. *response (the ResponseWriter) ->
3652-// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
3653-// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
3654-// and which writes the chunk headers, if needed.
3655-// 4. conn.buf, a bufio.Writer of default (4kB) bytes
3656-// 5. the rwc, the net.Conn.
3657-//
3658-// TODO(bradfitz): short-circuit some of the buffering when the
3659-// initial header contains both a Content-Type and Content-Length.
3660-// Also short-circuit in (1) when the header's been sent and not in
3661-// chunking mode, writing directly to (4) instead, if (2) has no
3662-// buffered data. More generally, we could short-circuit from (1) to
3663-// (3) even in chunking mode if the write size from (1) is over some
3664-// threshold and nothing is in (2). The answer might be mostly making
3665-// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
3666-// with this instead.
3667-func (w *response) Write(data []byte) (n int, err error) {
3668- return w.write(len(data), data, "")
3669-}
3670-
3671-func (w *response) WriteString(data string) (n int, err error) {
3672- return w.write(len(data), nil, data)
3673-}
3674-
3675-// either dataB or dataS is non-zero.
3676-func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
3677- if w.conn.hijacked() {
3678- w.conn.server.logf("http: response.Write on hijacked connection")
3679- return 0, ErrHijacked
3680- }
3681- if !w.wroteHeader {
3682- w.WriteHeader(StatusOK)
3683- }
3684- if lenData == 0 {
3685- return 0, nil
3686- }
3687- if !w.bodyAllowed() {
3688- return 0, ErrBodyNotAllowed
3689- }
3690-
3691- w.written += int64(lenData) // ignoring errors, for errorKludge
3692- if w.contentLength != -1 && w.written > w.contentLength {
3693- return 0, ErrContentLength
3694- }
3695- if dataB != nil {
3696- return w.w.Write(dataB)
3697- } else {
3698- return w.w.WriteString(dataS)
3699- }
3700-}
3701-
3702-func (w *response) finishRequest() {
3703- w.handlerDone = true
3704-
3705- if !w.wroteHeader {
3706- w.WriteHeader(StatusOK)
3707- }
3708-
3709- w.w.Flush()
3710- putBufioWriter(w.w)
3711- w.cw.close()
3712- w.conn.buf.Flush()
3713-
3714- // Close the body (regardless of w.closeAfterReply) so we can
3715- // re-use its bufio.Reader later safely.
3716- w.req.Body.Close()
3717-
3718- if w.req.MultipartForm != nil {
3719- w.req.MultipartForm.RemoveAll()
3720- }
3721-
3722- if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
3723- // Did not write enough. Avoid getting out of sync.
3724- w.closeAfterReply = true
3725- }
3726-}
3727-
3728-func (w *response) Flush() {
3729- if !w.wroteHeader {
3730- w.WriteHeader(StatusOK)
3731- }
3732- w.w.Flush()
3733- w.cw.flush()
3734-}
3735-
3736-func (c *conn) finalFlush() {
3737- if c.buf != nil {
3738- c.buf.Flush()
3739-
3740- // Steal the bufio.Reader (~4KB worth of memory) and its associated
3741- // reader for a future connection.
3742- putBufioReader(c.buf.Reader)
3743-
3744- // Steal the bufio.Writer (~4KB worth of memory) and its associated
3745- // writer for a future connection.
3746- putBufioWriter(c.buf.Writer)
3747-
3748- c.buf = nil
3749- }
3750-}
3751-
3752-// Close the connection.
3753-func (c *conn) close() {
3754- c.finalFlush()
3755- if c.rwc != nil {
3756- c.rwc.Close()
3757- c.rwc = nil
3758- }
3759-}
3760-
3761-// rstAvoidanceDelay is the amount of time we sleep after closing the
3762-// write side of a TCP connection before closing the entire socket.
3763-// By sleeping, we increase the chances that the client sees our FIN
3764-// and processes its final data before they process the subsequent RST
3765-// from closing a connection with known unread data.
3766-// This RST seems to occur mostly on BSD systems. (And Windows?)
3767-// This timeout is somewhat arbitrary (~latency around the planet).
3768-const rstAvoidanceDelay = 500 * time.Millisecond
3769-
3770-// closeWrite flushes any outstanding data and sends a FIN packet (if
3771-// client is connected via TCP), signalling that we're done. We then
3772-// pause for a bit, hoping the client processes it before `any
3773-// subsequent RST.
3774-//
3775-// See http://golang.org/issue/3595
3776-func (c *conn) closeWriteAndWait() {
3777- c.finalFlush()
3778- if tcp, ok := c.rwc.(*net.TCPConn); ok {
3779- tcp.CloseWrite()
3780- }
3781- time.Sleep(rstAvoidanceDelay)
3782-}
3783-
3784-// validNPN reports whether the proto is not a blacklisted Next
3785-// Protocol Negotiation protocol. Empty and built-in protocol types
3786-// are blacklisted and can't be overridden with alternate
3787-// implementations.
3788-func validNPN(proto string) bool {
3789- switch proto {
3790- case "", "http/1.1", "http/1.0":
3791- return false
3792- }
3793- return true
3794-}
3795-
3796-func (c *conn) setState(nc net.Conn, state ConnState) {
3797- if hook := c.server.ConnState; hook != nil {
3798- hook(nc, state)
3799- }
3800-}
3801-
3802-// Serve a new connection.
3803-func (c *conn) serve() {
3804- origConn := c.rwc // copy it before it's set nil on Close or Hijack
3805- defer func() {
3806- if err := recover(); err != nil {
3807- const size = 64 << 10
3808- buf := make([]byte, size)
3809- buf = buf[:runtime.Stack(buf, false)]
3810- c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
3811- }
3812- if !c.hijacked() {
3813- c.close()
3814- c.setState(origConn, StateClosed)
3815- }
3816- }()
3817-
3818- if tlsConn, ok := c.rwc.(*tls.Conn); ok {
3819- if d := c.server.ReadTimeout; d != 0 {
3820- c.rwc.SetReadDeadline(time.Now().Add(d))
3821- }
3822- if d := c.server.WriteTimeout; d != 0 {
3823- c.rwc.SetWriteDeadline(time.Now().Add(d))
3824- }
3825- if err := tlsConn.Handshake(); err != nil {
3826- c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
3827- return
3828- }
3829- c.tlsState = new(tls.ConnectionState)
3830- *c.tlsState = tlsConn.ConnectionState()
3831- if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) {
3832- if fn := c.server.TLSNextProto[proto]; fn != nil {
3833- h := initNPNRequest{tlsConn, serverHandler{c.server}}
3834- fn(c.server, tlsConn, h)
3835- }
3836- return
3837- }
3838- }
3839-
3840- for {
3841- w, err := c.readRequest()
3842- if c.lr.N != c.server.initialLimitedReaderSize() {
3843- // If we read any bytes off the wire, we're active.
3844- c.setState(c.rwc, StateActive)
3845- }
3846- if err != nil {
3847- if err == errTooLarge {
3848- // Their HTTP client may or may not be
3849- // able to read this if we're
3850- // responding to them and hanging up
3851- // while they're still writing their
3852- // request. Undefined behavior.
3853- io.WriteString(c.rwc, "HTTP/1.1 413 Request Entity Too Large\r\n\r\n")
3854- c.closeWriteAndWait()
3855- break
3856- } else if err == io.EOF {
3857- break // Don't reply
3858- } else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
3859- break // Don't reply
3860- }
3861- io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\n\r\n")
3862- break
3863- }
3864-
3865- // Expect 100 Continue support
3866- req := w.req
3867- if req.expectsContinue() {
3868- if req.ProtoAtLeast(1, 1) {
3869- // Wrap the Body reader with one that replies on the connection
3870- req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
3871- }
3872- if req.ContentLength == 0 {
3873- w.Header().Set("Connection", "close")
3874- w.WriteHeader(StatusBadRequest)
3875- w.finishRequest()
3876- break
3877- }
3878- req.Header.Del("Expect")
3879- } else if req.Header.get("Expect") != "" {
3880- w.sendExpectationFailed()
3881- break
3882- }
3883-
3884- // HTTP cannot have multiple simultaneous active requests.[*]
3885- // Until the server replies to this request, it can't read another,
3886- // so we might as well run the handler in this goroutine.
3887- // [*] Not strictly true: HTTP pipelining. We could let them all process
3888- // in parallel even if their responses need to be serialized.
3889- serverHandler{c.server}.ServeHTTP(w, w.req)
3890- if c.hijacked() {
3891- return
3892- }
3893- w.finishRequest()
3894- if w.closeAfterReply {
3895- if w.requestBodyLimitHit {
3896- c.closeWriteAndWait()
3897- }
3898- break
3899- }
3900- c.setState(c.rwc, StateIdle)
3901- }
3902-}
3903-
3904-func (w *response) sendExpectationFailed() {
3905- // TODO(bradfitz): let ServeHTTP handlers handle
3906- // requests with non-standard expectation[s]? Seems
3907- // theoretical at best, and doesn't fit into the
3908- // current ServeHTTP model anyway. We'd need to
3909- // make the ResponseWriter an optional
3910- // "ExpectReplier" interface or something.
3911- //
3912- // For now we'll just obey RFC 2616 14.20 which says
3913- // "If a server receives a request containing an
3914- // Expect field that includes an expectation-
3915- // extension that it does not support, it MUST
3916- // respond with a 417 (Expectation Failed) status."
3917- w.Header().Set("Connection", "close")
3918- w.WriteHeader(StatusExpectationFailed)
3919- w.finishRequest()
3920-}
3921-
3922-// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
3923-// and a Hijacker.
3924-func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
3925- if w.wroteHeader {
3926- w.cw.flush()
3927- }
3928- // Release the bufioWriter that writes to the chunk writer, it is not
3929- // used after a connection has been hijacked.
3930- rwc, buf, err = w.conn.hijack()
3931- if err == nil {
3932- putBufioWriter(w.w)
3933- w.w = nil
3934- }
3935- return rwc, buf, err
3936-}
3937-
3938-func (w *response) CloseNotify() <-chan bool {
3939- return w.conn.closeNotify()
3940-}
3941-
3942-// The HandlerFunc type is an adapter to allow the use of
3943-// ordinary functions as HTTP handlers. If f is a function
3944-// with the appropriate signature, HandlerFunc(f) is a
3945-// Handler object that calls f.
3946-type HandlerFunc func(ResponseWriter, *Request)
3947-
3948-// ServeHTTP calls f(w, r).
3949-func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
3950- f(w, r)
3951-}
3952-
3953-// Helper handlers
3954-
3955-// Error replies to the request with the specified error message and HTTP code.
3956-// The error message should be plain text.
3957-func Error(w ResponseWriter, error string, code int) {
3958- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
3959- w.WriteHeader(code)
3960- fmt.Fprintln(w, error)
3961-}
3962-
3963-// NotFound replies to the request with an HTTP 404 not found error.
3964-func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
3965-
3966-// NotFoundHandler returns a simple request handler
3967-// that replies to each request with a ``404 page not found'' reply.
3968-func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
3969-
3970-// StripPrefix returns a handler that serves HTTP requests
3971-// by removing the given prefix from the request URL's Path
3972-// and invoking the handler h. StripPrefix handles a
3973-// request for a path that doesn't begin with prefix by
3974-// replying with an HTTP 404 not found error.
3975-func StripPrefix(prefix string, h Handler) Handler {
3976- if prefix == "" {
3977- return h
3978- }
3979- return HandlerFunc(func(w ResponseWriter, r *Request) {
3980- if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
3981- r.URL.Path = p
3982- h.ServeHTTP(w, r)
3983- } else {
3984- NotFound(w, r)
3985- }
3986- })
3987-}
3988-
3989-// Redirect replies to the request with a redirect to url,
3990-// which may be a path relative to the request path.
3991-func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
3992- if u, err := url.Parse(urlStr); err == nil {
3993- // If url was relative, make absolute by
3994- // combining with request path.
3995- // The browser would probably do this for us,
3996- // but doing it ourselves is more reliable.
3997-
3998- // NOTE(rsc): RFC 2616 says that the Location
3999- // line must be an absolute URI, like
4000- // "http://www.google.com/redirect/",
4001- // not a path like "/redirect/".
4002- // Unfortunately, we don't know what to
4003- // put in the host name section to get the
4004- // client to connect to us again, so we can't
4005- // know the right absolute URI to send back.
4006- // Because of this problem, no one pays attention
4007- // to the RFC; they all send back just a new path.
4008- // So do we.
4009- oldpath := r.URL.Path
4010- if oldpath == "" { // should not happen, but avoid a crash if it does
4011- oldpath = "/"
4012- }
4013- if u.Scheme == "" {
4014- // no leading http://server
4015- if urlStr == "" || urlStr[0] != '/' {
4016- // make relative path absolute
4017- olddir, _ := path.Split(oldpath)
4018- urlStr = olddir + urlStr
4019- }
4020-
4021- var query string
4022- if i := strings.Index(urlStr, "?"); i != -1 {
4023- urlStr, query = urlStr[:i], urlStr[i:]
4024- }
4025-
4026- // clean up but preserve trailing slash
4027- trailing := strings.HasSuffix(urlStr, "/")
4028- urlStr = path.Clean(urlStr)
4029- if trailing && !strings.HasSuffix(urlStr, "/") {
4030- urlStr += "/"
4031- }
4032- urlStr += query
4033- }
4034- }
4035-
4036- w.Header().Set("Location", urlStr)
4037- w.WriteHeader(code)
4038-
4039- // RFC2616 recommends that a short note "SHOULD" be included in the
4040- // response because older user agents may not understand 301/307.
4041- // Shouldn't send the response for POST or HEAD; that leaves GET.
4042- if r.Method == "GET" {
4043- note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
4044- fmt.Fprintln(w, note)
4045- }
4046-}
4047-
4048-var htmlReplacer = strings.NewReplacer(
4049- "&", "&amp;",
4050- "<", "&lt;",
4051- ">", "&gt;",
4052- // "&#34;" is shorter than "&quot;".
4053- `"`, "&#34;",
4054- // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
4055- "'", "&#39;",
4056-)
4057-
4058-func htmlEscape(s string) string {
4059- return htmlReplacer.Replace(s)
4060-}
4061-
4062-// Redirect to a fixed URL
4063-type redirectHandler struct {
4064- url string
4065- code int
4066-}
4067-
4068-func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
4069- Redirect(w, r, rh.url, rh.code)
4070-}
4071-
4072-// RedirectHandler returns a request handler that redirects
4073-// each request it receives to the given url using the given
4074-// status code.
4075-func RedirectHandler(url string, code int) Handler {
4076- return &redirectHandler{url, code}
4077-}
4078-
4079-// ServeMux is an HTTP request multiplexer.
4080-// It matches the URL of each incoming request against a list of registered
4081-// patterns and calls the handler for the pattern that
4082-// most closely matches the URL.
4083-//
4084-// Patterns name fixed, rooted paths, like "/favicon.ico",
4085-// or rooted subtrees, like "/images/" (note the trailing slash).
4086-// Longer patterns take precedence over shorter ones, so that
4087-// if there are handlers registered for both "/images/"
4088-// and "/images/thumbnails/", the latter handler will be
4089-// called for paths beginning "/images/thumbnails/" and the
4090-// former will receive requests for any other paths in the
4091-// "/images/" subtree.
4092-//
4093-// Note that since a pattern ending in a slash names a rooted subtree,
4094-// the pattern "/" matches all paths not matched by other registered
4095-// patterns, not just the URL with Path == "/".
4096-//
4097-// Patterns may optionally begin with a host name, restricting matches to
4098-// URLs on that host only. Host-specific patterns take precedence over
4099-// general patterns, so that a handler might register for the two patterns
4100-// "/codesearch" and "codesearch.google.com/" without also taking over
4101-// requests for "http://www.google.com/".
4102-//
4103-// ServeMux also takes care of sanitizing the URL request path,
4104-// redirecting any request containing . or .. elements to an
4105-// equivalent .- and ..-free URL.
4106-type ServeMux struct {
4107- mu sync.RWMutex
4108- m map[string]muxEntry
4109- hosts bool // whether any patterns contain hostnames
4110-}
4111-
4112-type muxEntry struct {
4113- explicit bool
4114- h Handler
4115- pattern string
4116-}
4117-
4118-// NewServeMux allocates and returns a new ServeMux.
4119-func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }
4120-
4121-// DefaultServeMux is the default ServeMux used by Serve.
4122-var DefaultServeMux = NewServeMux()
4123-
4124-// Does path match pattern?
4125-func pathMatch(pattern, path string) bool {
4126- if len(pattern) == 0 {
4127- // should not happen
4128- return false
4129- }
4130- n := len(pattern)
4131- if pattern[n-1] != '/' {
4132- return pattern == path
4133- }
4134- return len(path) >= n && path[0:n] == pattern
4135-}
4136-
4137-// Return the canonical path for p, eliminating . and .. elements.
4138-func cleanPath(p string) string {
4139- if p == "" {
4140- return "/"
4141- }
4142- if p[0] != '/' {
4143- p = "/" + p
4144- }
4145- np := path.Clean(p)
4146- // path.Clean removes trailing slash except for root;
4147- // put the trailing slash back if necessary.
4148- if p[len(p)-1] == '/' && np != "/" {
4149- np += "/"
4150- }
4151- return np
4152-}
4153-
4154-// Find a handler on a handler map given a path string
4155-// Most-specific (longest) pattern wins
4156-func (mux *ServeMux) match(path string) (h Handler, pattern string) {
4157- var n = 0
4158- for k, v := range mux.m {
4159- if !pathMatch(k, path) {
4160- continue
4161- }
4162- if h == nil || len(k) > n {
4163- n = len(k)
4164- h = v.h
4165- pattern = v.pattern
4166- }
4167- }
4168- return
4169-}
4170-
4171-// Handler returns the handler to use for the given request,
4172-// consulting r.Method, r.Host, and r.URL.Path. It always returns
4173-// a non-nil handler. If the path is not in its canonical form, the
4174-// handler will be an internally-generated handler that redirects
4175-// to the canonical path.
4176-//
4177-// Handler also returns the registered pattern that matches the
4178-// request or, in the case of internally-generated redirects,
4179-// the pattern that will match after following the redirect.
4180-//
4181-// If there is no registered handler that applies to the request,
4182-// Handler returns a ``page not found'' handler and an empty pattern.
4183-func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
4184- if r.Method != "CONNECT" {
4185- if p := cleanPath(r.URL.Path); p != r.URL.Path {
4186- _, pattern = mux.handler(r.Host, p)
4187- url := *r.URL
4188- url.Path = p
4189- return RedirectHandler(url.String(), StatusMovedPermanently), pattern
4190- }
4191- }
4192-
4193- return mux.handler(r.Host, r.URL.Path)
4194-}
4195-
4196-// handler is the main implementation of Handler.
4197-// The path is known to be in canonical form, except for CONNECT methods.
4198-func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
4199- mux.mu.RLock()
4200- defer mux.mu.RUnlock()
4201-
4202- // Host-specific pattern takes precedence over generic ones
4203- if mux.hosts {
4204- h, pattern = mux.match(host + path)
4205- }
4206- if h == nil {
4207- h, pattern = mux.match(path)
4208- }
4209- if h == nil {
4210- h, pattern = NotFoundHandler(), ""
4211- }
4212- return
4213-}
4214-
4215-// ServeHTTP dispatches the request to the handler whose
4216-// pattern most closely matches the request URL.
4217-func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
4218- if r.RequestURI == "*" {
4219- if r.ProtoAtLeast(1, 1) {
4220- w.Header().Set("Connection", "close")
4221- }
4222- w.WriteHeader(StatusBadRequest)
4223- return
4224- }
4225- h, _ := mux.Handler(r)
4226- h.ServeHTTP(w, r)
4227-}
4228-
4229-// Handle registers the handler for the given pattern.
4230-// If a handler already exists for pattern, Handle panics.
4231-func (mux *ServeMux) Handle(pattern string, handler Handler) {
4232- mux.mu.Lock()
4233- defer mux.mu.Unlock()
4234-
4235- if pattern == "" {
4236- panic("http: invalid pattern " + pattern)
4237- }
4238- if handler == nil {
4239- panic("http: nil handler")
4240- }
4241- if mux.m[pattern].explicit {
4242- panic("http: multiple registrations for " + pattern)
4243- }
4244-
4245- mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
4246-
4247- if pattern[0] != '/' {
4248- mux.hosts = true
4249- }
4250-
4251- // Helpful behavior:
4252- // If pattern is /tree/, insert an implicit permanent redirect for /tree.
4253- // It can be overridden by an explicit registration.
4254- n := len(pattern)
4255- if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
4256- // If pattern contains a host name, strip it and use remaining
4257- // path for redirect.
4258- path := pattern
4259- if pattern[0] != '/' {
4260- // In pattern, at least the last character is a '/', so
4261- // strings.Index can't be -1.
4262- path = pattern[strings.Index(pattern, "/"):]
4263- }
4264- mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(path, StatusMovedPermanently), pattern: pattern}
4265- }
4266-}
4267-
4268-// HandleFunc registers the handler function for the given pattern.
4269-func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
4270- mux.Handle(pattern, HandlerFunc(handler))
4271-}
4272-
4273-// Handle registers the handler for the given pattern
4274-// in the DefaultServeMux.
4275-// The documentation for ServeMux explains how patterns are matched.
4276-func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
4277-
4278-// HandleFunc registers the handler function for the given pattern
4279-// in the DefaultServeMux.
4280-// The documentation for ServeMux explains how patterns are matched.
4281-func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
4282- DefaultServeMux.HandleFunc(pattern, handler)
4283-}
4284-
4285-// Serve accepts incoming HTTP connections on the listener l,
4286-// creating a new service goroutine for each. The service goroutines
4287-// read requests and then call handler to reply to them.
4288-// Handler is typically nil, in which case the DefaultServeMux is used.
4289-func Serve(l net.Listener, handler Handler) error {
4290- srv := &Server{Handler: handler}
4291- return srv.Serve(l)
4292-}
4293-
4294-// A Server defines parameters for running an HTTP server.
4295-// The zero value for Server is a valid configuration.
4296-type Server struct {
4297- Addr string // TCP address to listen on, ":http" if empty
4298- Handler Handler // handler to invoke, http.DefaultServeMux if nil
4299- ReadTimeout time.Duration // maximum duration before timing out read of the request
4300- WriteTimeout time.Duration // maximum duration before timing out write of the response
4301- MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0
4302- TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS
4303-
4304- // TLSNextProto optionally specifies a function to take over
4305- // ownership of the provided TLS connection when an NPN
4306- // protocol upgrade has occurred. The map key is the protocol
4307- // name negotiated. The Handler argument should be used to
4308- // handle HTTP requests and will initialize the Request's TLS
4309- // and RemoteAddr if not already set. The connection is
4310- // automatically closed when the function returns.
4311- TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
4312-
4313- // ConnState specifies an optional callback function that is
4314- // called when a client connection changes state. See the
4315- // ConnState type and associated constants for details.
4316- ConnState func(net.Conn, ConnState)
4317-
4318- // ErrorLog specifies an optional logger for errors accepting
4319- // connections and unexpected behavior from handlers.
4320- // If nil, logging goes to os.Stderr via the log package's
4321- // standard logger.
4322- ErrorLog *log.Logger
4323-
4324- disableKeepAlives int32 // accessed atomically.
4325-}
4326-
4327-// A ConnState represents the state of a client connection to a server.
4328-// It's used by the optional Server.ConnState hook.
4329-type ConnState int
4330-
4331-const (
4332- // StateNew represents a new connection that is expected to
4333- // send a request immediately. Connections begin at this
4334- // state and then transition to either StateActive or
4335- // StateClosed.
4336- StateNew ConnState = iota
4337-
4338- // StateActive represents a connection that has read 1 or more
4339- // bytes of a request. The Server.ConnState hook for
4340- // StateActive fires before the request has entered a handler
4341- // and doesn't fire again until the request has been
4342- // handled. After the request is handled, the state
4343- // transitions to StateClosed, StateHijacked, or StateIdle.
4344- StateActive
4345-
4346- // StateIdle represents a connection that has finished
4347- // handling a request and is in the keep-alive state, waiting
4348- // for a new request. Connections transition from StateIdle
4349- // to either StateActive or StateClosed.
4350- StateIdle
4351-
4352- // StateHijacked represents a hijacked connection.
4353- // This is a terminal state. It does not transition to StateClosed.
4354- StateHijacked
4355-
4356- // StateClosed represents a closed connection.
4357- // This is a terminal state. Hijacked connections do not
4358- // transition to StateClosed.
4359- StateClosed
4360-)
4361-
4362-var stateName = map[ConnState]string{
4363- StateNew: "new",
4364- StateActive: "active",
4365- StateIdle: "idle",
4366- StateHijacked: "hijacked",
4367- StateClosed: "closed",
4368-}
4369-
4370-func (c ConnState) String() string {
4371- return stateName[c]
4372-}
4373-
4374-// serverHandler delegates to either the server's Handler or
4375-// DefaultServeMux and also handles "OPTIONS *" requests.
4376-type serverHandler struct {
4377- srv *Server
4378-}
4379-
4380-func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
4381- handler := sh.srv.Handler
4382- if handler == nil {
4383- handler = DefaultServeMux
4384- }
4385- if req.RequestURI == "*" && req.Method == "OPTIONS" {
4386- handler = globalOptionsHandler{}
4387- }
4388- handler.ServeHTTP(rw, req)
4389-}
4390-
4391-// ListenAndServe listens on the TCP network address srv.Addr and then
4392-// calls Serve to handle requests on incoming connections. If
4393-// srv.Addr is blank, ":http" is used.
4394-func (srv *Server) ListenAndServe() error {
4395- addr := srv.Addr
4396- if addr == "" {
4397- addr = ":http"
4398- }
4399- ln, err := net.Listen("tcp", addr)
4400- if err != nil {
4401- return err
4402- }
4403- return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
4404-}
4405-
4406-// Serve accepts incoming connections on the Listener l, creating a
4407-// new service goroutine for each. The service goroutines read requests and
4408-// then call srv.Handler to reply to them.
4409-func (srv *Server) Serve(l net.Listener) error {
4410- defer l.Close()
4411- var tempDelay time.Duration // how long to sleep on accept failure
4412- for {
4413- rw, e := l.Accept()
4414- if e != nil {
4415- if ne, ok := e.(net.Error); ok && ne.Temporary() {
4416- if tempDelay == 0 {
4417- tempDelay = 5 * time.Millisecond
4418- } else {
4419- tempDelay *= 2
4420- }
4421- if max := 1 * time.Second; tempDelay > max {
4422- tempDelay = max
4423- }
4424- srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
4425- time.Sleep(tempDelay)
4426- continue
4427- }
4428- return e
4429- }
4430- tempDelay = 0
4431- c, err := srv.newConn(rw)
4432- if err != nil {
4433- continue
4434- }
4435- c.setState(c.rwc, StateNew) // before Serve can return
4436- go c.serve()
4437- }
4438-}
4439-
4440-func (s *Server) doKeepAlives() bool {
4441- return atomic.LoadInt32(&s.disableKeepAlives) == 0
4442-}
4443-
4444-// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
4445-// By default, keep-alives are always enabled. Only very
4446-// resource-constrained environments or servers in the process of
4447-// shutting down should disable them.
4448-func (s *Server) SetKeepAlivesEnabled(v bool) {
4449- if v {
4450- atomic.StoreInt32(&s.disableKeepAlives, 0)
4451- } else {
4452- atomic.StoreInt32(&s.disableKeepAlives, 1)
4453- }
4454-}
4455-
4456-func (s *Server) logf(format string, args ...interface{}) {
4457- if s.ErrorLog != nil {
4458- s.ErrorLog.Printf(format, args...)
4459- } else {
4460- log.Printf(format, args...)
4461- }
4462-}
4463-
4464-// ListenAndServe listens on the TCP network address addr
4465-// and then calls Serve with handler to handle requests
4466-// on incoming connections. Handler is typically nil,
4467-// in which case the DefaultServeMux is used.
4468-//
4469-// A trivial example server is:
4470-//
4471-// package main
4472-//
4473-// import (
4474-// "io"
4475-// "launchpad.net/ubuntu-push/http13client"
4476-// "log"
4477-// )
4478-//
4479-// // hello world, the web server
4480-// func HelloServer(w http.ResponseWriter, req *http.Request) {
4481-// io.WriteString(w, "hello, world!\n")
4482-// }
4483-//
4484-// func main() {
4485-// http.HandleFunc("/hello", HelloServer)
4486-// err := http.ListenAndServe(":12345", nil)
4487-// if err != nil {
4488-// log.Fatal("ListenAndServe: ", err)
4489-// }
4490-// }
4491-func ListenAndServe(addr string, handler Handler) error {
4492- server := &Server{Addr: addr, Handler: handler}
4493- return server.ListenAndServe()
4494-}
4495-
4496-// ListenAndServeTLS acts identically to ListenAndServe, except that it
4497-// expects HTTPS connections. Additionally, files containing a certificate and
4498-// matching private key for the server must be provided. If the certificate
4499-// is signed by a certificate authority, the certFile should be the concatenation
4500-// of the server's certificate followed by the CA's certificate.
4501-//
4502-// A trivial example server is:
4503-//
4504-// import (
4505-// "log"
4506-// "launchpad.net/ubuntu-push/http13client"
4507-// )
4508-//
4509-// func handler(w http.ResponseWriter, req *http.Request) {
4510-// w.Header().Set("Content-Type", "text/plain")
4511-// w.Write([]byte("This is an example server.\n"))
4512-// }
4513-//
4514-// func main() {
4515-// http.HandleFunc("/", handler)
4516-// log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
4517-// err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
4518-// if err != nil {
4519-// log.Fatal(err)
4520-// }
4521-// }
4522-//
4523-// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
4524-func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error {
4525- server := &Server{Addr: addr, Handler: handler}
4526- return server.ListenAndServeTLS(certFile, keyFile)
4527-}
4528-
4529-// ListenAndServeTLS listens on the TCP network address srv.Addr and
4530-// then calls Serve to handle requests on incoming TLS connections.
4531-//
4532-// Filenames containing a certificate and matching private key for
4533-// the server must be provided. If the certificate is signed by a
4534-// certificate authority, the certFile should be the concatenation
4535-// of the server's certificate followed by the CA's certificate.
4536-//
4537-// If srv.Addr is blank, ":https" is used.
4538-func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
4539- addr := srv.Addr
4540- if addr == "" {
4541- addr = ":https"
4542- }
4543- config := &tls.Config{}
4544- if srv.TLSConfig != nil {
4545- *config = *srv.TLSConfig
4546- }
4547- if config.NextProtos == nil {
4548- config.NextProtos = []string{"http/1.1"}
4549- }
4550-
4551- var err error
4552- config.Certificates = make([]tls.Certificate, 1)
4553- config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
4554- if err != nil {
4555- return err
4556- }
4557-
4558- ln, err := net.Listen("tcp", addr)
4559- if err != nil {
4560- return err
4561- }
4562-
4563- tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
4564- return srv.Serve(tlsListener)
4565-}
4566-
4567-// TimeoutHandler returns a Handler that runs h with the given time limit.
4568-//
4569-// The new Handler calls h.ServeHTTP to handle each request, but if a
4570-// call runs for longer than its time limit, the handler responds with
4571-// a 503 Service Unavailable error and the given message in its body.
4572-// (If msg is empty, a suitable default message will be sent.)
4573-// After such a timeout, writes by h to its ResponseWriter will return
4574-// ErrHandlerTimeout.
4575-func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
4576- f := func() <-chan time.Time {
4577- return time.After(dt)
4578- }
4579- return &timeoutHandler{h, f, msg}
4580-}
4581-
4582-// ErrHandlerTimeout is returned on ResponseWriter Write calls
4583-// in handlers which have timed out.
4584-var ErrHandlerTimeout = errors.New("http: Handler timeout")
4585-
4586-type timeoutHandler struct {
4587- handler Handler
4588- timeout func() <-chan time.Time // returns channel producing a timeout
4589- body string
4590-}
4591-
4592-func (h *timeoutHandler) errorBody() string {
4593- if h.body != "" {
4594- return h.body
4595- }
4596- return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
4597-}
4598-
4599-func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
4600- done := make(chan bool, 1)
4601- tw := &timeoutWriter{w: w}
4602- go func() {
4603- h.handler.ServeHTTP(tw, r)
4604- done <- true
4605- }()
4606- select {
4607- case <-done:
4608- return
4609- case <-h.timeout():
4610- tw.mu.Lock()
4611- defer tw.mu.Unlock()
4612- if !tw.wroteHeader {
4613- tw.w.WriteHeader(StatusServiceUnavailable)
4614- tw.w.Write([]byte(h.errorBody()))
4615- }
4616- tw.timedOut = true
4617- }
4618-}
4619-
4620-type timeoutWriter struct {
4621- w ResponseWriter
4622-
4623- mu sync.Mutex
4624- timedOut bool
4625- wroteHeader bool
4626-}
4627-
4628-func (tw *timeoutWriter) Header() Header {
4629- return tw.w.Header()
4630-}
4631-
4632-func (tw *timeoutWriter) Write(p []byte) (int, error) {
4633- tw.mu.Lock()
4634- timedOut := tw.timedOut
4635- tw.mu.Unlock()
4636- if timedOut {
4637- return 0, ErrHandlerTimeout
4638- }
4639- return tw.w.Write(p)
4640-}
4641-
4642-func (tw *timeoutWriter) WriteHeader(code int) {
4643- tw.mu.Lock()
4644- if tw.timedOut || tw.wroteHeader {
4645- tw.mu.Unlock()
4646- return
4647- }
4648- tw.wroteHeader = true
4649- tw.mu.Unlock()
4650- tw.w.WriteHeader(code)
4651-}
4652-
4653-// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
4654-// connections. It's used by ListenAndServe and ListenAndServeTLS so
4655-// dead TCP connections (e.g. closing laptop mid-download) eventually
4656-// go away.
4657-type tcpKeepAliveListener struct {
4658- *net.TCPListener
4659-}
4660-
4661-func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
4662- tc, err := ln.AcceptTCP()
4663- if err != nil {
4664- return
4665- }
4666- tc.SetKeepAlive(true)
4667- tc.SetKeepAlivePeriod(3 * time.Minute)
4668- return tc, nil
4669-}
4670-
4671-// globalOptionsHandler responds to "OPTIONS *" requests.
4672-type globalOptionsHandler struct{}
4673-
4674-func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
4675- w.Header().Set("Content-Length", "0")
4676- if r.ContentLength != 0 {
4677- // Read up to 4KB of OPTIONS body (as mentioned in the
4678- // spec as being reserved for future use), but anything
4679- // over that is considered a waste of server resources
4680- // (or an attack) and we abort and close the connection,
4681- // courtesy of MaxBytesReader's EOF behavior.
4682- mb := MaxBytesReader(w, r.Body, 4<<10)
4683- io.Copy(ioutil.Discard, mb)
4684- }
4685-}
4686+)
4687
4688 // eofReader is a non-nil io.ReadCloser that always returns EOF.
4689 // It embeds a *strings.Reader so it still has a WriteTo method
4690@@ -1992,28 +25,6 @@
4691 ioutil.NopCloser(nil),
4692 }
4693
4694-// initNPNRequest is an HTTP handler that initializes certain
4695-// uninitialized fields in its *Request. Such partially-initialized
4696-// Requests come from NPN protocol handlers.
4697-type initNPNRequest struct {
4698- c *tls.Conn
4699- h serverHandler
4700-}
4701-
4702-func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
4703- if req.TLS == nil {
4704- req.TLS = &tls.ConnectionState{}
4705- *req.TLS = h.c.ConnectionState()
4706- }
4707- if req.Body == nil {
4708- req.Body = eofReader
4709- }
4710- if req.RemoteAddr == "" {
4711- req.RemoteAddr = h.c.RemoteAddr().String()
4712- }
4713- h.h.ServeHTTP(rw, req)
4714-}
4715-
4716 // loggingConn is used for debugging.
4717 type loggingConn struct {
4718 name string
4719
04720
=== added file 'http13client/_patches/fix_code.patch'
--- http13client/_patches/fix_code.patch 1970-01-01 00:00:00 +0000
+++ http13client/_patches/fix_code.patch 2014-03-20 12:26:55 +0000
@@ -0,0 +1,739 @@
1=== modified file 'http13client/client.go'
2--- http13client/client.go 2014-03-19 20:20:19 +0000
3+++ http13client/client.go 2014-03-19 22:27:37 +0000
4@@ -17,6 +17,7 @@
5 "io/ioutil"
6 "log"
7 "net/url"
8+ "net/http"
9 "strings"
10 "sync"
11 "time"
12@@ -54,7 +55,7 @@
13 // Jar specifies the cookie jar.
14 // If Jar is nil, cookies are not sent in requests and ignored
15 // in responses.
16- Jar CookieJar
17+ Jar http.CookieJar
18
19 // Timeout specifies a time limit for requests made by this
20 // Client. The timeout includes connection time, any
21@@ -177,7 +178,7 @@
22 // Headers, leaving it uninitialized. We guarantee to the
23 // Transport that this has been initialized, though.
24 if req.Header == nil {
25- req.Header = make(Header)
26+ req.Header = make(http.Header)
27 }
28
29 if u := req.URL.User; u != nil {
30@@ -308,7 +309,7 @@
31 if ireq.Method == "POST" || ireq.Method == "PUT" {
32 nreq.Method = "GET"
33 }
34- nreq.Header = make(Header)
35+ nreq.Header = make(http.Header)
36 nreq.URL, err = base.Parse(urlStr)
37 if err != nil {
38 break
39
40=== modified file 'http13client/cookie.go'
41--- http13client/cookie.go 2014-03-19 20:20:19 +0000
42+++ http13client/cookie.go 2014-03-19 22:27:37 +0000
43@@ -5,10 +5,9 @@
44 package http
45
46 import (
47- "bytes"
48- "fmt"
49 "log"
50 "net"
51+ "net/http"
52 "strconv"
53 "strings"
54 "time"
55@@ -18,30 +17,10 @@
56 //
57 // http://tools.ietf.org/html/rfc6265
58
59-// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
60-// HTTP response or the Cookie header of an HTTP request.
61-type Cookie struct {
62- Name string
63- Value string
64- Path string
65- Domain string
66- Expires time.Time
67- RawExpires string
68-
69- // MaxAge=0 means no 'Max-Age' attribute specified.
70- // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
71- // MaxAge>0 means Max-Age attribute present and given in seconds
72- MaxAge int
73- Secure bool
74- HttpOnly bool
75- Raw string
76- Unparsed []string // Raw text of unparsed attribute-value pairs
77-}
78-
79 // readSetCookies parses all "Set-Cookie" values from
80 // the header h and returns the successfully parsed Cookies.
81-func readSetCookies(h Header) []*Cookie {
82- cookies := []*Cookie{}
83+func readSetCookies(h http.Header) []*http.Cookie {
84+ cookies := []*http.Cookie{}
85 for _, line := range h["Set-Cookie"] {
86 parts := strings.Split(strings.TrimSpace(line), ";")
87 if len(parts) == 1 && parts[0] == "" {
88@@ -60,7 +39,7 @@
89 if !success {
90 continue
91 }
92- c := &Cookie{
93+ c := &http.Cookie{
94 Name: name,
95 Value: value,
96 Raw: line,
97@@ -129,59 +108,12 @@
98 return cookies
99 }
100
101-// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
102-func SetCookie(w ResponseWriter, cookie *Cookie) {
103- w.Header().Add("Set-Cookie", cookie.String())
104-}
105-
106-// String returns the serialization of the cookie for use in a Cookie
107-// header (if only Name and Value are set) or a Set-Cookie response
108-// header (if other fields are set).
109-func (c *Cookie) String() string {
110- var b bytes.Buffer
111- fmt.Fprintf(&b, "%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
112- if len(c.Path) > 0 {
113- fmt.Fprintf(&b, "; Path=%s", sanitizeCookiePath(c.Path))
114- }
115- if len(c.Domain) > 0 {
116- if validCookieDomain(c.Domain) {
117- // A c.Domain containing illegal characters is not
118- // sanitized but simply dropped which turns the cookie
119- // into a host-only cookie. A leading dot is okay
120- // but won't be sent.
121- d := c.Domain
122- if d[0] == '.' {
123- d = d[1:]
124- }
125- fmt.Fprintf(&b, "; Domain=%s", d)
126- } else {
127- log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute",
128- c.Domain)
129- }
130- }
131- if c.Expires.Unix() > 0 {
132- fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(time.RFC1123))
133- }
134- if c.MaxAge > 0 {
135- fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
136- } else if c.MaxAge < 0 {
137- fmt.Fprintf(&b, "; Max-Age=0")
138- }
139- if c.HttpOnly {
140- fmt.Fprintf(&b, "; HttpOnly")
141- }
142- if c.Secure {
143- fmt.Fprintf(&b, "; Secure")
144- }
145- return b.String()
146-}
147-
148 // readCookies parses all "Cookie" values from the header h and
149 // returns the successfully parsed Cookies.
150 //
151 // if filter isn't empty, only cookies of that name are returned
152-func readCookies(h Header, filter string) []*Cookie {
153- cookies := []*Cookie{}
154+func readCookies(h http.Header, filter string) []*http.Cookie {
155+ cookies := []*http.Cookie{}
156 lines, ok := h["Cookie"]
157 if !ok {
158 return cookies
159@@ -213,7 +145,7 @@
160 if !success {
161 continue
162 }
163- cookies = append(cookies, &Cookie{Name: name, Value: val})
164+ cookies = append(cookies, &http.Cookie{Name: name, Value: val})
165 parsedPairs++
166 }
167 }
168
169=== modified file 'http13client/header.go'
170--- http13client/header.go 2014-03-19 20:20:19 +0000
171+++ http13client/header.go 2014-03-19 22:27:37 +0000
172@@ -5,176 +5,9 @@
173 package http
174
175 import (
176- "io"
177- "net/textproto"
178- "sort"
179 "strings"
180- "time"
181 )
182
183-var raceEnabled = false // set by race.go
184-
185-// A Header represents the key-value pairs in an HTTP header.
186-type Header map[string][]string
187-
188-// Add adds the key, value pair to the header.
189-// It appends to any existing values associated with key.
190-func (h Header) Add(key, value string) {
191- textproto.MIMEHeader(h).Add(key, value)
192-}
193-
194-// Set sets the header entries associated with key to
195-// the single element value. It replaces any existing
196-// values associated with key.
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches