mirror of https://github.com/gofiber/fiber.git
🐛 fix(middleware/adaptor): Reduce memory usage by replacing io.ReadAll() with io.Copy() (#2637)
* Replace io.ReadAll with io.Copy for Adaptor Middleware * Add nolint to Close() during benchmarkpull/2642/head
parent
52f1eb9ddf
commit
5d6552e42d
|
@ -116,14 +116,9 @@ func handlerFunc(app *fiber.App, h ...fiber.Handler) http.HandlerFunc {
|
|||
defer fasthttp.ReleaseRequest(req)
|
||||
// Convert net/http -> fasthttp request
|
||||
if r.Body != nil {
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
n, err := io.Copy(req.BodyWriter(), r.Body)
|
||||
req.Header.SetContentLength(int(n))
|
||||
|
||||
req.Header.SetContentLength(len(body))
|
||||
_, err = req.BodyWriter().Write(body)
|
||||
if err != nil {
|
||||
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
|
||||
return
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package adaptor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -485,3 +486,88 @@ func Test_ConvertRequest(t *testing.T) {
|
|||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, "Request URL: /test?hello=world&another=test", string(body))
|
||||
}
|
||||
|
||||
// Benchmark for FiberHandlerFunc
|
||||
func Benchmark_FiberHandlerFunc_1MB(b *testing.B) {
|
||||
fiberH := func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
handlerFunc := FiberHandlerFunc(fiberH)
|
||||
|
||||
// Create body content
|
||||
bodyContent := make([]byte, 1*1024*1024)
|
||||
bodyBuffer := bytes.NewBuffer(bodyContent)
|
||||
|
||||
r := http.Request{
|
||||
Method: http.MethodPost,
|
||||
Body: http.NoBody,
|
||||
}
|
||||
|
||||
// Replace the empty Body with our buffer
|
||||
r.Body = io.NopCloser(bodyBuffer)
|
||||
defer r.Body.Close() //nolint:errcheck // not needed
|
||||
|
||||
// Create recorder
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
handlerFunc.ServeHTTP(w, &r)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_FiberHandlerFunc_10MB(b *testing.B) {
|
||||
fiberH := func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
handlerFunc := FiberHandlerFunc(fiberH)
|
||||
|
||||
// Create body content
|
||||
bodyContent := make([]byte, 10*1024*1024)
|
||||
bodyBuffer := bytes.NewBuffer(bodyContent)
|
||||
|
||||
r := http.Request{
|
||||
Method: http.MethodPost,
|
||||
Body: http.NoBody,
|
||||
}
|
||||
|
||||
// Replace the empty Body with our buffer
|
||||
r.Body = io.NopCloser(bodyBuffer)
|
||||
defer r.Body.Close() //nolint:errcheck // not needed
|
||||
|
||||
// Create recorder
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
handlerFunc.ServeHTTP(w, &r)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_FiberHandlerFunc_50MB(b *testing.B) {
|
||||
fiberH := func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
handlerFunc := FiberHandlerFunc(fiberH)
|
||||
|
||||
// Create body content
|
||||
bodyContent := make([]byte, 50*1024*1024)
|
||||
bodyBuffer := bytes.NewBuffer(bodyContent)
|
||||
|
||||
r := http.Request{
|
||||
Method: http.MethodPost,
|
||||
Body: http.NoBody,
|
||||
}
|
||||
|
||||
// Replace the empty Body with our buffer
|
||||
r.Body = io.NopCloser(bodyBuffer)
|
||||
defer r.Body.Close() //nolint:errcheck // not needed
|
||||
|
||||
// Create recorder
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
handlerFunc.ServeHTTP(w, &r)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue