Skip to content

Commit

Permalink
ctx: change signatures of GetReqHeaders and GetRespHeaders (#2650)
Browse files Browse the repository at this point in the history
* ctx: change signatures of GetReqHeaders and GetRespHeaders

* fix middlewares
  • Loading branch information
efectn authored Sep 28, 2023
1 parent c0988de commit a9447a5
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 26 deletions.
14 changes: 8 additions & 6 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,11 @@ func (c *Ctx) GetRespHeader(key string, defaultValue ...string) string {
// GetReqHeaders returns the HTTP request headers.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
func (c *Ctx) GetReqHeaders() map[string]string {
headers := make(map[string]string)
func (c *Ctx) GetReqHeaders() map[string][]string {
headers := make(map[string][]string)
c.Request().Header.VisitAll(func(k, v []byte) {
headers[c.app.getString(k)] = c.app.getString(v)
key := c.app.getString(k)
headers[key] = append(headers[key], c.app.getString(v))
})

return headers
Expand All @@ -663,10 +664,11 @@ func (c *Ctx) GetReqHeaders() map[string]string {
// GetRespHeaders returns the HTTP response headers.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
func (c *Ctx) GetRespHeaders() map[string]string {
headers := make(map[string]string)
func (c *Ctx) GetRespHeaders() map[string][]string {
headers := make(map[string][]string)
c.Response().Header.VisitAll(func(k, v []byte) {
headers[c.app.getString(k)] = c.app.getString(v)
key := c.app.getString(k)
headers[key] = append(headers[key], c.app.getString(v))
})

return headers
Expand Down
70 changes: 62 additions & 8 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5117,12 +5117,39 @@ func Test_Ctx_GetRespHeaders(t *testing.T) {

c.Set("test", "Hello, World 👋!")
c.Set("foo", "bar")
c.Response().Header.Set("multi", "one")
c.Response().Header.Add("multi", "two")
c.Response().Header.Set(HeaderContentType, "application/json")

utils.AssertEqual(t, c.GetRespHeaders(), map[string]string{
"Content-Type": "application/json",
"Foo": "bar",
"Test": "Hello, World 👋!",
utils.AssertEqual(t, c.GetRespHeaders(), map[string][]string{
"Content-Type": {"application/json"},
"Foo": {"bar"},
"Multi": {"one", "two"},
"Test": {"Hello, World 👋!"},
})
}

func Benchmark_Ctx_GetRespHeaders(b *testing.B) {
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

c.Response().Header.Set("test", "Hello, World 👋!")
c.Response().Header.Set("foo", "bar")
c.Response().Header.Set(HeaderContentType, "application/json")

b.ReportAllocs()
b.ResetTimer()

var headers map[string][]string
for n := 0; n < b.N; n++ {
headers = c.GetRespHeaders()
}

utils.AssertEqual(b, headers, map[string][]string{
"Content-Type": {"application/json"},
"Foo": {"bar"},
"Test": {"Hello, World 👋!"},
})
}

Expand All @@ -5133,14 +5160,41 @@ func Test_Ctx_GetReqHeaders(t *testing.T) {
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

c.Request().Header.Set("test", "Hello, World 👋!")
c.Request().Header.Set("foo", "bar")
c.Request().Header.Set("multi", "one")
c.Request().Header.Add("multi", "two")
c.Request().Header.Set(HeaderContentType, "application/json")

utils.AssertEqual(t, c.GetReqHeaders(), map[string][]string{
"Content-Type": {"application/json"},
"Foo": {"bar"},
"Test": {"Hello, World 👋!"},
"Multi": {"one", "two"},
})
}

func Benchmark_Ctx_GetReqHeaders(b *testing.B) {
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

c.Request().Header.Set("test", "Hello, World 👋!")
c.Request().Header.Set("foo", "bar")
c.Request().Header.Set(HeaderContentType, "application/json")

utils.AssertEqual(t, c.GetReqHeaders(), map[string]string{
"Content-Type": "application/json",
"Foo": "bar",
"Test": "Hello, World 👋!",
b.ReportAllocs()
b.ResetTimer()

var headers map[string][]string
for n := 0; n < b.N; n++ {
headers = c.GetReqHeaders()
}

utils.AssertEqual(b, headers, map[string][]string{
"Content-Type": {"application/json"},
"Foo": {"bar"},
"Test": {"Hello, World 👋!"},
})
}

Expand Down
4 changes: 2 additions & 2 deletions docs/api/ctx.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ app.Get("/", func(c *fiber.Ctx) error {
Returns the HTTP request headers.

```go title="Signature"
func (c *Ctx) GetReqHeaders() map[string]string
func (c *Ctx) GetReqHeaders() map[string][]string
```

> _Returned value is only valid within the handler. Do not store any references.
Expand Down Expand Up @@ -589,7 +589,7 @@ app.Get("/", func(c *fiber.Ctx) error {
Returns the HTTP response headers.

```go title="Signature"
func (c *Ctx) GetRespHeaders() map[string]string
func (c *Ctx) GetRespHeaders() map[string][]string
```

> _Returned value is only valid within the handler. Do not store any references.
Expand Down
8 changes: 5 additions & 3 deletions middleware/idempotency/idempotency.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ func New(config ...Config) fiber.Handler {

_ = c.Status(res.StatusCode)

for header, val := range res.Headers {
c.Set(header, val)
for header, vals := range res.Headers {
for _, val := range vals {
c.Context().Response.Header.Add(header, val)
}
}

if len(res.Body) != 0 {
Expand Down Expand Up @@ -122,7 +124,7 @@ func New(config ...Config) fiber.Handler {
res.Headers = headers
} else {
// Filter
res.Headers = make(map[string]string)
res.Headers = make(map[string][]string)
for h := range headers {
if _, ok := keepResponseHeadersMap[utils.ToLower(h)]; ok {
res.Headers[h] = headers[h]
Expand Down
2 changes: 1 addition & 1 deletion middleware/idempotency/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package idempotency
type response struct {
StatusCode int `msg:"sc"`

Headers map[string]string `msg:"hs"`
Headers map[string][]string `msg:"hs"`

Body []byte `msg:"b"`
}
29 changes: 24 additions & 5 deletions middleware/idempotency/response_msgp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion middleware/logger/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func createTagMap(cfg *Config) map[string]LogFunc {
TagReqHeaders: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
reqHeaders := make([]string, 0)
for k, v := range c.GetReqHeaders() {
reqHeaders = append(reqHeaders, k+"="+v)
reqHeaders = append(reqHeaders, k+"="+strings.Join(v, ","))
}
return output.Write([]byte(strings.Join(reqHeaders, "&")))
},
Expand Down

0 comments on commit a9447a5

Please sign in to comment.