Sagar
Sagar

Reputation: 5596

Jetty ResourceCache vs CachedContentFactory

I am migrating from Jetty 9.0.x to 9.4.x

org.eclipse.jetty.server.ResourceCache is removed from Jetty 9.4.x

Questions:

1) What is the replacement for this class in 9.4.x ?

2) I found CachedContentFactory is the closest equivalent of this class but constructor of this class takes one extra parameter CompressedContentFormat[] precompressedFormats. if this is a correct replacement then I am not sure what should I pass it in for this param? can it be empty array ? Sorry, javadocs did not help a lot either.

Upvotes: 1

Views: 343

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49515

First some history.

Back during the major release Jetty 9.0.0 there were 2 main ways to handle static content: DefaultHandler (and the inferior ResourceHandler).

When major release Jetty 9.4.0 rolled out (this is 4 major version releases of Jetty later then Jetty 9.0.0) an effort was made to make both of those component use a common codebase, so the ResourceService was created to standardize the servicing of static content in a single place. Now the differences between DefaultHandler and ResourceHandler were vastly reduced. (note: DefaultHandler still supports more features of its own and more features of the various HTTP specs)

Next, Issue #539 was resolved to allow the ResourceHandler (and now DefaultHandler) to have customized directory listings. To accomplish this the HttpOutput.ContentFactory interface was introduced.

The new HttpOutput.ContentFactory was responsible for returning the HttpContent representing the path provided (and an optional maximum buffer size configuration option).

So that means, at this point we have ...

  1. A DefaultServlet (or ResourceHandler)
  2. Which has a ResourceService
  3. Which gets it's content from a HttpOutput.ContentFactory
  4. The returned HttpContent can be a static resource, a directory listing, or a welcome file.

When it comes time to send a piece of static content the steps taken are ...

  1. Ask for HttpContent object from HttpOutput.ContentFactory.getContent(path, maxBufferSize)
  2. Ask for representation of HttpContent that can be used to send the referenced content, one of the following (in this order):
    1. If HttpChannel is configured to use "direct buffers", then ask for HttpContent.getDirectBuffer() representing the entire content. (this could be a memory mapped file using a negligible amount of heap memory)
    2. Ask for HttpContent.getIndirectBuffer() representing the entire content. (this could be a memory mapped file using a negligible amount of heap memory)
    3. Ask for HttpContent.getReadableByteChannel() to send content.
    4. Ask for HttpContent.getInputStream() to send content.
  3. Return error indicating "Unknown Content"

There are 2 major implementations of HttpOutput.ContentFactory present in Jetty 9.4.0+

  • ResourceContentFactory which handles transient content (not cached) - if content exceeds maxBufferSize then raw ByteBuffer versions will not be returned.
  • CachedContentFactory which will cache various ByteBuffer values returned from previous HttpOutput usage.

The CachedContentFactory has a isCacheable(Resource) method that is interrogated to know if the supplied resource should enter the in-memory cache or not.

With regards to the CompressedContentFormat[] precompressedFormats parameter in the CachedContentFactory constructor, that refers to the "pre-compressed" formats supported by both the ResourceService and the CachedContentFactory.

Typical, default, setup is ...

CompressedContentFormat[] precompressedFormats = {
    CompressedContentFormat.GZIP, // gzip compressed
    CompressedContentFormat.BR, // brotli compressed
    new CompressedContentFormat("bzip", ".bz") // bzip compressed
};
CachedContentFactory cachedContentFactory = new CachedContentFactory(parentContentFactory,
   resourceFactory, mimeTypes, useFileMappedBuffers,
   useEtags, precompressedFormats);
resourceService.setContentFactory(cachedContentFactory);

These precompressedFormats refer to static (and immutable) content that has been precompressed before server startup.

This allows a client to send a request for say ...

GET /css/main.css HTTP/1.1
Host: example.hostname.com
Accept-Encoding: gzip, deflate

and if the "Base Resource" directory has a ${resource.basedir}/css/main.css AND a ${resource.basedir}/css/main.css.gz then the response will be served from the main.css.gz (not the main.css), resulting in an HTTP response like ...

HTTP/1.1 200 OK
Date: Wed, 15 May 2019 20:17:22 GMT
Vary: Accept-Encoding
Last-Modified: Wed, 15 May 2019 20:17:22 GMT
Content-Type: text/css
ETag: W/"H/6qTDwA8vsH/6rJoEknqc"
Accept-Ranges: bytes
Content-Length: 11222

Upvotes: 1

Related Questions