gin icon indicating copy to clipboard operation
gin copied to clipboard

Middleware doesn't apply to Redirect

Open xdays opened this issue 6 years ago • 12 comments

Here's sample code:

package main

import (
	"net/http"

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

//CORSMiddleware ...
func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost")
		c.Writer.Header().Set("Access-Control-Max-Age", "86400")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, x-access-token")
		c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(200)
		} else {
			c.Next()
		}
	}
}

func main() {
	r := gin.Default()
    r.Use(CORSMiddleware())
    g := r.Group("/users")

	g.GET("/", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"hello": "world"})
	})

	r.Run(":8081")
}

Here's normal response with CORS headers.

curl -v localhost:8081/users/                                                       <aws:loop-staging>
*   Trying ::1:8081...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> GET /users/ HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.65.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, x-access-token
< Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, UPDATE
< Access-Control-Allow-Origin: http://localhost
< Access-Control-Expose-Headers: Content-Length
< Access-Control-Max-Age: 86400
< Content-Type: application/json; charset=utf-8
< Date: Fri, 12 Jul 2019 06:27:16 GMT
< Content-Length: 18
<
{"hello":"world"}
* Connection #0 to host localhost left intact

But my CORS header doesn't apear in the 301 redirect response

[14:27] ➜  ~ curl -v localhost:8081/users                                                        <aws:loop-staging>
*   Trying ::1:8081...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> GET /users HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.65.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /users/
< Date: Fri, 12 Jul 2019 06:27:19 GMT
< Content-Length: 42
<
<a href="/users/">Moved Permanently</a>.

* Connection #0 to host localhost left intact

xdays avatar Jul 12 '19 06:07 xdays

Same here did you find a fix?

Louis-Amas avatar May 01 '20 15:05 Louis-Amas

My solution is not using api group for /users to avoid 301 redireciton.

xdays avatar May 02 '20 04:05 xdays

g.GET("", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"hello": "world"})
	})

Try to use this code.

lolgolflol avatar Aug 01 '21 11:08 lolgolflol

still have this problem.

tangx avatar Sep 27 '21 10:09 tangx

and gin, for the present, call middleware after router finding.

https://github.com/gin-gonic/gin/issues/2413

		rg.GET("/", func(c *gin.Context) {
			_url := strings.TrimRight(c.Request.URL.Path, "/") + "?" + c.Request.URL.RawQuery
			c.Redirect(301, _url)
		})

it's ugly, but it works

tangx avatar Sep 27 '21 10:09 tangx

Any updates on this issue?

timqian avatar Feb 13 '23 01:02 timqian

Raised a fix here - https://github.com/gin-gonic/gin/pull/3858

You can directly start using it in your project by running this

go mod edit -replace="github.com/gin-gonic/gin=github.com/yashvardhan-kukreja/gin@issue-3857-onredirect-middleware"  && GOPROXY=direct go get -d ./...

yashvardhan-kukreja avatar Feb 29 '24 02:02 yashvardhan-kukreja