Description

It appears that the path is decoded before matching/routing, leading to erroneous matches when the URL contains %2F.

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    g := gin.Default()
    g.GET("/hello/:param1", func(c *gin.Context) {
        c.String(200, "One parameter: '%s'", c.Param("param1"))
    })
    g.GET("/hello/:param1/:param2", func(c *gin.Context) {
        c.String(200, "Two parameters: '%s' and '%s'", c.Param("param1"), c.Param("param2"))
    })
    g.Run(":9000")
}

Expectations

I expect a path component with %2F to match one path parameter:

$ curl localhost:9000/hello/p1%2Fp2
One parameter: 'p1%2Fp2'

Actual result

~> curl localhost:9000/hello/p1
One parameter: 'p1'
~> curl localhost:9000/hello/p1/p2
Two parameters: 'p1' and 'p2'
~> curl localhost:9000/hello/p1%2Fp2
Two parameters: 'p1' and 'p2'

Environment

  • go version: 1.17.5
  • gin version (or commit ref): v1.7.7
  • operating system: macOS 11.6.2 (darwin/amd64)

Related issues

I suspect that issue 2047 has the same underlying problem.

Comment From: otcirtan

Setting engine.UseRawPath = true resolves this problem. The logging is wrong, though

$ curl localhost:9000/hello/p1%2Fp2
...
[GIN] 2022/01/12 - 00:00:00 | 200 |      14.162µs |             ::1 | GET      "/hello/p1/p2"