Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Added decompression cases for Body function #1402

Merged
28 changes: 27 additions & 1 deletion ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const maxParams = 30

const queryTag = "query"


// 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.
type Ctx struct {
Expand Down Expand Up @@ -239,7 +240,32 @@ func (c *Ctx) BaseURL() string {
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
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
Expand Down
46 changes: 46 additions & 0 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package fiber
import (
"bufio"
"bytes"
"compress/gzip"
"context"
"errors"
"fmt"
Expand Down Expand Up @@ -303,6 +304,49 @@ func Test_Ctx_Body(t *testing.T) {
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
func Test_Ctx_BodyParser(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -1633,6 +1677,7 @@ func Test_Ctx_Render(t *testing.T) {
utils.AssertEqual(t, false, err == nil)
}


type testTemplateEngine struct {
mu sync.Mutex
templates *template.Template
Expand Down Expand Up @@ -2196,6 +2241,7 @@ func Benchmark_Ctx_BodyStreamWriter(b *testing.B) {
}
}


func Test_Ctx_String(t *testing.T) {
t.Parallel()

Expand Down
8 changes: 8 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,3 +684,11 @@ const (
NetworkTCP4 = "tcp4"
NetworkTCP6 = "tcp6"
)

//Compression types
const (
StrGzip = "gzip"
StrBr = "br"
StrDeflate = "deflate"
StrBrotli = "brotli"
)