Hi Henryk, Some additional infos : I'm using jetty component & Camel 2.15.1.redhat-620133.
CORS has been enabled at the level of the REST Configuration ( https://github.com/FuseByExample/rest-dsl-in-action/blob/master/routing/src/main/java/org/jboss/fuse/route/RestToServicesRoute.java) as you can see here. I see from the netty4-http component code that Allow header is returned for OPTIONS request - https://github.com/apache/camel/blob/master/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java#L103-L107 Nevertheless, there is a problem with the logic implemented as we only get a response (= Allow Header) when the path of the URL is created without httpMethodRestrict : https://github.com/apache/camel/blob/master/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpRestOptionsAllowTest.java#L54 If you use the url path like this --> from("netty4-http:http://0.0.0.0:{{port}}/myapp?httpMethodRestrict=OPTIONS"), we don't receive the Allow Header FYI : I have created the verb options to avoid to use verb("") syntax - camel-9129 On Mon, Sep 14, 2015 at 5:46 PM, Henryk Konsek <hekon...@gmail.com> wrote: > Hi Charles, > > You have to enable the CORS on the route DSL configuration, not only on the > routes level. For example here is the REST+Netty combination for Camel > 2.15.1 that works properly with the AngularJS REST client: > > RestPropertyDefinition corsAllowedHeaders = new RestPropertyDefinition(); > corsAllowedHeaders.setKey("Access-Control-Allow-Headers"); > corsAllowedHeaders.setValue("Origin, Accept, X-Requested-With, > Content-Type, Access-Control-Request-Method, > Access-Control-Request-Headers, Authorization"); > > RestConfigurationDefinition restConfiguration = > restConfiguration().component("netty4-http"). > host("0.0.0.0").port(restPort).bindingMode(json). > enableCORS(enableCors).endpointProperty("matchOnUriPrefix", "true"); > > restConfiguration.setCorsHeaders(singletonList(corsAllowedHeaders)); > > rest("*/api/*") > .verb("OPTIONS", "/").route() > .setHeader("Access-Control-Allow-Origin", constant("*")) > .setHeader("Access-Control-Allow-Methods", constant("GET, HEAD, POST, > PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH")) > .setHeader("Access-Control-Allow-Headers", > constant("Origin, Accept, X-Requested-With, Content-Type, > Access-Control-Request-Method, Access-Control-Request-Headers, > Authorization")) > .setHeader("Allow", constant("GET, OPTIONS, POST, PATCH")); > > In general, Camel REST DSL tries to provide the OPTIONS routes for you, so > you don't have to define those, but sometimes it fails to do it properly. I > fixed some of such corner cases for REST+Netty combination in Camel 2.15.1, > but I think that there are some corner cases still to cover. > > The configuration above is the mix of my fixes included in Camel 2.15.1 and > workarounds to make Netty REST API properly consume the requests from > Angular clients. Probably the latest Camel works better in this regards. > > Cheers! > > pon., 14.09.2015 o 14:42 użytkownik Charles Moulliard <ch0...@gmail.com> > napisał: > > > Hi, > > > > I try to see if there is a workaround to avoid this issue (HTTP method > not > > allowed - 405) or If I have to dig into the code to provide a fix > > > > 1) HTTP Method 405 - returned > > > > This REST DSL definition generates a HTTP 405 Method not allowed when > this > > request is issued (http -v OPTIONS http://localhost:9191/blog/article/) > > > > > > > > > rest("/blog/").id("rest-blog-service").produces("application/json").consumes("application/json") > > > > > > > .get("/article/search/user/{user}").id("rest-searchbyuser").outTypeList(Blog.class) > > .to("direct:searchByUser") > > > > .put("/article/").id("rest-put-article").type(Blog.class) > > .to("direct:add") > > > > rest("/blog/article/").id("rest-options") > > .verb("options") > > .route() > > .setHeader("Access-Control-Allow-Origin", constant("*")) > > .setHeader("Access-Control-Allow-Methods", constant("GET, > > HEAD, POST, PUT, DELETE, OPTIONS")) > > .setHeader("Access-Control-Allow-Headers", constant("Origin, > > Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, > > Access-Control-Request-Headers")) > > .setHeader("Allow", constant("GET, HEAD, POST, PUT, DELETE, > > OPTIONS")); > > > > > > http -v options http://localhost:9191/blog/article/ > > OPTIONS /blog/article/ HTTP/1.1 > > Accept: */* > > Accept-Encoding: gzip, deflate > > Connection: keep-alive > > Content-Length: 0 > > Host: localhost:9191 > > User-Agent: HTTPie/0.9.2 > > > > --> > > > > HTTP/1.1 405 Method Not Allowed > > > > endpoints registered > > > > INFO Route: rest-searchbyid started and consuming from: Endpoint[ > > > http://0.0.0.0:9191/blog/article/search/id/%7Bid%7D?httpMethodRestrict=GET > > ] > > INFO Route: rest-searchbyuser started and consuming from: Endpoint[ > > > > > http://0.0.0.0:9191/blog/article/search/user/%7Buser%7D?httpMethodRestrict=GET > > ] > > INFO Route: rest-put-article started and consuming from: Endpoint[ > > http://0.0.0.0:9191/blog/article?httpMethodRestrict=PUT] > > INFO Route: rest-deletearticle started and consuming from: Endpoint[ > > http://0.0.0.0:9191/blog/article/%7Bid%7D?httpMethodRestrict=DELETE] > > INFO Route: route1 started and consuming from: Endpoint[ > > http://0.0.0.0:9191/blog/article?httpMethodRestrict=OPTIONS] > > > > > > while this is not the case If I comment the line with the put as you can > > see hereafter > > > > > > 2) HTTP Method - 200 OK > > > > > > > > > rest("/blog/").id("rest-blog-service").produces("application/json").consumes("application/json") > > > > > > > > > .get("/article/search/user/{user}").id("rest-searchbyuser").outTypeList(Blog.class) > > .to("direct:searchByUser") > > > > /* .put("/article/").id("rest-put-article").type(Blog.class) > > .to("direct:add") */ > > > > rest("/blog/article/").id("rest-options") > > .verb("options") > > .route() > > .setHeader("Access-Control-Allow-Origin", constant("*")) > > .setHeader("Access-Control-Allow-Methods", constant("GET, > > HEAD, POST, PUT, DELETE, OPTIONS")) > > .setHeader("Access-Control-Allow-Headers", constant("Origin, > > Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, > > Access-Control-Request-Headers")) > > .setHeader("Allow", constant("GET, HEAD, POST, PUT, DELETE, > > OPTIONS")); > > > > > > Endpoints > > > > INFO Route: rest-searchbyid started and consuming from: Endpoint[ > > > http://0.0.0.0:9191/blog/article/search/id/%7Bid%7D?httpMethodRestrict=GET > > ] > > INFO Route: rest-searchbyuser started and consuming from: Endpoint[ > > > > > http://0.0.0.0:9191/blog/article/search/user/%7Buser%7D?httpMethodRestrict=GET > > ] > > INFO Route: rest-deletearticle started and consuming from: Endpoint[ > > http://0.0.0.0:9191/blog/article/%7Bid%7D?httpMethodRestrict=DELETE] > > INFO Route: route1 started and consuming from: Endpoint[ > > http://0.0.0.0:9191/blog/article?httpMethodRestrict=OPTIONS] > > > > > > > > http -v OPTIONS http://localhost:9191/blog/article/ > > > > --> > > > > HTTP/1.1 200 OK > > Accept: */* > > Accept-Encoding: gzip, deflate > > Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, > > Content-Type, Access-Control-Request-Method, > Access-Control-Request-Headers > > Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, TRACE, > OPTIONS, > > CONNECT, PATCH > > Access-Control-Allow-Origin: * > > Access-Control-Max-Age: 3600 > > Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS > > > > > > Regards, > > > > -- > > Charles Moulliard > > Apache Committer / Architect @RedHat > > Twitter : @cmoulliard | Blog : http://cmoulliard.github.io > > > -- > Henryk Konsek > http://about.me/hekonsek > -- Charles Moulliard Apache Committer / Architect @RedHat Twitter : @cmoulliard | Blog : http://cmoulliard.github.io