diff --git a/fasthttpadaptor/request.go b/fasthttpadaptor/request.go index 7a49bfd079..9631ec7151 100644 --- a/fasthttpadaptor/request.go +++ b/fasthttpadaptor/request.go @@ -5,28 +5,32 @@ import ( "io/ioutil" "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 = ioutil.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) + } +}