mirror of
https://github.com/gin-gonic/gin.git
synced 2025-12-03 05:12:17 +08:00
feat(gin): add option to use escaped path (#4420)
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
52ecf029bd
commit
771dcc6476
16
gin.go
16
gin.go
@ -135,10 +135,16 @@ type Engine struct {
|
||||
AppEngine bool
|
||||
|
||||
// UseRawPath if enabled, the url.RawPath will be used to find parameters.
|
||||
// The RawPath is only a hint, EscapedPath() should be use instead. (https://pkg.go.dev/net/url@master#URL)
|
||||
// Only use RawPath if you know what you are doing.
|
||||
UseRawPath bool
|
||||
|
||||
// UseEscapedPath if enable, the url.EscapedPath() will be used to find parameters
|
||||
// It overrides UseRawPath
|
||||
UseEscapedPath bool
|
||||
|
||||
// UnescapePathValues if true, the path value will be unescaped.
|
||||
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
|
||||
// If UseRawPath and UseEscapedPath are false (by default), the UnescapePathValues effectively is true,
|
||||
// as url.Path gonna be used, which is already unescaped.
|
||||
UnescapePathValues bool
|
||||
|
||||
@ -191,6 +197,7 @@ var _ IRouter = (*Engine)(nil)
|
||||
// - HandleMethodNotAllowed: false
|
||||
// - ForwardedByClientIP: true
|
||||
// - UseRawPath: false
|
||||
// - UseEscapedPath: false
|
||||
// - UnescapePathValues: true
|
||||
func New(opts ...OptionFunc) *Engine {
|
||||
debugPrintWARNINGNew()
|
||||
@ -208,6 +215,7 @@ func New(opts ...OptionFunc) *Engine {
|
||||
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
|
||||
TrustedPlatform: defaultPlatform,
|
||||
UseRawPath: false,
|
||||
UseEscapedPath: false,
|
||||
RemoveExtraSlash: false,
|
||||
UnescapePathValues: true,
|
||||
MaxMultipartMemory: defaultMultipartMemory,
|
||||
@ -683,7 +691,11 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
httpMethod := c.Request.Method
|
||||
rPath := c.Request.URL.Path
|
||||
unescape := false
|
||||
if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
|
||||
|
||||
if engine.UseEscapedPath {
|
||||
rPath = c.Request.URL.EscapedPath()
|
||||
unescape = engine.UnescapePathValues
|
||||
} else if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
|
||||
rPath = c.Request.URL.RawPath
|
||||
unescape = engine.UnescapePathValues
|
||||
}
|
||||
|
||||
49
gin_test.go
49
gin_test.go
@ -720,6 +720,55 @@ func TestEngineHandleContextPreventsMiddlewareReEntry(t *testing.T) {
|
||||
assert.Equal(t, int64(1), handlerCounterV2)
|
||||
}
|
||||
|
||||
func TestEngineHandleContextUseEscapedPathPercentEncoded(t *testing.T) {
|
||||
r := New()
|
||||
r.UseEscapedPath = true
|
||||
r.UnescapePathValues = false
|
||||
|
||||
r.GET("/v1/:path", func(c *Context) {
|
||||
// Path is Escaped, the %25 is not interpreted as %
|
||||
assert.Equal(t, "foo%252Fbar", c.Param("path"))
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/v1/foo%252Fbar", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
func TestEngineHandleContextUseRawPathPercentEncoded(t *testing.T) {
|
||||
r := New()
|
||||
r.UseRawPath = true
|
||||
r.UnescapePathValues = false
|
||||
|
||||
r.GET("/v1/:path", func(c *Context) {
|
||||
// Path is used, the %25 is interpreted as %
|
||||
assert.Equal(t, "foo%2Fbar", c.Param("path"))
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/v1/foo%252Fbar", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
func TestEngineHandleContextUseEscapedPathOverride(t *testing.T) {
|
||||
r := New()
|
||||
r.UseEscapedPath = true
|
||||
r.UseRawPath = true
|
||||
r.UnescapePathValues = false
|
||||
|
||||
r.GET("/v1/:path", func(c *Context) {
|
||||
assert.Equal(t, "foo%25bar", c.Param("path"))
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
w := PerformRequest(r, http.MethodGet, "/v1/foo%25bar")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrepareTrustedCIRDsWith(t *testing.T) {
|
||||
r := New()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user