Hi all,

I enabled CORS on embedded Fuseki (when handling YASGUI SPARQL requests) and 
wanted to share the way I did it for others' benefit. It took me a while to 
figure out how to do this. I found instructions on how to enable CORS via the 
web.xml, but the embedded Fuseki does not use a web.xml (as far as I am aware). 
I also found a lot of examples on how to add the CORS filter in Jetty when you 
control when filters are added. The code at the end of the email enables it in 
my setup.

Some remarks:
- as far as I could see, Fuseki builder does not allow custom filters to be 
chained/configured before the FusekiFilter (which intercepts all traffic to 
datasets).
- adding the CORS filter after the FusekiFilter does not work in case of a 
SPARQL request to a particular dataset, because FusekiFilter intercepts its and 
prevents it from continuing through the filter chain.
- the above two remarks forced me to add the CORS filter directly to the Jetty 
Server, however, it does not allow insertion of filters before other filters, 
it only supports adding it to the end of the chain.
- After succeeding to add my filter before the FusekiFilter, it still did not 
work, because (after some searching) a FilterMapping (to a particular path) is 
also required.
- So, the not so elegant code below retrieves both the filters and the 
filtermappings and inserts the filter (and filtermapping) before the 
FusekiFilter.

Maybe someone can check whether there is an easier way to enable it and 
hopefully it saves somebody a few hours in the future!

Regards, Barry

----------- code to enable CORS for embedded fuseki (note that this code is not 
directly runnable)------------------------------
//... configure server through builder ...

server = builder.build();

Server jettyServer = server.getJettyServer();

/*
 * trying to add the cross origin filter. Fuseki adds its FusekiFilter as the
 * first and this one consumes a SPARQL request to a particular dataset. So, to
 * be able to add the cross origin filter, we have to add it BEFORE the
 * FusekiFilter. This is not as easy as it looks, because you need to add the
 * filter as a filter and as a filtermapping to the /* pathspec.
 */
Handler handler = jettyServer.getHandler();
FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
// we use the default CrossOriginFilter settings, but you can specify them.
//holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
//holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, 
"*");
//holder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, 
"GET,POST,HEAD,OPTIONS");
// holder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM,
//                      "X-Requested-With,Content-Type,Accept,Origin");
assert (handler instanceof ServletContextHandler);
ServletContextHandler h = (ServletContextHandler) handler;
ServletHandler servletHandler = h.getServletHandler();
List<FilterMapping> mappings = new 
ArrayList<FilterMapping>(Arrays.asList(servletHandler.getFilterMappings()));
List<FilterHolder> holders = new 
ArrayList<FilterHolder>(Arrays.asList(servletHandler.getFilters()));
FilterMapping mapping = new FilterMapping();
mapping.setFilterName(holder.getName());
mapping.setPathSpec("/*");
mapping.setDispatcherTypes(EnumSet.of(DispatcherType.REQUEST));
mappings.add(0, mapping);
holders.add(0, holder);
FilterMapping[] mappings3 = new FilterMapping[mappings.size()];
mappings3 = mappings.toArray(mappings3);
FilterHolder[] holders3 = new FilterHolder[holders.size()];
holders3 = holders.toArray(holders3);
servletHandler.setFilters(holders3);
servletHandler.setFilterMappings(mappings3);

server.start();
This message may contain information that is not intended for you. If you are 
not the addressee or if this message was sent to you by mistake, you are 
requested to inform the sender and delete the message. TNO accepts no liability 
for the content of this e-mail, for the manner in which you use it and for 
damage of any kind resulting from the risks inherent to the electronic 
transmission of messages.

Reply via email to