|
1 From c0dd2011132f179e77f7f6e1ccd88b5a0e0ee659 Mon Sep 17 00:00:00 2001 |
|
2 From: Brad Fitzpatrick <[email protected]> |
|
3 Date: Wed, 26 Aug 2015 10:53:59 -0700 |
|
4 Subject: [PATCH 15/63] [release-branch.go1.5] net/http/httputil: permit nil |
|
5 request body in ReverseProxy |
|
6 |
|
7 Accepting a request with a nil body was never explicitly supported but |
|
8 happened to work in the past. |
|
9 |
|
10 This doesn't happen in most cases because usually people pass |
|
11 a Server's incoming Request to the ReverseProxy's ServeHTTP method, |
|
12 and incoming server requests are guaranteed to have non-nil bodies. |
|
13 |
|
14 Still, it's a regression, so fix. |
|
15 |
|
16 Fixes #12344 |
|
17 |
|
18 Change-Id: Id9a5a47aea3f2875d195b66c9a5f8581c4ca2aed |
|
19 Reviewed-on: https://go-review.googlesource.com/13935 |
|
20 Reviewed-by: Ian Lance Taylor <[email protected]> |
|
21 Run-TryBot: Brad Fitzpatrick <[email protected]> |
|
22 TryBot-Result: Gobot Gobot <[email protected]> |
|
23 Reviewed-on: https://go-review.googlesource.com/14245 |
|
24 --- |
|
25 src/net/http/httputil/reverseproxy.go | 5 +++- |
|
26 src/net/http/httputil/reverseproxy_test.go | 39 ++++++++++++++++++++++++++++++ |
|
27 2 files changed, 43 insertions(+), 1 deletion(-) |
|
28 |
|
29 diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go |
|
30 index 3b7a184..c8e1132 100644 |
|
31 --- a/src/net/http/httputil/reverseproxy.go |
|
32 +++ b/src/net/http/httputil/reverseproxy.go |
|
33 @@ -105,7 +105,7 @@ type requestCanceler interface { |
|
34 } |
|
35 |
|
36 type runOnFirstRead struct { |
|
37 - io.Reader |
|
38 + io.Reader // optional; nil means empty body |
|
39 |
|
40 fn func() // Run before first Read, then set to nil |
|
41 } |
|
42 @@ -115,6 +115,9 @@ func (c *runOnFirstRead) Read(bs []byte) (int, error) { |
|
43 c.fn() |
|
44 c.fn = nil |
|
45 } |
|
46 + if c.Reader == nil { |
|
47 + return 0, io.EOF |
|
48 + } |
|
49 return c.Reader.Read(bs) |
|
50 } |
|
51 |
|
52 diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go |
|
53 index 25947e6..80a26ab 100644 |
|
54 --- a/src/net/http/httputil/reverseproxy_test.go |
|
55 +++ b/src/net/http/httputil/reverseproxy_test.go |
|
56 @@ -7,6 +7,7 @@ |
|
57 package httputil |
|
58 |
|
59 import ( |
|
60 + "bufio" |
|
61 "io/ioutil" |
|
62 "log" |
|
63 "net/http" |
|
64 @@ -281,3 +282,41 @@ func TestReverseProxyCancellation(t *testing.T) { |
|
65 t.Fatal("DefaultClient.Do() returned nil error") |
|
66 } |
|
67 } |
|
68 + |
|
69 +func req(t *testing.T, v string) *http.Request { |
|
70 + req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(v))) |
|
71 + if err != nil { |
|
72 + t.Fatal(err) |
|
73 + } |
|
74 + return req |
|
75 +} |
|
76 + |
|
77 +// Issue 12344 |
|
78 +func TestNilBody(t *testing.T) { |
|
79 + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
80 + w.Write([]byte("hi")) |
|
81 + })) |
|
82 + defer backend.Close() |
|
83 + |
|
84 + frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { |
|
85 + backURL, _ := url.Parse(backend.URL) |
|
86 + rp := NewSingleHostReverseProxy(backURL) |
|
87 + r := req(t, "GET / HTTP/1.0\r\n\r\n") |
|
88 + r.Body = nil // this accidentally worked in Go 1.4 and below, so keep it working |
|
89 + rp.ServeHTTP(w, r) |
|
90 + })) |
|
91 + defer frontend.Close() |
|
92 + |
|
93 + res, err := http.Get(frontend.URL) |
|
94 + if err != nil { |
|
95 + t.Fatal(err) |
|
96 + } |
|
97 + defer res.Body.Close() |
|
98 + slurp, err := ioutil.ReadAll(res.Body) |
|
99 + if err != nil { |
|
100 + t.Fatal(err) |
|
101 + } |
|
102 + if string(slurp) != "hi" { |
|
103 + t.Errorf("Got %q; want %q", slurp, "hi") |
|
104 + } |
|
105 +} |
|
106 -- |
|
107 2.6.1 |
|
108 |