Reputation: 163
I have an embedded Jetty v9.2.10 server with a cross-origin filter (org.eclipse.jetty.servlets.CrossOriginFilter) set up. The server has a REST service on it that I'm trying to POST to using jQuery. The POST attempt gets as far as the OPTIONS request in Firefox; the exchange goes as follows:
Request headers
Host: localhost:8402
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Response headers
Allow: HEAD, POST, GET, OPTIONS
Content-Length: 24
Content-Type: text/plain
Date: Wed, 12 Aug 2015 00:57:35 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(9.2.10.v20150310)
(Notably, none of the Access-Control headers that I would expect to be in the response are there.) If I try it in Chrome, its network debugger tells me that the response to the OPTIONS request is insecure, so I can't even see what comes back, but that's probably a separate issue.
Here is the JavaScript that makes the request:
$(document).ready(function(){
var queryString = URI.parseQuery(URI(window.location.href).search());
var cred = "/*a really long token*/";
$.ajax({
type: "POST",
url: "https://localhost:8402/api/v1/resource/agent/" + queryString.agentId + "/connector?token=" + cred,
data: {
//some JSON
},
success: function(data,status){
alert("Response: " + data + "\nStatus: " + status);
},
crossDomain: true,
contentType: 'application/json'
});
});
Here is the method where I set up the CORS filter on the server:
private void addCorsFilter(ServletContextHandler servletHandler)
{
FilterHolder corsFilter = servletHandler.addFilter(CrossOriginFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
// this string is set to "http(s?)://localhost*" as I have everything running locally right now, but setting to "*" doesn't make a difference
String studioDomain = environmentVariableReader.read(Constants.Env.STUDIO_DOMAIN);
corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, studioDomain);
corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,OPTIONS");
corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
logger.info("cross-origin filter allowing {}", studioDomain);
}
I've tried setting up the CrossOriginFilter using instructions from both of the answers here--as well as wildcarding many of the fields--but most configurations give me the same result. I can provide relevant Jetty logs if they would help.
Upvotes: 1
Views: 259
Reputation: 163
The problem turned out to be unrelated to anything here. Filtering was actually being handled by Guice, and it would delegate to Jetty's filter chain only after it had gone through the filters it knew about and attempted to service the request using a servlet it injected. I didn't know about this, so I hadn't added the CrossOriginFilter
to Guice's ServletModule
. As a result, Guice attempted to service the request using the RESTEasy dispatcher servlet it had injected (hence the response looking like the default HttpServlet.doOptions()
) and wouldn't use Jetty's filter chain because the request had been serviced.
Upvotes: 1