From 755e597a113db817edb99c9a1e1606a9f016e2ad Mon Sep 17 00:00:00 2001 From: MrMelon54 Date: Tue, 11 Jul 2023 02:03:20 +0100 Subject: [PATCH] Remove breaking body close call and add test for reading request body --- target/route.go | 9 --------- target/route_test.go | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/target/route.go b/target/route.go index 0737693..3d3ba3a 100644 --- a/target/route.go +++ b/target/route.go @@ -203,15 +203,6 @@ func (r Route) internalReverseProxyMeta(rw http.ResponseWriter, req *http.Reques if req.ContentLength == 0 { outreq.Body = nil // Issue 16036: nil Body for http.Transport retries } - if outreq.Body != nil { - // Reading from the request body after returning from a handler is not - // allowed, and the RoundTrip goroutine that reads the Body can outlive - // this handler. This can lead to a crash if the handler panics (see - // Issue 46866). Although calling Close doesn't guarantee there isn't - // any Read in flight after the handle returns, in practice it's safe to - // read after closing it. - defer outreq.Body.Close() - } if outreq.Header == nil { outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate } diff --git a/target/route_test.go b/target/route_test.go index 075e73c..2b08339 100644 --- a/target/route_test.go +++ b/target/route_test.go @@ -1,8 +1,10 @@ package target import ( + "bytes" "github.com/MrMelon54/violet/proxy" "github.com/stretchr/testify/assert" + "io" "net/http" "net/http/httptest" "testing" @@ -77,3 +79,21 @@ func TestRoute_ServeHTTP_Cors(t *testing.T) { assert.Equal(t, "true", res.Header().Get("Access-Control-Allow-Credentials")) assert.Equal(t, "Origin", res.Header().Get("Vary")) } + +func TestRoute_ServeHTTP_Body(t *testing.T) { + pt := &proxyTester{} + res := httptest.NewRecorder() + buf := bytes.NewBuffer([]byte{0x54}) + req := httptest.NewRequest(http.MethodPost, "https://www.example.com/test", buf) + req.Header.Set("Origin", "https://test.example.com") + i := &Route{Host: "1.1.1.1", Port: 8080, Path: "/hello", Cors: true, Proxy: pt.makeHybridTransport()} + i.ServeHTTP(res, req) + + assert.True(t, pt.got) + assert.Equal(t, http.MethodPost, pt.req.Method) + assert.Equal(t, "http://1.1.1.1:8080/hello/test", pt.req.URL.String()) + all, err := io.ReadAll(pt.req.Body) + assert.NoError(t, err) + assert.Equal(t, 0, bytes.Compare(all, []byte{0x54})) + assert.NoError(t, pt.req.Body.Close()) +}