diff --git a/ctx.go b/ctx.go index b2d13c0a..efd6006d 100644 --- a/ctx.go +++ b/ctx.go @@ -49,28 +49,26 @@ const userContextKey contextKey = 0 // __local_user_context__ // //go:generate ifacemaker --file ctx.go --struct DefaultCtx --iface Ctx --pkg fiber --output ctx_interface_gen.go --not-exported true --iface-comment "Ctx represents the Context which hold the HTTP request and response.\nIt has methods for the request query string, parameters, body, HTTP headers and so on." type DefaultCtx struct { - app *App // Reference to *App - route *Route // Reference to *Route - fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx - bind *Bind // Default bind reference - redirect *Redirect // Default redirect reference - req *DefaultReq // Default request api reference - res *DefaultRes // Default response api reference - values [maxParams]string // Route parameter values - viewBindMap sync.Map // Default view map to bind template engine - method string // HTTP method - baseURI string // HTTP base uri - path string // HTTP path with the modifications by the configuration -> string copy from pathBuffer - detectionPath string // Route detection path -> string copy from detectionPathBuffer - treePath string // Path for the search in the tree - pathOriginal string // Original HTTP path - pathBuffer []byte // HTTP path buffer - detectionPathBuffer []byte // HTTP detectionPath buffer - flashMessages redirectionMsgs // Flash messages - indexRoute int // Index of the current route - indexHandler int // Index of the current handler - methodINT int // HTTP method INT equivalent - matched bool // Non use route matched + app *App // Reference to *App + route *Route // Reference to *Route + fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx + bind *Bind // Default bind reference + redirect *Redirect // Default redirect reference + req *DefaultReq // Default request api reference + res *DefaultRes // Default response api reference + values [maxParams]string // Route parameter values + viewBindMap sync.Map // Default view map to bind template engine + method string // HTTP method + baseURI string // HTTP base uri + treePath string // Path for the search in the tree + pathOriginal string // Original HTTP path + flashMessages redirectionMsgs // Flash messages + path []byte // HTTP path with the modifications by the configuration + detectionPath []byte // Route detection path + indexRoute int // Index of the current route + indexHandler int // Index of the current handler + methodINT int // HTTP method INT equivalent + matched bool // Non use route matched } // SendFile defines configuration options when to transfer file with SendFile. @@ -1123,8 +1121,9 @@ func Params[V GenericType](c Ctx, key string, defaultValue ...V) V { // Path returns the path part of the request URL. // Optionally, you could override the path. +// Make copies or use the Immutable setting to use the value outside the Handler. func (c *DefaultCtx) Path(override ...string) string { - if len(override) != 0 && c.path != override[0] { + if len(override) != 0 && string(c.path) != override[0] { // Set new path to context c.pathOriginal = override[0] @@ -1133,7 +1132,7 @@ func (c *DefaultCtx) Path(override ...string) string { // Prettify path c.configDependentPaths() } - return c.path + return c.app.getString(c.path) } // Scheme contains the request protocol string: http or https for TLS requests. @@ -1832,32 +1831,32 @@ func (c *DefaultCtx) XHR() bool { // configDependentPaths set paths for route recognition and prepared paths for the user, // here the features for caseSensitive, decoded paths, strict paths are evaluated func (c *DefaultCtx) configDependentPaths() { - c.pathBuffer = append(c.pathBuffer[0:0], c.pathOriginal...) + c.path = append(c.path[:0], c.pathOriginal...) // If UnescapePath enabled, we decode the path and save it for the framework user if c.app.config.UnescapePath { - c.pathBuffer = fasthttp.AppendUnquotedArg(c.pathBuffer[:0], c.pathBuffer) + c.path = fasthttp.AppendUnquotedArg(c.path[:0], c.path) } - c.path = c.app.getString(c.pathBuffer) // another path is specified which is for routing recognition only // use the path that was changed by the previous configuration flags - c.detectionPathBuffer = append(c.detectionPathBuffer[0:0], c.pathBuffer...) + c.detectionPath = append(c.detectionPath[:0], c.path...) // If CaseSensitive is disabled, we lowercase the original path if !c.app.config.CaseSensitive { - c.detectionPathBuffer = utils.ToLowerBytes(c.detectionPathBuffer) + c.detectionPath = utils.ToLowerBytes(c.detectionPath) } // If StrictRouting is disabled, we strip all trailing slashes - if !c.app.config.StrictRouting && len(c.detectionPathBuffer) > 1 && c.detectionPathBuffer[len(c.detectionPathBuffer)-1] == '/' { - c.detectionPathBuffer = utils.TrimRight(c.detectionPathBuffer, '/') + if !c.app.config.StrictRouting && len(c.detectionPath) > 1 && c.detectionPath[len(c.detectionPath)-1] == '/' { + c.detectionPath = utils.TrimRight(c.detectionPath, '/') } - c.detectionPath = c.app.getString(c.detectionPathBuffer) // Define the path for dividing routes into areas for fast tree detection, so that fewer routes need to be traversed, // since the first three characters area select a list of routes - c.treePath = c.treePath[0:0] + c.treePath = "" const maxDetectionPaths = 3 if len(c.detectionPath) >= maxDetectionPaths { - c.treePath = c.detectionPath[:maxDetectionPaths] + // c.treePath is only used by Fiber and is not exposed to the user + // so we can use utils.UnsafeString instead of c.app.getString + c.treePath = utils.UnsafeString(c.detectionPath[:maxDetectionPaths]) } } @@ -1963,7 +1962,7 @@ func (c *DefaultCtx) getTreePath() string { } func (c *DefaultCtx) getDetectionPath() string { - return c.detectionPath + return c.app.getString(c.detectionPath) } func (c *DefaultCtx) getPathOriginal() string { diff --git a/router.go b/router.go index 795529bd..be289ca5 100644 --- a/router.go +++ b/router.go @@ -180,7 +180,7 @@ func (app *App) next(c *DefaultCtx) (bool, error) { } // Check if it matches the request path - match = route.match(c.detectionPath, c.path, &c.values) + match = route.match(utils.UnsafeString(c.detectionPath), utils.UnsafeString(c.path), &c.values) if !match { // No match, next route continue