Search code examples
javascriptjetty

Jetty ResourceHandler serving js.gz file


I have a fairly large js file which is already in gz format server side. It's being used in an html page in the following way

<script type="text/javascript" src="static/code.min.js.gz"></script>

My only use case is Chrome (seems like browsers can be picky) and my understanding is that for Chrome to process this as js, the server needs to return the content with:

Content-Encoding:gzip
Content-Type:application/javascript

I am using Jetty ResourceHandler in the following way, and am not able to get it to produce the headers shown above. Here is my ResourceHandler setup:

ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setResourceBase(...);
ContextHandler contextHandler = new ContextHandler("/static");
contextHandler.setHandler(resourceHandler);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { contextHandler, handler });
server.setHandler(handlers);

I have tried using addMimeMapping and setPrecompressedFormats but didn't succeed with either, possible that I did it wrong

Curl currently looks like this:

curl -i http://localhost:8080/static/code.min.js.gz
HTTP/1.1 200 OK
Date: Wed, 07 Feb 2024 16:13:22 GMT
Last-Modified: Wed, 07 Feb 2024 14:59:22 GMT
Content-Type: application/gzip
Accept-Ranges: bytes
Content-Length: 390351
Server: Jetty(9.4.z-SNAPSHOT)

If anyone can help me figure out how to setup ResourceHander correctly to move gzip to the encoding I'd appreciate it


Solution

  • The HTML you are using ...

    <script type="text/javascript" src="static/code.min.js.gz"></script>
    

    ... will download a file called code.min.js.gz as-is, compressed and all, with no decompression done by Chrome.

    Do this ...

    • Create both code.min.js (uncompressed) and code.min.js.gz (compressed) in your static resource directory.
    • Change your HTML to not mention the .gz extension.
    <script type="text/javascript" src="static/code.min.js"></script>
    

    That should be it, you now have a static resource that can be served in both compressed and uncompressed form (depending on the capabilities of the user agent / browser)

    What happens is Chrome requests static/code.min.js from Jetty.

    1. Jetty 12's ResourceHandler will first look for what the request says it can handle in based on its request headers. (eg: Content-Encoding: gzip, brotli, compress)
    2. The ResourceHandler will look for each of the supported encoding techniques using the registered extension names. (eg: "gzip" means it looks for <name>.gz)
    3. Serve the compressed version.

    For browsers that do not have compression support (a vanishingly small list) will instead be served <name> from the Resource base directory.