From 87117b2f2ab7ce319f157b64587dddbbb6116f5a Mon Sep 17 00:00:00 2001 From: uwaterloo gitlab Date: Wed, 6 Oct 2021 06:43:25 -0400 Subject: [PATCH 1/6] Adding ConvertHTTPRequest and renaming ConvertRequest to ConvertFastRequest --- fasthttpadaptor/adaptor.go | 2 +- fasthttpadaptor/request.go | 65 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/fasthttpadaptor/adaptor.go b/fasthttpadaptor/adaptor.go index 51b9c7a45c..e08a00b281 100644 --- a/fasthttpadaptor/adaptor.go +++ b/fasthttpadaptor/adaptor.go @@ -47,7 +47,7 @@ func NewFastHTTPHandlerFunc(h http.HandlerFunc) fasthttp.RequestHandler { func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { var r http.Request - if err := ConvertRequest(ctx, &r, true); err != nil { + if err := ConvertFastRequest(ctx, &r, true); err != nil { ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err) ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError) return diff --git a/fasthttpadaptor/request.go b/fasthttpadaptor/request.go index 7a49bfd079..a8b1b95765 100644 --- a/fasthttpadaptor/request.go +++ b/fasthttpadaptor/request.go @@ -3,15 +3,16 @@ package fasthttpadaptor import ( "bytes" "io/ioutil" + "net" "net/http" "net/url" "github.com/valyala/fasthttp" ) -// ConvertRequest convert a fasthttp.Request to an http.Request -// forServer should be set to true when the http.Request is going to passed to a http.Handler. -func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error { +// ConvertFastRequest converts a fasthttp.Request to a http.Request +// forServer should be set to true when the http.Request is going to be passed to a http.Handler. +func ConvertFastRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error { body := ctx.PostBody() strRequestURI := string(ctx.RequestURI()) @@ -57,3 +58,61 @@ func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) e return nil } + +// ConvertHTTPRequest converts a http.Request to a fasthttp.Request +// forServer should be set to true when the http.Request is going to be passed to a http.Handler. +func ConvertHTTPRequest(r *http.Request, ctx *fasthttp.RequestCtx, forServer bool) error { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return err + } + + ip, err := net.ResolveIPAddr("tcp", host) + if err != nil { + return err + } + + ctx.SetRemoteAddr(ip) + + if ctx.Request.Header.Len() > 0 { + ctx.Request.Header.Reset() + } + + for k, v := range r.Header { + if len(v) > 1 { + for _, vv := range v { + ctx.Request.Header.Add(k, vv) + } + } else { + ctx.Request.Header.Set(k, v[0]) + } + } + + if len(r.TransferEncoding) > 0 { + if len(r.TransferEncoding) > 1 { + for _, e := range r.TransferEncoding { + ctx.Request.Header.Add("Transfer-Encoding", e) + } + } else { + ctx.Request.Header.Add("Transfer-Encoding", r.TransferEncoding[0]) + } + } + + ctx.Request.URI().Update(r.URL.String()) + + ctx.Request.Header.SetMethod(r.Method) + ctx.Request.Header.SetProtocol(r.Proto) + ctx.Request.Header.SetContentLength(int(r.ContentLength)) + ctx.Request.Header.SetHost(r.Host) + *ctx.TLSConnectionState() = *r.TLS + + bodyBytes := new(bytes.Buffer) + _, err = bodyBytes.ReadFrom(r.Body) + if err != nil { + return err + } + + ctx.Request.SetBodyRaw(bodyBytes.Bytes()) + + return nil +} From f5543f86299c71459e6ec766199c62182a126956 Mon Sep 17 00:00:00 2001 From: uwaterloo gitlab Date: Wed, 6 Oct 2021 06:44:12 -0400 Subject: [PATCH 2/6] Removing forServer boolean from ConvertHTTPRequest --- fasthttpadaptor/request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fasthttpadaptor/request.go b/fasthttpadaptor/request.go index a8b1b95765..afc311db7d 100644 --- a/fasthttpadaptor/request.go +++ b/fasthttpadaptor/request.go @@ -61,7 +61,7 @@ func ConvertFastRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer boo // ConvertHTTPRequest converts a http.Request to a fasthttp.Request // forServer should be set to true when the http.Request is going to be passed to a http.Handler. -func ConvertHTTPRequest(r *http.Request, ctx *fasthttp.RequestCtx, forServer bool) error { +func ConvertHTTPRequest(r *http.Request, ctx *fasthttp.RequestCtx) error { host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { return err From 0a47edb874039c470820d792d6089d6524882128 Mon Sep 17 00:00:00 2001 From: uwaterloo gitlab Date: Wed, 20 Oct 2021 17:54:14 -0400 Subject: [PATCH 3/6] Preparing for PR --- http.go | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/http.go b/http.go index 18e5f8126c..3926239756 100644 --- a/http.go +++ b/http.go @@ -1200,7 +1200,10 @@ func (resp *Response) Read(r *bufio.Reader) error { return resp.ReadLimitBody(r, 0) } -// ReadLimitBody reads response from the given r, limiting the body size. +// ReadLimitBody reads response headers from the given r, +// then reads the body using the ReadBody function and limiting the body size. +// +// If SkipBody is true then it skips reading the response body. // // If maxBodySize > 0 and the body size exceeds maxBodySize, // then ErrBodyTooLarge is returned. @@ -1220,14 +1223,23 @@ func (resp *Response) ReadLimitBody(r *bufio.Reader, maxBodySize int) error { } if !resp.mustSkipBody() { - bodyBuf := resp.bodyBuffer() - bodyBuf.Reset() - bodyBuf.B, err = readBody(r, resp.Header.ContentLength(), maxBodySize, bodyBuf.B) - if err != nil { - return err - } - resp.Header.SetContentLength(len(bodyBuf.B)) + return resp.ReadBody(r, maxBodySize) + } + return nil +} + +// ReadBody reads response body from the given r, limiting the body size. +// +// If maxBodySize > 0 and the body size exceeds maxBodySize, +// then ErrBodyTooLarge is returned. +func (resp *Response) ReadBody(r *bufio.Reader, maxBodySize int) (err error) { + bodyBuf := resp.bodyBuffer() + bodyBuf.Reset() + bodyBuf.B, err = readBody(r, resp.Header.ContentLength(), maxBodySize, bodyBuf.B) + if err != nil { + return err } + resp.Header.SetContentLength(len(bodyBuf.B)) return nil } From c464a5f1653cb927f589e9f1316a112460946067 Mon Sep 17 00:00:00 2001 From: uwaterloo gitlab Date: Wed, 20 Oct 2021 17:56:25 -0400 Subject: [PATCH 4/6] Reverting adaptor changes --- fasthttpadaptor/adaptor.go | 2 +- fasthttpadaptor/request.go | 65 ++------------------------------------ 2 files changed, 4 insertions(+), 63 deletions(-) diff --git a/fasthttpadaptor/adaptor.go b/fasthttpadaptor/adaptor.go index e08a00b281..51b9c7a45c 100644 --- a/fasthttpadaptor/adaptor.go +++ b/fasthttpadaptor/adaptor.go @@ -47,7 +47,7 @@ func NewFastHTTPHandlerFunc(h http.HandlerFunc) fasthttp.RequestHandler { func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { var r http.Request - if err := ConvertFastRequest(ctx, &r, true); err != nil { + if err := ConvertRequest(ctx, &r, true); err != nil { ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err) ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError) return diff --git a/fasthttpadaptor/request.go b/fasthttpadaptor/request.go index afc311db7d..7a49bfd079 100644 --- a/fasthttpadaptor/request.go +++ b/fasthttpadaptor/request.go @@ -3,16 +3,15 @@ package fasthttpadaptor import ( "bytes" "io/ioutil" - "net" "net/http" "net/url" "github.com/valyala/fasthttp" ) -// ConvertFastRequest converts a fasthttp.Request to a http.Request -// forServer should be set to true when the http.Request is going to be passed to a http.Handler. -func ConvertFastRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error { +// ConvertRequest convert a fasthttp.Request to an http.Request +// forServer should be set to true when the http.Request is going to passed to a http.Handler. +func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error { body := ctx.PostBody() strRequestURI := string(ctx.RequestURI()) @@ -58,61 +57,3 @@ func ConvertFastRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer boo return nil } - -// ConvertHTTPRequest converts a http.Request to a fasthttp.Request -// forServer should be set to true when the http.Request is going to be passed to a http.Handler. -func ConvertHTTPRequest(r *http.Request, ctx *fasthttp.RequestCtx) error { - host, _, err := net.SplitHostPort(r.RemoteAddr) - if err != nil { - return err - } - - ip, err := net.ResolveIPAddr("tcp", host) - if err != nil { - return err - } - - ctx.SetRemoteAddr(ip) - - if ctx.Request.Header.Len() > 0 { - ctx.Request.Header.Reset() - } - - for k, v := range r.Header { - if len(v) > 1 { - for _, vv := range v { - ctx.Request.Header.Add(k, vv) - } - } else { - ctx.Request.Header.Set(k, v[0]) - } - } - - if len(r.TransferEncoding) > 0 { - if len(r.TransferEncoding) > 1 { - for _, e := range r.TransferEncoding { - ctx.Request.Header.Add("Transfer-Encoding", e) - } - } else { - ctx.Request.Header.Add("Transfer-Encoding", r.TransferEncoding[0]) - } - } - - ctx.Request.URI().Update(r.URL.String()) - - ctx.Request.Header.SetMethod(r.Method) - ctx.Request.Header.SetProtocol(r.Proto) - ctx.Request.Header.SetContentLength(int(r.ContentLength)) - ctx.Request.Header.SetHost(r.Host) - *ctx.TLSConnectionState() = *r.TLS - - bodyBytes := new(bytes.Buffer) - _, err = bodyBytes.ReadFrom(r.Body) - if err != nil { - return err - } - - ctx.Request.SetBodyRaw(bodyBytes.Bytes()) - - return nil -} From c91bc14391e6bb5f209dd88ab90be1b7989d5470 Mon Sep 17 00:00:00 2001 From: uwaterloo gitlab Date: Wed, 20 Oct 2021 18:02:22 -0400 Subject: [PATCH 5/6] Fixing godoc, adding req.ReadBody function as well --- http.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/http.go b/http.go index 3926239756..0b0d7ff19a 100644 --- a/http.go +++ b/http.go @@ -1122,6 +1122,14 @@ func (req *Request) ContinueReadBody(r *bufio.Reader, maxBodySize int, preParseM return nil } + return req.ReadBody(r, contentLength, maxBodySize) +} + +// ReadBody reads request body from the given r, limiting the body size. +// +// If maxBodySize > 0 and the body size exceeds maxBodySize, +// then ErrBodyTooLarge is returned. +func (req *Request) ReadBody(r *bufio.Reader, contentLength int, maxBodySize int) (err error) { bodyBuf := req.bodyBuffer() bodyBuf.Reset() bodyBuf.B, err = readBody(r, contentLength, maxBodySize, bodyBuf.B) @@ -1133,7 +1141,7 @@ func (req *Request) ContinueReadBody(r *bufio.Reader, maxBodySize int, preParseM return nil } -// ContinueReadBody reads request body if request header contains +// ContinueReadBodyStream reads request body if request header contains // 'Expect: 100-continue'. // // The caller must send StatusContinue response before calling this method. From 9075c98b4a431ce4ddf9e7aa0d52b432fc2a9ce6 Mon Sep 17 00:00:00 2001 From: Shivansh Vij Date: Fri, 22 Oct 2021 13:46:49 -0400 Subject: [PATCH 6/6] Update comment to be more clear As per @erikdubbelboer suggestion Co-authored-by: Erik Dubbelboer --- http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http.go b/http.go index 0b0d7ff19a..8021a2528d 100644 --- a/http.go +++ b/http.go @@ -1211,7 +1211,7 @@ func (resp *Response) Read(r *bufio.Reader) error { // ReadLimitBody reads response headers from the given r, // then reads the body using the ReadBody function and limiting the body size. // -// If SkipBody is true then it skips reading the response body. +// If resp.SkipBody is true then it skips reading the response body. // // If maxBodySize > 0 and the body size exceeds maxBodySize, // then ErrBodyTooLarge is returned.