Search code examples
gourl-routinghttphandlergo-gin

How to control behavior for missing URL params in gin 1.4.0+?


I'm working on migrating from 1.3.0 to 1.4.0 (or 1.5.0) and I've discovered that 1.3.0 for the following snippet

router := gin.New()
router.GET("/func/:id/details", func(c *gin.Context) {
    value := c.Param("id")
    fmt.Printf("value is %v\n", value)
})

Would always get to the handler even when requesting /func//details (note the missing URL param) whereas 1.4.0 and above will return 404.

Is it possible to control this behavior? (to work the same way as it worked in 1.3.0?)

I've tried using BindUri introduced in 1.5.0

func main() {
    type Params struct {
        ID string `uri:"id" binding:"required"`
    }
    router := gin.New()
    router.GET("/func/:id/details", func(c *gin.Context) {
        var pp Params
        if err := c.BindUri(&pp); err != nil {
            log.Errorf("failed binding: %v", err)
            c.Status(http.StatusBadRequest)
            return
        }

        log.Printf("params %+v\n", pp)
    })

    if err := router.Run("localhost:8080"); err != nil {
        panic(err)
    }
}

But this also fails (with 404) when called.


Solution

  • I found out that the problem is the internal cleanPath() function with the following documentation:

    ... The following rules are applied iteratively until no further processing can be done:

    1. Replace multiple slashes with a single slash.

    reference

    And if you checkout the latest master branch on Github there is a configuration called RemoveExtraSlash and is false by default. The RemoveExtraSlash by default will not call cleanPath()here.

    What I can see this was added Nov 28 and the latest commit for 1.5.0 was Nov 24.

    What you can do is download the source from GitHub:

    git clone https://github.com/gin-gonic/gin.git /home/user/projects/gin
    

    Then do a replace at the end of your go.mod file. When there is a new release you can just remove the line:

    replace github.com/gin-gonic/gin => /home/user/projects/gin