The Issue
the following config leads to some odd interactions with my streaming fiber handler.
config:
app := fiber.New()
app.Use(slogfiber.NewWithConfig(slog.Default(),
slogfiber.Config{
WithRequestID: true,
},
))
my fiber handler, say GET /foo, uses c.Context().SetBodyStreamWriter(func(w *bufio.Writer)) to stream the response body to the client in chunks.
Response Headers With slogfiber
HTTP/1.1 200 OK
Date: Thu, 02 Jan 2025 01:11:41 GMT
Content-Type: text/event-stream // set by me
Content-Length: 25044 // crux of the issue
X-Request-Id: e8f629e6-d90b-498c-8d0b-f2aa148532ab // from the `WithRequestID: true`
Cache-Control: no-cache // set by me
Transfer-Encoding header missing despite being set with c.Set("Transfer-Encoding", "chunked")
Response Headers Without slogfiber
HTTP/1.1 200 OK
Date: Wed, 01 Jan 2025 01:12:31 GMT
Content-Type: text/event-stream // set by me
Cache-Control: no-cache // set by me
Transfer-Encoding: chunked
Explanation of the Issue
to stream to the client in chunks using theTransfer-Encoding: chunked header, there is one key note:
per the mdn web docs,
The Content-Length header must be omitted
because slogfiber includes response information of the form
{
"response": {
"time": "...",
"latency": 0,
"status": 200,
"length": 123 // crux of the issue
}
}
this call responseAttributes = append(responseAttributes, slog.Int("length", len(c.Response().Body())))
causes the Content-Length: 123 header to be populated, messing up the Transfer-Encoding: chunked header and thus breaking my streaming implementation.
Attempted Workarounds
i tried to add a filter to my config for the impacted streaming route
app := fiber.New()
app.Use(slogfiber.NewWithConfig(slog.Default(),
slogfiber.Config{
WithRequestID: true,
Filters: []slogfiber.Filter{
slogfiber.IgnorePath("/foo"),
},
},
))
however, since the filter check occurs after the problem call (responseAttributes = append(responseAttributes, slog.Int("length", len(c.Response().Body())))), the Content-Length: 123 header is still populated.
SetBodyStreamWriter sets the contentLength to the bodySize of -1, however, slogfiber's call to c.Response().Body() repopulates contentLength, thus the fasthttp.ResponseHeader.SetContentLength func deletes the Transfer-Encoding header
Solution
i can open a pr moving the filter check to the top of the returned handler (middleware), before the potentially problematic calls
The Issue
the following config leads to some odd interactions with my streaming fiber handler.
config:
my fiber handler, say
GET /foo, usesc.Context().SetBodyStreamWriter(func(w *bufio.Writer))to stream the response body to the client in chunks.Response Headers With slogfiber
Transfer-Encodingheader missing despite being set withc.Set("Transfer-Encoding", "chunked")Response Headers Without slogfiber
Explanation of the Issue
to stream to the client in chunks using the
Transfer-Encoding: chunkedheader, there is one key note:per the mdn web docs,
because slogfiber includes response information of the form
{ "response": { "time": "...", "latency": 0, "status": 200, "length": 123 // crux of the issue } }this call
responseAttributes = append(responseAttributes, slog.Int("length", len(c.Response().Body())))causes the
Content-Length: 123header to be populated, messing up theTransfer-Encoding: chunkedheader and thus breaking my streaming implementation.Attempted Workarounds
i tried to add a filter to my config for the impacted streaming route
however, since the filter check occurs after the problem call (
responseAttributes = append(responseAttributes, slog.Int("length", len(c.Response().Body())))), theContent-Length: 123header is still populated.SetBodyStreamWritersets the contentLength to the bodySize of -1, however, slogfiber's call toc.Response().Body()repopulates contentLength, thus thefasthttp.ResponseHeader.SetContentLengthfunc deletes theTransfer-EncodingheaderSolution
i can open a pr moving the filter check to the top of the returned handler (middleware), before the potentially problematic calls