Thanks for your contribution!
Describe the bug
when dynamic routing parameters have type judgments, cause cors problem
To Reproduce
Steps to reproduce the behavior:
func main() {
app := iris.New()
app.Use(cors.AllowAll())
app.AllowMethods(iris.MethodOptions)
app.Delete("user/{id}", user.deleteUser) // no cors problem
app.Delete("user/{id:uint64}", user.deleteUser) // has cors problem
_ = app.Run(iris.Addr(":8080"))
}
Expected behavior
Fix it
Desktop (please complete the following information):
@CyJaySong what version of Iris did you try? Because on the master it's already fixed. Here is an example which works fine, cors middleware should work too, if it doesn't then it's something wrong in your settings:
package main
import (
"github.com/kataras/iris/v12"
)
func main() {
app := iris.New()
app.Use(middleware)
app.AllowMethods(iris.MethodOptions)
app.Get("/user/{id}", delUserStr) // no cors problem
app.Get("/user/{id:uint64}", deleteUserInt) // has cors problem
app.Listen(":8080")
}
func middleware(ctx iris.Context) {
id := ctx.Params().GetEntry("id")
ctx.Application().Logger().Infof("middleware ID entry: %v and type of: %T", id.ValueRaw, id.ValueRaw)
ctx.Next()
}
func delUserStr(ctx iris.Context) {
id := ctx.Params().Get("id")
ctx.Writef("id: %v", id)
}
func deleteUserInt(ctx iris.Context) {
id := ctx.Params().GetUint64Default("id", 0)
ctx.Writef("id: %v | Type: %T\n", id, id)
}
@kataras v12.1.8,your example not use cors middleware
@CyJaySong it doesn't matter, it uses a middleware. If there was a problem with "type judgments" that middleware wouldn't be fired, the cors middleware works exactly the same. However, thanks for your bug report. In fact, that is a duplication of that: https://github.com/kataras/iris/issues/1549.
The problem is already fixed on master v12.2.0 branch as said above, test it by yourself:
$ cd YOUR_PROJECT_PATH
$ go get -u github.com/kataras/iris/v12@master
$ go run .
And tell me that it didn't work, please close the issue if works as expected. Thank you a lot, and don't hesitate to ask more!
It seems to be solved。 If I meet it again, I will ask. Thanks for your contribution!
You are welcome @CyJaySong!
sir, there are new problem.When two methods use the same route with dynamic parameters, CORS problem is caused
package main
import (
"github.com/kataras/iris/v12"
)
func main() {
app := iris.New()
app.Use(middleware)
app.AllowMethods(iris.MethodOptions)
app.Get("/user/{id:uint64}", getUser)
app.Patch("/user/{id:uint64}", editUser)
app.Listen(":8080")
}
func middleware(ctx iris.Context) {
id := ctx.Params().GetEntry("id")
ctx.Application().Logger().Infof("middleware ID entry: %v and type of: %T", id.ValueRaw, id.ValueRaw)
ctx.Next()
}
func getUser(ctx iris.Context) {
id := ctx.Params().GetUint64Default("id")
ctx.Writef("id: %v", id)
}
func editUser(ctx iris.Context) {
id := ctx.Params().GetUint64Default("id", 0)
ctx.Writef("id: %v | Type: %T\n", id, id)
}
version: v12.2.0-alpha
@CyJaySong Hmm can you give me a full repository example, so I can run and test? I don't believe there is an issue with CORS and more methods with the same path pattern, cors middleware has nothing to do with the router builder itself.
@CyJaySong There is nothing on the client folder. How can I see the code you used on the client-side?
@kataras Sorry,try again
@CyJaySong replace app.Use(cors.AllowAll()) with app.UseRouter(cors.AllowAll()) and remove the app.AllowMethods(iris.MethodOptions) or better:
```go
api := app.Party("/api")
api.UseRouter(cors.AllowAll())
api.Get("/user", ...)
api.Post("/user", ...)
```
ok, It seems to have been solved. thanks @kataras
I have a question about the above discussion,the following example throws an error. @kataras
package main
import (
"github.com/google/uuid"
"github.com/iris-contrib/middleware/cors"
"github.com/kataras/iris/v12" // v12.2.0-alpha.0.20201126085352-5b6802d00eaf
"github.com/kataras/iris/v12/httptest"
"github.com/kataras/iris/v12/mvc"
"net/http"
"testing"
)
func TestCorsAllowOrigins(t *testing.T) {
origin := "https://iris-go.com"
app := iris.New()
app.UseRouter(cors.AllowAll())
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
ctx := app.ContextPool.Acquire(w, r)
ctx.Values().Set("RequestId", uuid.New().String())
app.ServeHTTPC(ctx)
app.ContextPool.Release(ctx)
})
mvc.New(app.Party("/")).Handle(new(ControllerT1))
e := httptest.New(t, app)
e.GET("/param/1").WithHeader("Origin", origin).Expect().Status(httptest.StatusOK)
e.DELETE("/param/1").WithHeader("Origin", origin).Expect().Status(httptest.StatusOK)
// test options , expect 200, got 404
e.OPTIONS("/param/1").WithHeader("Origin", origin).
WithHeader("Access-Control-Request-Method", "GET").
WithHeader("Access-Control-Request-Headers", "Content-Type").
Expect().Status(httptest.StatusOK)
}
type ControllerT1 struct {
Ctx iris.Context
}
func (*ControllerT1) GetParamBy(id uint) interface{} {
return id
}
func (*ControllerT1) DeleteParamBy(id uint) interface{} {
return id
}
Hello @Ostaer, this is expected as you don't call the router in the app.WrapRouter, instead you call the ServeHTTPC which directly fires the routing matching handler without respecting the app.UseRouter(cors...) - the router filters (UseRouter) ran on main router (router(w,r) inside the app.WrapRouter but you skip this part so these will not ran). You do NOT need to use app.WrapRouter for request id. Instead do that:
import "github.com/kataras/iris/v12/middleware/requestid"
app := iris.New()
app.UseRouter(cors.AllowAll())
app.UseRouter(requestid.New([here you can register your own generator, by-default it uses the google's uuid]))
mvc.New(app.Party("/")).Handle(new(ControllerT1))
// [...]
Most helpful comment
ok, It seems to have been solved. thanks @kataras