gofiber / fiber

⚡️ Express inspired web framework written in Go
https://gofiber.io
MIT License
34.05k stars 1.68k forks source link

🤗 [Question]: How to determine response header length? #2466

Closed Krishnakumar-b closed 1 year ago

Krishnakumar-b commented 1 year ago

Question Description

I was trying to get the content length for response. I am getting 0 as the value.But when I get the response in client , I am getting content length.

I was using the method : c.Response().Header.ContentLength() , and also tried with c.Context().Response.Header.ContentLength() , the result is 0.

Can I please get a response?

Thank you

Code Snippet (optional)

fmt.Println("Length",c.Response().Header.ContentLength())

Checklist:

welcome[bot] commented 1 year ago

Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

leonklingele commented 1 year ago

You can probably add a middleware to achieve this:

app := fiber.New()

app.Use(func(ctx *fiber.Ctx) error {
    if err := c.Next(); err != nil {
        return err
    }

    fmt.Println("Length", c.Response().Header.ContentLength())
})
Krishnakumar-b commented 1 year ago

Thanks for the reponse, But I am doing the same

func limit(c *fiber.Ctx) (err error) { if c.Response().Body() == nil && c.Request().Body() != nil { err = c.Next() if err != nil { return } } fmt.Println("Length",c.Response().Header.ContentLength()) return c.Next() }

leonklingele commented 1 year ago

Sorry, only now got to try this myself.

The logger middleware determines the length as follows: https://github.com/gofiber/fiber/blob/182f9f09705eab40c61a618835d46faee79c1e49/middleware/logger/tags.go#L90-L95

Also, this seems to work:

package main

import (
    "log"
    "net"

    "github.com/gofiber/fiber/v2"
)

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

    app.Use(func(c *fiber.Ctx) error {
        res := c.Response()
        c.Context().Hijack(func(_ net.Conn) {
            log.Printf(
                "Body=%s, length=%d\n",
                res.Body(),
                res.Header.ContentLength(),
            )
        })

        return c.Next()
    })

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World 👋!")
    })

    if err := app.Listen("127.0.0.1:8080"); err != nil {
        log.Panicln(err)
    }
}

Although doing so you'll not be able to determine the number of compressed bytes sent if compression is used.

Does that help @Krishnakumar-b ?

Krishnakumar-b commented 1 year ago

Thanks for the response @leonklingele , I will have a check with this as well.

ReneWerner87 commented 1 year ago

yes because fasthttp is so lazy that they do the calculation of the length only at the end https://github.com/valyala/fasthttp/blob/9bc8e480c444fa6bf54a4cd79091692ceff6011c/http.go#L1447

package main

import (
    "fmt"
    "github.com/gofiber/fiber/v2"
)

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

    app.Use(func(c *fiber.Ctx) error {
        if err := c.Next(); err != nil {
            return err
        }

        fmt.Println("Length", len(c.Response().Body()))

        return nil
    })

    app.Get("/test", func(c *fiber.Ctx) error {
        return c.SendString("abc")
    })

    app.Listen(":3000")
}
Krishnakumar-b commented 1 year ago

This will work; Thanks @ReneWerner87