I have created a the following middleware function but It doesn't seem to be working properly. When I do an options request I get a 404 and I get http: multiple response.WriteHeader calls
in my console.
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
if c.Req.Method == "OPTIONS" {
fmt.Println("options")
c.Abort(200)
return
}
// c.Next()
}
}
I have mounted it as the before anything else with the following.
r.Use(CORSMiddleware())
What gin/go versions are you on? Can you please post a complete, runnable example? This[0] works fine for me.
[0] https://gist.github.com/alexandernyquist/94580423363d3ec95fa8
@alexandernyquist I am using the newest version of gin and I am on go1.3 darwin/amd64. (I just did go get -u . before sending this)
Also I have given you and @manucorporat read permissions to the repo. I think there may be too hard to get a runnable example without the rest of the app.
I think the only dependency the app has is Rethinkdb.
Routes: https://github.com/Lanciv/GoGradeAPI/blob/master/handlers/routes.go
Main: https://github.com/Lanciv/GoGradeAPI/blob/master/main.go
Thanks for the access, however I only have access to a Windows machine at the moment.
I'll see if I can get a VirtualBox running this weekend.
"http: multiple response.WriteHeader calls" will be fixed soon with this: https://github.com/gin-gonic/gin/pull/16
Anyway I think that message is just a warning, it guess it should work.
It's incredible that the standard library do not provide any way to know the current status code.
@alexandernyquist I'll get a VM up for you real quick.
@manucorporat Well I get a 404 and the headers aren't set at all :/
Can you guys do a quick review of this: https://github.com/gin-gonic/gin/issues/24 ? once this is merged, your bug can be fixed easily.
@manucorporat I switched to that commit but I am getting the same error.
Of course! that commit do not fix it, but I need to merge that first :)
@manucorporat Do you know when you will have it done?
@alexandernyquist Would you still like me to get you a vm to test with?
@alexandernyquist I just tested your gist and it is returning a 404 to OPTIONS.
it will be fixed today!
@MattAitchison Have you added route for OPTIONS? Unfortunately, there is no OPTIONS-method in the current master branch (PR coming).
Patching gin.go with a OPTIONS-method:
func (group *RouterGroup) OPTIONS(path string, handlers ...HandlerFunc) {
group.Handle("OPTIONS", path, handlers)
}
And registering the route:
r.OPTIONS("", func (g *gin.Context) {
g.JSON(200, gin.H{"foo":"bar"})
})
Will work.
@alexandernyquist Well I would like to handle OPTIONS inside my middleware. I don't believe I should have to mount the middleware and add a route for OPTIONS. I have added the following route which has fixed the problem for now. I hope it's only temporary.
r.Handle("OPTIONS", "/*cors", []gin.HandlerFunc{CORSMiddleware()})
It looks like the 404 handler sends a 404 before my OPTIONS middleware can write.
Ah, I was a bit too quick there. I'll check it out when I get home.
Just an update, this is already fixed in my local repo
Can you guys try the develop branch? https://github.com/gin-gonic/gin/commit/e1781e2db10b1c3580837491198ea2f7ef3c0ab4
@manucorporat that works like a charm. Nice!
Works now! Thanks!
has someone successful experience with cors?
@qwertmax - Super basic approach but works very well.
r.Use(func(c *gin.Context) {
// Run this on all requests
// Should be moved to a proper middleware
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type,Token")
c.Next()
})
r.OPTIONS("/*cors", func(c *gin.Context) {
// Empty 200 response
})
I'm using smth like this right now.
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "http://domain.com")
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", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
if c.Request.Method == "OPTIONS" {
fmt.Println("OPTIONS")
c.AbortWithStatus(200)
} else {
c.Next()
}
}
}
r.Use(CORSMiddleware())
Hello I am getting multiple headers on 2 nd request.
@shivkumarsingh7 can you describe a little bit more your problem?
I am using middleware with below code
````
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "http://domain.com")
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", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
if c.Request.Method == "OPTIONS" {
fmt.Println("OPTIONS")
c.AbortWithStatus(200)
} else {
c.Next()
}
}
}
r.Use(CORSMiddleware())
````
It's working properly with package "github.com/gin-gonic/gin" but When I am changing package to "gopkg.in/gin-gonic/gin.v1" I am getting multiple headers on 2nd request.
@shivkumarsingh7 may be because you receive 2 responses (OPTIONS and than GET/POST/whatever) ?
@qwertmax apart from the option and one get, post, put or delete I am getting header twice in one response only
Deal with http OPTIONS method currently:
engine := gin.Default() // return *gin.Engine
engine.Use(CorsMW) // incomplete
group := engine.Group("/prefix") // return *gin.RouterGroup
group.GET("/path", handlerFunc)
404 Happend:
engine := gin.Default()
engine := engine.Group("/prefix")
group.Use(CorsMW)
group.GET("/path", handlerFunc)
So we use CorsMiddleware in *gin.Engine will process all CORS correctly.
Most helpful comment
I'm using smth like this right now.