Fiber: ๐Ÿž C.Set duplicate header

Created on 11 Mar 2020  ยท  3Comments  ยท  Source: gofiber/fiber

Fiber version/commit
v1.8.2

Issue description
Just playing around with Fiber, and I have some problem here. In my case, I need to set custom headers dynamically. For example, I need to set content-type taken from database.

The code:

func someRoute(c *fiber.Ctx) {

    for _, responseHeader := range response.Headers {
        c.Set(responseHeader.Key, responseHeader.Value)
    }

    c.Status(response.Status)
    c.Send(response.Body)
}

Let's say one of key from responseHeader.key is content-type and the value is application/json, the result is like this:

>  curl localhost:3000 --head

HTTP/1.1 200 OK
Content-Length: 16
Content-Type: text/plain; charset=utf-8
Content-Type: application/json

Probably we need to override the existing key? Even though this is not a big deal, but this will lead to unpredictable problem.

Expected behavior
Override existing header in case the value is different.

> curl localhost:3000 --head

HTTP/1.1 200 OK
Content-Length: 16
Content-Type: application/json

Steps to reproduce

  • Set custom header via c.Set
  • Try to set existing header

Code snippet

package main

import "github.com/gofiber/fiber"

// Header โ€”
type Header struct {
    Key   string
    Value string
}

// Response โ€”
type Response struct {
    Headers []Header
}

func helloHandler(c *fiber.Ctx) {
    var response = &Response{
        Headers: []Header{
            {
                Key:   "Content-Type",
                Value: "application/json",
            },
        },
    }

    for _, responseHeader := range response.Headers {
        c.Set(responseHeader.Key, responseHeader.Value)
    }

    c.Send("OKOK")
}

func main() {
    app := fiber.New()

    app.Get("/", helloHandler)
    app.Listen(3000)
}

Most helpful comment

I found two problems that causes duplicate headers:

  • c.Set() uses the fasthttp SetCanonical method to set headers, but it assumes that the given key is in canonical form. coNteNt-tyPe will not be normalized into Content-Type and could cause duplicate header problems.
  • Currently app.Get routes are not trigger by HEAD requests ( your example --head ) and the default content-type is used.

Fiber will address these problems in v1.8.3

  • c.Set() will automatically normalize header keys to avoid duplicates.
  • app.Get() will automatically be triggered by HEAD methods if no app.Head() is registered before the app.Get().

I will close this issue if v1.8.3 is released.

All 3 comments

Thanks for opening your first issue here! ๐ŸŽ‰ Be sure to follow the issue template!

I found two problems that causes duplicate headers:

  • c.Set() uses the fasthttp SetCanonical method to set headers, but it assumes that the given key is in canonical form. coNteNt-tyPe will not be normalized into Content-Type and could cause duplicate header problems.
  • Currently app.Get routes are not trigger by HEAD requests ( your example --head ) and the default content-type is used.

Fiber will address these problems in v1.8.3

  • c.Set() will automatically normalize header keys to avoid duplicates.
  • app.Get() will automatically be triggered by HEAD methods if no app.Head() is registered before the app.Get().

I will close this issue if v1.8.3 is released.

Thank you for confirming, can't wait!

Was this page helpful?
0 / 5 - 0 ratings