Repository: valyala/fasthttp
Pull request #897 (2020-10-30 07:59:00)

fixed default schema for for req url
There is a bug with req url schema settings in the proxy dialer adapter.


Patch:
diff --git a/.gitignore b/.gitignore
index 220a3f8..32c6c80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 tags
 *.pprof
 *.fasthttp.gz
-.idea
\ No newline at end of file
+*.fasthttp.br
+.idea
diff --git a/fasthttpproxy/proxy_env.go b/fasthttpproxy/proxy_env.go
index 9d5fe98..34089ca 100644
--- a/fasthttpproxy/proxy_env.go
+++ b/fasthttpproxy/proxy_env.go
@@ -35,6 +35,7 @@ func FasthttpProxyHTTPDialer() fasthttp.DialFunc {
 
 const (
 	httpsScheme = "https"
+	httpScheme  = "http"
 	tlsPort     = "443"
 )
 
@@ -52,7 +53,7 @@ func FasthttpProxyHTTPDialerTimeout(timeout time.Duration) fasthttp.DialFunc {
 			return nil, fmt.Errorf("unexpected addr format: %w", err)
 		}
 
-		reqURL := &url.URL{Host: addr, Scheme: httpsScheme}
+		reqURL := &url.URL{Host: addr, Scheme: httpScheme}
 		if port == tlsPort {
 			reqURL.Scheme = httpsScheme
 		}
diff --git a/http.go b/http.go
index d062c14..5e3d7d3 100644
--- a/http.go
+++ b/http.go
@@ -36,6 +36,7 @@ type Request struct {
 	bodyStream io.Reader
 	w          requestBodyWriter
 	body       *bytebufferpool.ByteBuffer
+	bodyRaw    []byte
 
 	multipartForm         *multipart.Form
 	multipartFormBoundary string
@@ -341,6 +342,9 @@ func (resp *Response) bodyBytes() []byte {
 }
 
 func (req *Request) bodyBytes() []byte {
+	if req.bodyRaw != nil {
+		return req.bodyRaw
+	}
 	if req.body == nil {
 		return nil
 	}
@@ -359,6 +363,7 @@ func (req *Request) bodyBuffer() *bytebufferpool.ByteBuffer {
 	if req.body == nil {
 		req.body = requestBodyPool.Get()
 	}
+	req.bodyRaw = nil
 	return req.body
 }
 
@@ -527,6 +532,14 @@ func (resp *Response) SetBodyRaw(body []byte) {
 	resp.bodyRaw = body
 }
 
+// SetBodyRaw sets response body, but without copying it.
+//
+// From this point onward the body argument must not be changed.
+func (req *Request) SetBodyRaw(body []byte) {
+	req.ResetBody()
+	req.bodyRaw = body
+}
+
 // ReleaseBody retires the response body if it is greater than "size" bytes.
 //
 // This permits GC to reclaim the large buffer.  If used, must be before
@@ -550,6 +563,7 @@ func (resp *Response) ReleaseBody(size int) {
 // Use this method only if you really understand how it works.
 // The majority of workloads don't need this method.
 func (req *Request) ReleaseBody(size int) {
+	req.bodyRaw = nil
 	if cap(req.body.B) > size {
 		req.closeBodyStream() //nolint:errcheck
 		req.body = nil
@@ -599,6 +613,8 @@ func (req *Request) SwapBody(body []byte) []byte {
 		}
 	}
 
+	req.bodyRaw = nil
+
 	oldBody := bb.B
 	bb.B = body
 	return oldBody
@@ -608,7 +624,9 @@ func (req *Request) SwapBody(body []byte) []byte {
 //
 // The returned body is valid until the request modification.
 func (req *Request) Body() []byte {
-	if req.bodyStream != nil {
+	if req.bodyRaw != nil {
+		return req.bodyRaw
+	} else if req.bodyStream != nil {
 		bodyBuf := req.bodyBuffer()
 		bodyBuf.Reset()
 		_, err := copyZeroAlloc(bodyBuf, req.bodyStream)
@@ -660,6 +678,7 @@ func (req *Request) SetBodyString(body string) {
 
 // ResetBody resets request body.
 func (req *Request) ResetBody() {
+	req.bodyRaw = nil
 	req.RemoveMultipartFormFiles()
 	req.closeBodyStream() //nolint:errcheck
 	if req.body != nil {
@@ -675,7 +694,12 @@ func (req *Request) ResetBody() {
 // CopyTo copies req contents to dst except of body stream.
 func (req *Request) CopyTo(dst *Request) {
 	req.copyToSkipBody(dst)
-	if req.body != nil {
+	if req.bodyRaw != nil {
+		dst.bodyRaw = req.bodyRaw
+		if dst.body != nil {
+			dst.body.Reset()
+		}
+	} else if req.body != nil {
 		dst.bodyBuffer().Set(req.body.B)
 	} else if dst.body != nil {
 		dst.body.Reset()
@@ -722,6 +746,7 @@ func (resp *Response) copyToSkipBody(dst *Response) {
 
 func swapRequestBody(a, b *Request) {
 	a.body, b.body = b.body, a.body
+	a.bodyRaw, b.bodyRaw = b.bodyRaw, a.bodyRaw
 	a.bodyStream, b.bodyStream = b.bodyStream, a.bodyStream
 }
 


Test patch:
diff --git a/http_test.go b/http_test.go
index bcac9dc..c67f520 100644
--- a/http_test.go
+++ b/http_test.go
@@ -2081,6 +2081,18 @@ func TestResponseRawBodySet(t *testing.T) {
 	testBodyWriteTo(t, &resp, expectedS, true)
 }
 
+func TestRequestRawBodySet(t *testing.T) {
+	t.Parallel()
+
+	var r Request
+
+	expectedS := "test"
+	body := []byte(expectedS)
+	r.SetBodyRaw(body)
+
+	testBodyWriteTo(t, &r, expectedS, true)
+}
+
 func TestResponseRawBodyReset(t *testing.T) {
 	t.Parallel()
 
@@ -2093,6 +2105,18 @@ func TestResponseRawBodyReset(t *testing.T) {
 	testBodyWriteTo(t, &resp, "", true)
 }
 
+func TestRequestRawBodyReset(t *testing.T) {
+	t.Parallel()
+
+	var r Request
+
+	body := []byte("test")
+	r.SetBodyRaw(body)
+	r.ResetBody()
+
+	testBodyWriteTo(t, &r, "", true)
+}
+
 func TestResponseRawBodyCopyTo(t *testing.T) {
 	t.Parallel()
 
@@ -2105,6 +2129,22 @@ func TestResponseRawBodyCopyTo(t *testing.T) {
 	testResponseCopyTo(t, &resp)
 }
 
+func TestRequestRawBodyCopyTo(t *testing.T) {
+	t.Parallel()
+
+	var a Request
+
+	body := []byte("test")
+	a.SetBodyRaw(body)
+
+	var b Request
+
+	a.CopyTo(&b)
+
+	testBodyWriteTo(t, &a, "test", true)
+	testBodyWriteTo(t, &b, "test", true)
+}
+
 type testReader struct {
 	read chan (int)
 	cb   chan (struct{})