Description
I ran into this problem while testing implementing internal redirects
How to reproduce
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func Middleware1() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("Middleware 1 - Before")
// Call the next middleware
c.Next()
fmt.Println("Middleware 1 - After")
}
}
func Middleware2() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("Middleware 2 - Before")
c.Next()
// Continue executing the remaining middleware or handler logic
fmt.Println("Middleware 2 - After")
}
}
func Middleware3() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("Middleware 3 - Before")
c.Next()
// Continue executing the remaining middleware or handler logic
fmt.Println("Middleware 3 - After")
}
}
func Middleware4() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("Middleware 4 - Before")
c.Next()
// Continue executing the remaining middleware or handler logic
fmt.Println("Middleware 4 - After")
}
}
func FinalHandler(c *gin.Context) {
fmt.Println("Final Handler")
c.String(http.StatusOK, "Response from final handler")
}
func main() {
router := gin.Default()
v1 := router.Group("/api")
{
v1.Use(Middleware1(), Middleware2(), Middleware3(), Middleware4())
v1.GET("/test", FinalHandler)
}
v2 := router.Group("/router")
{
v2.GET("/index", func(c *gin.Context) {
fmt.Println("改写")
c.Request.URL.Path = "/api/test"
}, func(c *gin.Context) {
fmt.Println("重入")
router.HandleContext(c)
})
}
router.Run(":8080")
}
Expectations
Actual result
Environment
- go version: 1.20
- gin version (or commit ref):v1.9.1
- operating system: Ubuntu 22.4
Comment From: Victoryship
func main() {
router := gin.Default()
v1 := router.Group("/api")
{
v1.Use(Middleware1(), Middleware2(), Middleware3(), Middleware4())
v1.GET("/test", FinalHandler)
}
v2 := router.Group("/router")
{
v2.GET("/index", func(c *gin.Context) {
fmt.Println("改写")
c.Request.URL.Path = "/api/test"
c.Abort()
router.HandleContext(c)
})
}
router.Run(":8080")
}
I can rewrite it like this, but I don't know why
Comment From: YuukanOO
Hi @Victoryship, as per https://jastorey.me/blog/request-rewrite-in-gin.html, your rewrite works because you're cancelling the initial context handling with c.Abort()
to make sure the response buffer is not written twice.
Comment From: Victoryship
Thank you @YuukanOO for answering,I check the source code here to see if it should be modified
that don't need abort