Hi Andy, thanks for the pointers. I've tested the 3.15.0-SNAPSHOT and I can confirm that your FusekiBuilder.enableCors(true) property indeed enables Cross-Origin Resource Sharing on the Fuseki Server. If Fuseki receives a request from the YASGUI instance on another domain, it returns the following cors headers:
Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:1234 Access-Control-Expose-Headers: Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, Pragma Once Apache Jena 3.15.0 comes out I will remove my ugly CORS code that I posted before and replace it by your elegant builder property. Thank you very much! Regards, Barry -----Original Message----- From: Andy Seaborne <[email protected]> Sent: vrijdag 28 februari 2020 15:39 To: [email protected] Subject: Re: Enable Cross-origin resource sharing (CORS) on embedded Fuseki (jetty) Yes, JENA-1846. I have no idea why I wrote 1294. Development builds are at https://repository.apache.org/snapshots Jena version 3.15.0-SNAPSHOT <repositories> <repository> <id>apache.snapshots</id> <name>Apache Snapshot Repository</name> <url>https://repository.apache.org/snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> Thanks Andy On 28/02/2020 09:41, Nouwt, B. (Barry) wrote: > Hi Andy, thanks for filing the JIRA. I'm unsure whether JENA-1294 is the > correct issue, it seems JENA-1846 describes it better. > > Is it possible to use a development build using maven? If so, I might be able > to test it. > > Regards, Barry > > -----Original Message----- > From: Andy Seaborne <[email protected]> > Sent: dinsdag 25 februari 2020 19:38 > To: [email protected] > Subject: Re: Enable Cross-origin resource sharing (CORS) on embedded > Fuseki (jetty) > > JENA-1294 > > I've put in a fixed setup activated by "--cors" - I'd be obliged if people > would try it out and let us know if it works. > > It's in the latest development build #1834. > > Thanks > Andy > > > On 29/01/2020 11:28, Andy Seaborne wrote: >> Barry - thanks for the report >> >> On 28/01/2020 19:28, Nouwt, B. (Barry) wrote: >>> 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. >> >> You are correct - Fuseki main is not a webapp, no war file. >> Fuseki Full, a webapp, does put the CORS filter in. >> >> I thought that servlet filters got added before the Fuseki main >> filter but it sounds like that is not your experience. That would be a bug. >> Could you file a JIRA please? As your code show, getting the order >> right is ... a bit opaque. >> >> The complication is that the Fuseki filter catches "/*" (any URL) >> because the valid names can change as datasets are added to registry >> which is possible at run time. >> >> It might need both "before" and "after" filters. >> >> And/or : It might be a good idea to have an "enableCORS" setting to >> the Fuseki Server builder which will need its own configuration. >> >> Andy >> >>> >>> 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_ORI >>> G >>> IN_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.getFilterMappi >>> n >>> gs())); >>> >>> 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. >>>
