diff --git a/ctx.go b/ctx.go index 68536c9a24..df2b754f86 100644 --- a/ctx.go +++ b/ctx.go @@ -578,6 +578,30 @@ func (c *Ctx) GetRespHeader(key string, defaultValue ...string) string { return defaultString(c.app.getString(c.fasthttp.Response.Header.Peek(key)), defaultValue) } +// 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) + c.Request().Header.VisitAll(func(k, v []byte) { + headers[string(k)] = c.app.getString(v) + }) + + return headers +} + +// 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) + c.Response().Header.VisitAll(func(k, v []byte) { + headers[string(k)] = c.app.getString(v) + }) + + return headers +} + // Hostname contains the hostname derived from the X-Forwarded-Host or Host HTTP header. // Returned value is only valid within the handler. Do not store any references. // Make copies or use the Immutable setting instead. diff --git a/ctx_test.go b/ctx_test.go index 28c0894d6b..7591372d33 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -2752,6 +2752,40 @@ func Test_Ctx_GetRespHeader(t *testing.T) { utils.AssertEqual(t, c.GetRespHeader(HeaderContentType), "application/json") } +// go test -run Test_Ctx_GetRespHeaders +func Test_Ctx_GetRespHeaders(t *testing.T) { + app := New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + + c.Set("test", "Hello, World 👋!") + c.Set("foo", "bar") + c.Response().Header.Set(HeaderContentType, "application/json") + + utils.AssertEqual(t, c.GetRespHeaders(), map[string]string{ + "Content-Type": "application/json", + "Foo": "bar", + "Test": "Hello, World 👋!", + }) +} + +// go test -run Test_Ctx_GetReqHeaders +func Test_Ctx_GetReqHeaders(t *testing.T) { + 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 👋!", + }) +} + // go test -run Test_Ctx_IsFromLocal func Test_Ctx_IsFromLocal(t *testing.T) { t.Parallel() diff --git a/middleware/logger/README.md b/middleware/logger/README.md index 433cb0dfd0..0ce18dd215 100644 --- a/middleware/logger/README.md +++ b/middleware/logger/README.md @@ -143,8 +143,9 @@ const ( TagLatency = "latency" TagStatus = "status" // response status TagResBody = "resBody" // response body - TagQueryStringParams = "queryParams" // request query parameters - TagBody = "body" // request body + TagReqHeaders = "reqHeaders" + TagQueryStringParams = "queryParams" // request query parameters + TagBody = "body" // request body TagBytesSent = "bytesSent" TagBytesReceived = "bytesReceived" TagRoute = "route" diff --git a/middleware/logger/logger.go b/middleware/logger/logger.go index 20d281c4ff..ad0ce03dbf 100644 --- a/middleware/logger/logger.go +++ b/middleware/logger/logger.go @@ -35,6 +35,7 @@ const ( TagLatency = "latency" TagStatus = "status" TagResBody = "resBody" + TagReqHeaders = "reqHeaders" TagQueryStringParams = "queryParams" TagBody = "body" TagBytesSent = "bytesSent" @@ -244,6 +245,12 @@ func New(config ...Config) fiber.Handler { return appendInt(buf, c.Response().StatusCode()) case TagResBody: return buf.Write(c.Response().Body()) + case TagReqHeaders: + reqHeaders := make([]string, 0) + for k, v := range c.GetReqHeaders() { + reqHeaders = append(reqHeaders, k+"="+v) + } + return buf.Write([]byte(strings.Join(reqHeaders, "&"))) case TagQueryStringParams: return buf.WriteString(c.Request().URI().QueryArgs().String()) case TagMethod: diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index b7b61da14b..3d564cfb19 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -140,7 +140,7 @@ func Test_Logger_All(t *testing.T) { app := fiber.New() app.Use(New(Config{ - Format: "${pid}${referer}${protocol}${ip}${ips}${host}${url}${ua}${body}${route}${black}${red}${green}${yellow}${blue}${magenta}${cyan}${white}${reset}${error}${header:test}${query:test}${form:test}${cookie:test}${non}", + Format: "${pid}${reqHeaders}${referer}${protocol}${ip}${ips}${host}${url}${ua}${body}${route}${black}${red}${green}${yellow}${blue}${magenta}${cyan}${white}${reset}${error}${header:test}${query:test}${form:test}${cookie:test}${non}", Output: buf, })) @@ -148,7 +148,7 @@ func Test_Logger_All(t *testing.T) { utils.AssertEqual(t, nil, err) utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode) - expected := fmt.Sprintf("%dhttp0.0.0.0example.com/?foo=bar/%s%s%s%s%s%s%s%s%s-", os.Getpid(), cBlack, cRed, cGreen, cYellow, cBlue, cMagenta, cCyan, cWhite, cReset) + expected := fmt.Sprintf("%dHost=example.comhttp0.0.0.0example.com/?foo=bar/%s%s%s%s%s%s%s%s%s-", os.Getpid(), cBlack, cRed, cGreen, cYellow, cBlue, cMagenta, cCyan, cWhite, cReset) utils.AssertEqual(t, expected, buf.String()) }