Remove breaking body close call and add test for reading request body

This commit is contained in:
Melon 2023-07-11 02:03:20 +01:00
parent 43eb689254
commit 755e597a11
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
2 changed files with 20 additions and 9 deletions

View File

@ -203,15 +203,6 @@ func (r Route) internalReverseProxyMeta(rw http.ResponseWriter, req *http.Reques
if req.ContentLength == 0 { if req.ContentLength == 0 {
outreq.Body = nil // Issue 16036: nil Body for http.Transport retries 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 { if outreq.Header == nil {
outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
} }

View File

@ -1,8 +1,10 @@
package target package target
import ( import (
"bytes"
"github.com/MrMelon54/violet/proxy" "github.com/MrMelon54/violet/proxy"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "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, "true", res.Header().Get("Access-Control-Allow-Credentials"))
assert.Equal(t, "Origin", res.Header().Get("Vary")) 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())
}