Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ctx_interface_gen.go

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

31 changes: 25 additions & 6 deletions redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
package fiber

import (
"bytes"
"encoding/hex"
"sync"

"github.com/gofiber/fiber/v3/binder"
"github.com/gofiber/utils/v2"
"github.com/valyala/bytebufferpool"
"github.com/valyala/fasthttp"

"github.com/gofiber/fiber/v3/binder"
)

// Pool for redirection
Expand All @@ -32,14 +35,30 @@ var (

const maxPoolableMapSize = 64

// Cookie name to send flash messages when to use redirection.
// FlashCookieName Cookie name to send flash messages when to use redirection.
const (
FlashCookieName = "fiber_flash"
OldInputDataPrefix = "old_input_data_"
CookieDataSeparator = ","
CookieDataAssigner = ":"
FlashCookieName = "fiber_flash"
)

var flashCookieNeedle = []byte(FlashCookieName + "=")

// hasFlashCookie is on the request hot path and runs on every request/response cycle.
// Keep this cheap for users who don't use flash messages:
// 1) a fast raw-header prefilter to avoid unnecessary cookie parsing,
// 2) an exact cookie lookup to avoid prefix false positives (e.g. fiber_flashX).
func hasFlashCookie(header *fasthttp.RequestHeader) bool {
rawHeaders := header.RawHeaders()
if len(rawHeaders) == 0 {
return false
}

if !bytes.Contains(rawHeaders, flashCookieNeedle) {
return false
}

return header.Cookie(FlashCookieName) != nil
}

// redirectionMsgs is a struct that used to store flash messages and old input data in cookie using MSGP.
// msgp -file="redirect.go" -o="redirect_msgp.go" -unexported
// Cookie payloads are limited to ~4KB, so keep flash message counts bounded but usable.
Expand Down
15 changes: 4 additions & 11 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package fiber

import (
"bytes"
"fmt"
"slices"
"sync/atomic"
Expand All @@ -14,10 +13,6 @@ import (
"github.com/valyala/fasthttp"
)

// flashCookieNameBytes is a precomputed byte slice for flash cookie detection
// to avoid string-to-bytes conversion on every request
var flashCookieNameBytes = []byte(FlashCookieName)

// Router defines all router handle interface, including app and group router.
type Router interface {
Use(args ...any) Router
Expand Down Expand Up @@ -328,9 +323,8 @@ func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
return
}

// Optional: Check flash messages
rawHeaders := d.Request().Header.RawHeaders()
if len(rawHeaders) > 0 && bytes.Contains(rawHeaders, flashCookieNameBytes) {
// Optional: check flash messages (hot path, see hasFlashCookie).
if hasFlashCookie(&d.Request().Header) {
d.Redirect().parseAndClearFlashMessages()
}
_, err = app.next(d)
Expand All @@ -341,9 +335,8 @@ func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
return
}

// Optional: Check flash messages
rawHeaders := ctx.Request().Header.RawHeaders()
if len(rawHeaders) > 0 && bytes.Contains(rawHeaders, flashCookieNameBytes) {
// Optional: check flash messages (hot path, see hasFlashCookie).
if hasFlashCookie(&ctx.Request().Header) {
ctx.Redirect().parseAndClearFlashMessages()
}
_, err = app.nextCustom(ctx)
Expand Down
26 changes: 26 additions & 0 deletions router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package fiber

import (
"bufio"
"context"
"encoding/json"
"errors"
Expand Down Expand Up @@ -69,6 +70,31 @@ func Test_Route_Handler_Order(t *testing.T) {
require.Equal(t, expectedOrder, order, "Handler order")
}

func Test_hasFlashCookieExactMatch(t *testing.T) {
t.Parallel()

buildRequestWithCookie := func(t *testing.T, cookie string) *fasthttp.Request {
t.Helper()

rawRequest := strings.NewReader(
"GET / HTTP/1.1\r\nHost: localhost\r\nCookie: " + cookie + "\r\n\r\n",
)
req := new(fasthttp.Request)
require.NoError(t, req.Read(bufio.NewReader(rawRequest)))
return req
}

req := buildRequestWithCookie(t, FlashCookieName+"X=not-the-flash-cookie")
require.False(t, hasFlashCookie(&req.Header))

req = buildRequestWithCookie(t, FlashCookieName+"=valid")
require.True(t, hasFlashCookie(&req.Header))

var syntheticReq fasthttp.Request
syntheticReq.Header.Set(HeaderCookie, FlashCookieName+"=valid")
require.False(t, hasFlashCookie(&syntheticReq.Header))
}

func Test_Route_MixedFiberAndHTTPHandlers(t *testing.T) {
t.Parallel()

Expand Down
Loading