mirror of https://github.com/gofiber/fiber.git
Merge branch 'main' into jiejaitt-feature/filter-logger
commit
eee8737746
2
ctx.go
2
ctx.go
|
@ -1349,7 +1349,7 @@ func (c *DefaultCtx) getLocationFromRoute(route Route, params Map) (string, erro
|
|||
|
||||
for key, val := range params {
|
||||
isSame := key == segment.ParamName || (!c.app.config.CaseSensitive && utils.EqualFold(key, segment.ParamName))
|
||||
isGreedy := segment.IsGreedy && len(key) == 1 && isInCharset(key[0], greedyParameters)
|
||||
isGreedy := segment.IsGreedy && len(key) == 1 && bytes.IndexByte(greedyParameters, key[0]) != -1
|
||||
if isSame || isGreedy {
|
||||
_, err := buf.WriteString(utils.ToString(val))
|
||||
if err != nil {
|
||||
|
|
6
go.mod
6
go.mod
|
@ -12,7 +12,7 @@ require (
|
|||
github.com/tinylib/msgp v1.2.5
|
||||
github.com/valyala/bytebufferpool v1.0.0
|
||||
github.com/valyala/fasthttp v1.59.0
|
||||
golang.org/x/crypto v0.35.0
|
||||
golang.org/x/crypto v0.36.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -24,7 +24,7 @@ require (
|
|||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -32,15 +32,15 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
|||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package keyauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
@ -59,7 +60,10 @@ func New(config ...Config) fiber.Handler {
|
|||
valid, err := cfg.Validator(c, key)
|
||||
|
||||
if err == nil && valid {
|
||||
// Store in both Locals and Context
|
||||
c.Locals(tokenKey, key)
|
||||
ctx := context.WithValue(c.Context(), tokenKey, key)
|
||||
c.SetContext(ctx)
|
||||
return cfg.SuccessHandler(c)
|
||||
}
|
||||
return cfg.ErrorHandler(c, err)
|
||||
|
@ -68,12 +72,20 @@ func New(config ...Config) fiber.Handler {
|
|||
|
||||
// TokenFromContext returns the bearer token from the request context.
|
||||
// returns an empty string if the token does not exist
|
||||
func TokenFromContext(c fiber.Ctx) string {
|
||||
token, ok := c.Locals(tokenKey).(string)
|
||||
if !ok {
|
||||
return ""
|
||||
func TokenFromContext(c any) string {
|
||||
switch ctx := c.(type) {
|
||||
case context.Context:
|
||||
if token, ok := ctx.Value(tokenKey).(string); ok {
|
||||
return token
|
||||
}
|
||||
case fiber.Ctx:
|
||||
if token, ok := ctx.Locals(tokenKey).(string); ok {
|
||||
return token
|
||||
}
|
||||
default:
|
||||
panic("unsupported context type, expected fiber.Ctx or context.Context")
|
||||
}
|
||||
return token
|
||||
return ""
|
||||
}
|
||||
|
||||
// MultipleKeySourceLookup creates a CustomKeyLookup function that checks multiple sources until one is found
|
||||
|
|
|
@ -503,33 +503,67 @@ func Test_TokenFromContext_None(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_TokenFromContext(t *testing.T) {
|
||||
app := fiber.New()
|
||||
// Wire up keyauth middleware to set TokenFromContext now
|
||||
app.Use(New(Config{
|
||||
KeyLookup: "header:Authorization",
|
||||
AuthScheme: "Basic",
|
||||
Validator: func(_ fiber.Ctx, key string) (bool, error) {
|
||||
if key == CorrectKey {
|
||||
return true, nil
|
||||
}
|
||||
return false, ErrMissingOrMalformedAPIKey
|
||||
},
|
||||
}))
|
||||
// Define a test handler that checks TokenFromContext
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
return c.SendString(TokenFromContext(c))
|
||||
// Test that TokenFromContext returns the correct token
|
||||
t.Run("fiber.Ctx", func(t *testing.T) {
|
||||
app := fiber.New()
|
||||
app.Use(New(Config{
|
||||
KeyLookup: "header:Authorization",
|
||||
AuthScheme: "Basic",
|
||||
Validator: func(_ fiber.Ctx, key string) (bool, error) {
|
||||
if key == CorrectKey {
|
||||
return true, nil
|
||||
}
|
||||
return false, ErrMissingOrMalformedAPIKey
|
||||
},
|
||||
}))
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
return c.SendString(TokenFromContext(c))
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||
req.Header.Add("Authorization", "Basic "+CorrectKey)
|
||||
res, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, CorrectKey, string(body))
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||
req.Header.Add("Authorization", "Basic "+CorrectKey)
|
||||
// Send
|
||||
res, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
t.Run("context.Context", func(t *testing.T) {
|
||||
app := fiber.New()
|
||||
app.Use(New(Config{
|
||||
KeyLookup: "header:Authorization",
|
||||
AuthScheme: "Basic",
|
||||
Validator: func(_ fiber.Ctx, key string) (bool, error) {
|
||||
if key == CorrectKey {
|
||||
return true, nil
|
||||
}
|
||||
return false, ErrMissingOrMalformedAPIKey
|
||||
},
|
||||
}))
|
||||
// Verify that TokenFromContext works with context.Context
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
ctx := c.Context()
|
||||
token := TokenFromContext(ctx)
|
||||
return c.SendString(token)
|
||||
})
|
||||
|
||||
// Read the response body into a string
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, CorrectKey, string(body))
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||
req.Header.Add("Authorization", "Basic "+CorrectKey)
|
||||
res, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, CorrectKey, string(body))
|
||||
})
|
||||
|
||||
t.Run("invalid context type", func(t *testing.T) {
|
||||
require.Panics(t, func() {
|
||||
_ = TokenFromContext("invalid")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_AuthSchemeToken(t *testing.T) {
|
||||
|
|
13
path.go
13
path.go
|
@ -7,6 +7,7 @@
|
|||
package fiber
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -308,7 +309,7 @@ func (routeParser *routeParser) analyseParameterPart(pattern string, customConst
|
|||
parameterEndPosition = 0
|
||||
case parameterEndPosition == -1:
|
||||
parameterEndPosition = len(pattern) - 1
|
||||
case !isInCharset(pattern[parameterEndPosition+1], parameterDelimiterChars):
|
||||
case bytes.IndexByte(parameterDelimiterChars, pattern[parameterEndPosition+1]) == -1:
|
||||
parameterEndPosition++
|
||||
}
|
||||
|
||||
|
@ -397,16 +398,6 @@ func (routeParser *routeParser) analyseParameterPart(pattern string, customConst
|
|||
return n, segment
|
||||
}
|
||||
|
||||
// isInCharset check is the given character in the charset list
|
||||
func isInCharset(searchChar byte, charset []byte) bool {
|
||||
for _, char := range charset {
|
||||
if char == searchChar {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// findNextCharsetPosition search the next char position from the charset
|
||||
func findNextCharsetPosition(search string, charset []byte) int {
|
||||
nextPosition := -1
|
||||
|
|
Loading…
Reference in New Issue