From 40eec0b70615364ab376dd4477e9f62bb5508864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emre=20Savc=C4=B1?= Date: Thu, 15 Sep 2022 23:15:26 +0300 Subject: [PATCH] byte to string unsafe conversion in fasthttpadaptor ConvertRequest method (#1375) * add byte to string unsafe conversion to fasthttpadaptor ConvertRequest method() * add nosec comment line * Update fasthttpadaptor/request.go Co-authored-by: Erik Dubbelboer * move unsafe package import next to std packages * fix lint error in test Co-authored-by: Erik Dubbelboer --- fasthttpadaptor/request.go | 19 ++++++++++++++----- fasthttpadaptor/request_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 fasthttpadaptor/request_test.go diff --git a/fasthttpadaptor/request.go b/fasthttpadaptor/request.go index 3f499f8cbb..cc2684bca2 100644 --- a/fasthttpadaptor/request.go +++ b/fasthttpadaptor/request.go @@ -5,28 +5,32 @@ import ( "io" "net/http" "net/url" + "unsafe" "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. +// +// The http.Request must not be used after the fasthttp handler has returned! +// Memory in use by the http.Request will be reused after your handler has returned! func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error { body := ctx.PostBody() - strRequestURI := string(ctx.RequestURI()) + strRequestURI := b2s(ctx.RequestURI()) rURL, err := url.ParseRequestURI(strRequestURI) if err != nil { return err } - r.Method = string(ctx.Method()) + r.Method = b2s(ctx.Method()) r.Proto = "HTTP/1.1" r.ProtoMajor = 1 r.ProtoMinor = 1 r.ContentLength = int64(len(body)) r.RemoteAddr = ctx.RemoteAddr().String() - r.Host = string(ctx.Host()) + r.Host = b2s(ctx.Host()) r.TLS = ctx.TLSConnectionState() r.Body = io.NopCloser(bytes.NewReader(body)) r.URL = rURL @@ -44,8 +48,8 @@ func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) e } ctx.Request.Header.VisitAll(func(k, v []byte) { - sk := string(k) - sv := string(v) + sk := b2s(k) + sv := b2s(v) switch sk { case "Transfer-Encoding": @@ -57,3 +61,8 @@ func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) e return nil } + +func b2s(b []byte) string { + /* #nosec G103 */ + return *(*string)(unsafe.Pointer(&b)) +} diff --git a/fasthttpadaptor/request_test.go b/fasthttpadaptor/request_test.go new file mode 100644 index 0000000000..3b6ba54ca7 --- /dev/null +++ b/fasthttpadaptor/request_test.go @@ -0,0 +1,28 @@ +package fasthttpadaptor + +import ( + "github.com/valyala/fasthttp" + "net/http" + "testing" +) + +func BenchmarkConvertRequest(b *testing.B) { + var httpReq http.Request + + ctx := &fasthttp.RequestCtx{ + Request: fasthttp.Request{ + Header: fasthttp.RequestHeader{}, + UseHostHeader: false, + }, + } + ctx.Request.Header.SetMethod("GET") + ctx.Request.Header.Set("x", "test") + ctx.Request.Header.Set("y", "test") + ctx.Request.SetRequestURI("/test") + ctx.Request.SetHost("test") + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _ = ConvertRequest(ctx, &httpReq, true) + } +}