[request] Some mechanism to add CORS-rules to an endpoint/a router/everything.
Here's what I've found so far:
- Adding a custom decorator won't work for OPTIONS-requests as the routes are tried before the decorators come into play.
- Overriding the
Main#defaultHandlerseems to be the way forward but this feels very "low-level" and introduces some concern-splitting
I'm willing to do some legwork here but I'd like to know if you have any ideas on how this can best be solved.
Overriding the Main#defaultHandler seems to be the way forward but this feels very "low-level" and introduces some concern-splitting
Would it be possible to put into a trait? I could imagin that a user who needs cors could just mix in the trait to their routes.
I think it's a bit trickier—but I may be wrong.
To add CORS in a somewhat convenient manner we'd need to:
- For simple requests, make sure we attach the proper response headers;
- For preflighted requests
-
- intercept OPTIONS requests for all routes and attach an
Access-Control-Allow-Methodsresponse header, listing all methods defined on the endpoint;
- intercept OPTIONS requests for all routes and attach an
-
- allow configuration of the
Originheader and filter incoming requests based and
- allow configuration of the
-
-
- attach an
Access-Control-Allow-Originwith the correct origin if it is allowed or;
- attach an
-
-
-
- reject(?) the request (not sure exactly, I'm new to the CORS specification);
-
- also handle/attach headers for
Access-Control-Allow-Headersand such.
Preferably it should be possible to configure at least some of these aspects.
To get access to an endpoint's allowed methods the only way I found was to apply the CORS-rules to cask.Main by overriding defaultHandler : non-endpoint decorators do not have information about the downstream endpoint, and from my experiments there can only be one endpoint decorator for any given route. This also means the interface you're working against is the underlying undertow (I feel potential in creating more abstraction here, to make it possible to inject custom handling/filtering at the edge of cask, but that's a story on its own.)
Perhaps it is possible to wrap an endpoint decorator with a cors-decorator? That would make things slightly simpler—provided the cors-decorator can access the endpoint-decorator—but would still have to be repeated for all endpoints of a route, as I see no way to automatically attach one.
FYI, I've built a CorsHandler that works in initial tests. See:
- https://github.com/objektwerks/cask/blob/master/src/main/scala/objektwerks/handler/CorsHandler.scala
- https://github.com/objektwerks/cask/blob/master/src/main/scala/objektwerks/Server.scala
Naturally, this can be built multiple ways. Note how a CorsHandler is initialized in Server, which extends cask.Main.