3

The task that we are trying to solve is to set custom response headers for static resources (e.g. Cache-Control) that are exposed in OSGi environment using HttpService.registerResources() method.

What is the best away to achieve this goal given the following details:

  • There could be numerous resource registrations based on the set of 'resource' services. These OSGi services provide information about static resource paths and bundles they reside in. The amount of resource path registrations we anticipate is in between 50 and 200.
  • Implementation should be OSGi-friendly. Usage of Pax Web extensions is acceptable.
  • Implementation should be web server agnostic (e.g. no direct knowledge about Jetty).

Solutions that we have in mind are:

  1. Set response headers in HttpContext.handleSecurity

    • The downside of this approach is that the method for handling security will be also responsible for the logic that is not related to security at all.
  2. Register filter for each registerResource() call using the same URI as the resources URI. Filter will be response for setting response headers.

    • The downside of this approach is that there may be too many filters serving the same purpose. But so far this seems to the easiest solution.
  3. Register one filter on the root path and configure it to set response headers if request URI correspond to a known resource URI path.

    • The downside of this approach is that filter has to be educated to know about resource paths, which means a bit more complex implementation.

We are eager to hear opinions on the suggested solutions and know other alternatives.

Volodymyr Tsukur
  • 275
  • 1
  • 3
  • 10

1 Answers1

2

The Equinox Jetty based HttpService implementation already supports If-None-Match and If-Modified-Since request headers for all resource registrations out of the box.

However, if it really needs to be framework agnostic and compliant with the HttpService standard and you are registering your resources programmatically anyway then I suggest writing your own servlet (eg. like the one from Equinox) which handles resource requests. Instead of using registerResources directly wrap any resource registration using this servlet and registerServlet. You can implement any caching strategy there.

Gunnar
  • 2,264
  • 17
  • 31
  • Thank you for the response. Custom servlet will do the job, however it would be good to reuse default resource fetching implemented by Equinox Jetty or Pax Web Jetty or whatever implementation is underneath. That's why were trying to figure out the way to do it without the need to reimplement resource fetching. – Volodymyr Tsukur Aug 06 '12 at 14:33
  • Yeah, but resource fetching is "the easy" part. The Equinox ResourceServlet just obtains a URL to the resource via Bundle.getEntry() and opens a stream which gets copied to the output stream. Jetty has some additional logic that may cache the resource content in memory (to save disc IO), use direct NIO buffers and may lock the resource as long as the server is running but that's not always wanted. However, you can re-use the code if you like (start at org.eclipse.jetty.servlet.DefaultServlet). – Gunnar Aug 07 '12 at 06:32
  • Yes, but then we are bound to web server implementation (`DefaultServlet`) that we are trying to avoid. – Volodymyr Tsukur Aug 07 '12 at 09:18
  • You are right. Deep in the code there is some logic that assumes a Jetty Connector and an NIOConnector for advanced features. I thought there might be a chance to re-use it in other environments but it won't work. – Gunnar Aug 08 '12 at 06:13