You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by "Nouwt, B. (Barry)" <ba...@tno.nl.INVALID> on 2020/03/05 13:05:18 UTC

RE: Enable Cross-origin resource sharing (CORS) on embedded Fuseki (jetty)

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 <an...@apache.org> 
Sent: vrijdag 28 februari 2020 15:39
To: users@jena.apache.org
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 <an...@apache.org>
> Sent: dinsdag 25 februari 2020 19:38
> To: users@jena.apache.org
> 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.
>>>