Thanks for sharing Lomig! I only skimmed through so far but looks very good already!
I've added it to my board of things to look at in detail, it's a bit long but I hope to get there eventually! You can also add it to the akka.io/community page so people can find it from there :-) (We aim to revamp this site soon-ish). ( you can add it to the list via PRing: https://github.com/akka/akka.github.com/blob/master/community/index.md ) -- Cheers, Konrad 'ktoso’ Malawski Akka @ Lightbend On 16 March 2016 at 22:16:38, Lomig Mégard ([email protected]) wrote: Hi, Jumping in this thread to share the akka-http CORS implementation I have been working on recently: https://github.com/lomigmegard/akka-http-cors The goal was to follow the recommendation from W3C (https://www.w3.org/TR/cors/) and be still easy to use. Not production ready as I would like to write more tests and do some benchmarks. Let me know if you would be interested to have this published to maven. And don't hesitate to open an issue to motivate me :) Cheers, Lomig On Wednesday, 3 February 2016 22:25:40 UTC+1, [email protected] wrote: Seems like as of akka-http 2.0.3 the pre-flight OPTIONS handling via RejectionHandler no longer works as expected - at least if you're trying to use the directive once to wrap all routes. It appears that the behavior of akka-http is to only return the first HttpMethod that was rejected - even if all of them were. As a result, we only are handed the first one - usually GET in the Access-Control-Allow-Methods header, so it looks like: Access-Control-Allow-Methods OPTIONS, GET Which for the following PUT, POST, etc isn't really valid... On Tuesday, October 6, 2015 at 2:47:18 AM UTC-7, Filippo De Luca wrote: Hi, This implementation works fine. But it does not handle a case in which a CORS request has been rejected. The headers are not set on the rejection handler. I don't know if it is an expected behavior or not. If so how we can wrap an existing RejectionHandler to add headers to all the cases? Thanks. On 25 September 2015 at 15:19, Patrik Nordwall <[email protected]> wrote: Thanks for sharing, Patrick. On Tue, Sep 22, 2015 at 1:42 PM, Patrick Ting <[email protected]> wrote: Hi Everyone, I ended up porting and modifying Ganta's original CORS support with an existing one I had that I pulled from the Spray mailing list awhile back and posted it here: https://gist.github.com/pcting/2e65c36f868c5cee7d6a The most frustrating part was finding a way around the loss of RequestContext.withRouteResponseHandling and RequestContext.withHttpResponseHeadersMapped. Please fork it, poke holes int it, and send feedback! Cheers, Patrick On Monday, August 17, 2015 at 1:40:42 PM UTC-7, Austin Guest wrote: Hi Yar. Thanks for getting back! The error message was regarding headers missing from the *server's* response to the actual POST request (it handled the "pre-flight" OPTIONS request just fine, which is why I was puzzled. I've since resolved the question, as it was a matter (as the blog you linked to helpfully pointed out) of the wildcard `*` as a value for the `Allow-Access-Origin` header being incompatible with setting `Allow-Access-Credentials` to `true`. I temporarily resolved the issue by disabling access credentials. Thanks for pointing me in the right direction! :) Not the best long-term fix, but necessary for the time being as a workaround for running locally (since I will always have the origin 'localhost'. As a longer term fix, I plan on using Chrome's Allow-Access-Origin Dev Tools add-on, which spoofs a '*' header for running locally -- just as soon as I can figure out how to get my webpack dev server to disable credentials so the the Allow-Access headers won't conflict. If anyone's stuck on a similar problem and is interested in results, I'm happy to post them here. (Though that set of problem solving would belong more properly on a React mailing list than one pertaining to akka-http! :P) /a/ On Sunday, August 16, 2015 at 5:12:29 AM UTC-4, Yar Ilich wrote: Hi, pleasure to be of use. I got confused: did client part omit headers from POST request? Where did you get the message "No 'Access-Control-Allow-Origin' header is present on the requested resource." from? The problem may be some caveats of using Access-Control-Allow-Origin. See http://www.webdavsystem.com/ajax/programming/cross_origin_requests, specifically the first Important! box. On 16 August 2015 at 10:07, Austin Guest <[email protected]> wrote: Great implementation `yar...`! Question: I borrowed this code in my own implementation but ran into an odd problem where it worked just fine on the preflight `OPTIONS` request, but then omitted the CORS headers from the subsequent `POST` that was getting preflighted, causing the request to be rejected with a 400 Error. ("No 'Access-Control-Allow-Origin' header is present on the requested resource.' etc...) Here's my version of your impl: https://github.com/the-learning-collective/whereat-server/blob/dev/src/main/scala/routes/CorsSupport.scala And here's me using it: https://github.com/the-learning-collective/whereat-server/blob/master/src/main/scala/routes/Routes.scala#L24 Any idea why I'm getting this error? I'm using superagent on the client side (which someone had this CORS-related issue with, but I think that's a red-herring, since I very much want/need my `content-type` to be `application/json`, unlike this user and the proposed solution he winds up being offered.) On Thursday, June 18, 2015 at 12:23:50 PM UTC-4, [email protected] wrote: Hi, I didn't find a counterpart of mapRequestContext in akka-http, so I just allow all the methods I have in my route. Here is my shot at CORS in akka-http: import akka.http.scaladsl.model.HttpMethods._ import akka.http.scaladsl.model.HttpResponse import akka.http.scaladsl.model.headers._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.{AuthenticationFailedRejection, Directive0, RejectionHandler, Route} import com.typesafe.config.ConfigFactory trait CorsSupport { lazy val allowedOrigin = { val config = ConfigFactory.load() val sAllowedOrigin = config.getString("cors.allowed-origin") HttpOrigin(sAllowedOrigin) } //this directive adds access control headers to normal responses private def addAccessControlHeaders: Directive0 = { mapResponseHeaders { headers => `Access-Control-Allow-Origin`(allowedOrigin) +: `Access-Control-Allow-Credentials`(true) +: `Access-Control-Allow-Headers`("Authorization", "Content-Type", "X-Requested-With") +: headers } } //this handles preflight OPTIONS requests. TODO: see if can be done with rejection handler, //otherwise has to be under addAccessControlHeaders private def preflightRequestHandler: Route = options { complete(HttpResponse(200).withHeaders( `Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE) ) ) } def corsHandler(r: Route) = addAccessControlHeaders { preflightRequestHandler ~ r } } you may notice I take allowed origin from the config file option "cors.allowed-origin". I mix this trait into my class which contains a route I want to handle CORS and wrap the route into corsHandler like so: corsHandler { path("") { ... } } On Tuesday, March 10, 2015 at 4:14:53 PM UTC+2, Ganta Murali Krishna wrote: Hello, I am currently experimenting with Akka-http on one of our modules. Below (or attached) is my current CORS file for spray. I am struggling with conversion, for e.g.: I cant find alternative to mapRequestContext. Can any help me to rewrite/convert this please. So I can use this with akka-http. Any help is appreciated. Regards Murali import spray.http.{HttpMethods, HttpMethod, HttpResponse, AllOrigins} import spray.http.HttpHeaders._ import spray.http.HttpMethods._ import spray.routing._ trait CORSSupport { this: HttpService => private val allowOriginHeader = `Access-Control-Allow-Origin`(AllOrigins) private val optionsCorsHeaders = List( `Access-Control-Allow-Headers`("Origin, X-Requested-With,Authorization,Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, User-Agent,apiKey"), `Access-Control-Max-Age`(1728000)) def cors[T]: Directive0 = mapRequestContext { ctx => ctx.withRouteResponseHandling({ //It is an option requeset for a resource that responds to some other method case Rejected(x) if (ctx.request.method.equals(HttpMethods.OPTIONS) && !x.filter(_.isInstanceOf[MethodRejection]).isEmpty) => { val allowedMethods: List[HttpMethod] = x.filter(_.isInstanceOf[MethodRejection]).map(rejection => { rejection.asInstanceOf[MethodRejection].supported }) ctx.complete(HttpResponse().withHeaders( `Access-Control-Allow-Methods`(OPTIONS, allowedMethods: _*) :: allowOriginHeader :: optionsCorsHeaders )) } }).withHttpResponseHeadersMapped { headers => allowOriginHeader :: headers } } } -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/5RCZIJt7jHo/unsubscribe. To unsubscribe from this group and all its topics, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout. -- Sincerely, Yar Illich -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to the Google Groups "Akka User List" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout. -- Patrik Nordwall Typesafe - Reactive apps on the JVM Twitter: @patriknw -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to the Google Groups "Akka User List" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout. -- Filippo De Luca about.me/FilippoDeLuca -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to the Google Groups "Akka User List" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout. -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to the Google Groups "Akka User List" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout.
