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

Subscribers

People subscribed via source and target branches