mirror of https://github.com/gofiber/fiber.git
✨ Added decompression cases for Body function (#1402)
* Added decompression cases for Body function * Fixed signature of Body() function * Removed regex, added Header.Peek * Added test case with compression * Added Benchmark, moved compression names to helpers and made them constants * Added long brotli as a constant * Update ctx.go improve Body function * Update ctx.go improve performance * Fixed formatting * Update helpers.go Co-authored-by: RW <rene@gofiber.io>pull/1404/head
parent
843fab720e
commit
2703e92c5d
28
ctx.go
28
ctx.go
|
@ -33,6 +33,7 @@ const maxParams = 30
|
||||||
|
|
||||||
const queryTag = "query"
|
const queryTag = "query"
|
||||||
|
|
||||||
|
|
||||||
// Ctx represents the Context which hold the HTTP request and response.
|
// Ctx represents the Context which hold the HTTP request and response.
|
||||||
// It has methods for the request query string, parameters, body, HTTP headers and so on.
|
// It has methods for the request query string, parameters, body, HTTP headers and so on.
|
||||||
type Ctx struct {
|
type Ctx struct {
|
||||||
|
@ -239,7 +240,32 @@ func (c *Ctx) BaseURL() string {
|
||||||
// Returned value is only valid within the handler. Do not store any references.
|
// Returned value is only valid within the handler. Do not store any references.
|
||||||
// Make copies or use the Immutable setting instead.
|
// Make copies or use the Immutable setting instead.
|
||||||
func (c *Ctx) Body() []byte {
|
func (c *Ctx) Body() []byte {
|
||||||
return c.fasthttp.Request.Body()
|
var err error
|
||||||
|
var encoding string
|
||||||
|
var body []byte
|
||||||
|
// faster than peek
|
||||||
|
c.Request().Header.VisitAll(func(key, value []byte) {
|
||||||
|
if utils.UnsafeString(key) == HeaderContentEncoding {
|
||||||
|
encoding = utils.UnsafeString(value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
switch encoding {
|
||||||
|
case StrGzip:
|
||||||
|
body, err = c.fasthttp.Request.BodyGunzip()
|
||||||
|
case StrBr, StrBrotli:
|
||||||
|
body, err = c.fasthttp.Request.BodyUnbrotli()
|
||||||
|
case StrDeflate:
|
||||||
|
body, err = c.fasthttp.Request.BodyInflate()
|
||||||
|
default:
|
||||||
|
body = c.fasthttp.Request.Body()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []byte(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
// decoderPool helps to improve BodyParser's and QueryParser's performance
|
// decoderPool helps to improve BodyParser's and QueryParser's performance
|
||||||
|
|
46
ctx_test.go
46
ctx_test.go
|
@ -10,6 +10,7 @@ package fiber
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -303,6 +304,49 @@ func Test_Ctx_Body(t *testing.T) {
|
||||||
utils.AssertEqual(t, []byte("john=doe"), c.Body())
|
utils.AssertEqual(t, []byte("john=doe"), c.Body())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// go test -run Test_Ctx_Body_With_Compression
|
||||||
|
func Test_Ctx_Body_With_Compression(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
app := New()
|
||||||
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
||||||
|
defer app.ReleaseCtx(c)
|
||||||
|
c.Request().Header.Set("Content-Encoding", "gzip")
|
||||||
|
var b bytes.Buffer
|
||||||
|
gz := gzip.NewWriter(&b)
|
||||||
|
_, err := gz.Write([]byte("john=doe"))
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
err = gz.Flush()
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
err = gz.Close()
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
c.Request().SetBody(b.Bytes())
|
||||||
|
utils.AssertEqual(t, []byte("john=doe"), c.Body())
|
||||||
|
}
|
||||||
|
|
||||||
|
// go test -v -run=^$ -bench=Benchmark_Ctx_Body_With_Compression -benchmem -count=4
|
||||||
|
func Benchmark_Ctx_Body_With_Compression(b *testing.B){
|
||||||
|
app := New()
|
||||||
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
||||||
|
defer app.ReleaseCtx(c)
|
||||||
|
c.Request().Header.Set("Content-Encoding", "gzip")
|
||||||
|
var buf bytes.Buffer
|
||||||
|
gz := gzip.NewWriter(&buf)
|
||||||
|
_, err := gz.Write([]byte("john=doe"))
|
||||||
|
utils.AssertEqual(b, nil, err)
|
||||||
|
err = gz.Flush()
|
||||||
|
utils.AssertEqual(b, nil, err)
|
||||||
|
err = gz.Close()
|
||||||
|
utils.AssertEqual(b, nil, err)
|
||||||
|
|
||||||
|
c.Request().SetBody(buf.Bytes())
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++{
|
||||||
|
_ = c.Body()
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.AssertEqual(b, []byte("john=doe"), c.Body())
|
||||||
|
}
|
||||||
|
|
||||||
// go test -run Test_Ctx_BodyParser
|
// go test -run Test_Ctx_BodyParser
|
||||||
func Test_Ctx_BodyParser(t *testing.T) {
|
func Test_Ctx_BodyParser(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@ -1633,6 +1677,7 @@ func Test_Ctx_Render(t *testing.T) {
|
||||||
utils.AssertEqual(t, false, err == nil)
|
utils.AssertEqual(t, false, err == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type testTemplateEngine struct {
|
type testTemplateEngine struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
|
@ -2196,6 +2241,7 @@ func Benchmark_Ctx_BodyStreamWriter(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_Ctx_String(t *testing.T) {
|
func Test_Ctx_String(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -684,3 +684,11 @@ const (
|
||||||
NetworkTCP4 = "tcp4"
|
NetworkTCP4 = "tcp4"
|
||||||
NetworkTCP6 = "tcp6"
|
NetworkTCP6 = "tcp6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Compression types
|
||||||
|
const (
|
||||||
|
StrGzip = "gzip"
|
||||||
|
StrBr = "br"
|
||||||
|
StrDeflate = "deflate"
|
||||||
|
StrBrotli = "brotli"
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue