Rocket icon indicating copy to clipboard operation
Rocket copied to clipboard

FileServer can serve pre-gzipped content if it exists on the filesystem

Open hcldan opened this issue 1 year ago • 1 comments

What's missing?

Rather than having to gzip on the fly, other static file server middleware have the ability to serve a pre-gzipped file based on the file name and extension to avoid the overhead of gzip on the fly (sometimes this feature can even create the gzipped file the first time so subsequent requests can make use of it).

Ideal Solution

At the very minimum, check if there is a .gz file for the resource in question. If there is, use that file content instead, set the appropriate content-encoding, and use the non-gz extension for the content-type.

Why can't this be implemented outside of Rocket?

I tried wrapping the FileServer but I couldn't edit the request to change the URI... and even if I could, I'm not sure that's a really clean way of doing things... because the request wasn't for that file.

Are there workarounds usable today?

Nothing that I've found that is maintainable.

Alternative Solutions

Maybe if fileServer could be given an optional function to help locating the source of the file and adjusting the header.

That could still lead to confusion when trying to set the correct headers based on a previous call to another function that redirected the source of the response. Would make the attempt to unify the response very disjointed.

Additional Context

FileServer lacks gzip capabilities, and issues in the past on this tracker have lamented the performance of gip-on-the-fly approaches.

System Checks

  • [X] I do not believe that this feature can or should be implemented outside of Rocket.
  • [X] I was unable to find a previous request for this feature.

hcldan avatar Jan 31 '24 18:01 hcldan

Sounds like it makes sense. Could also leverage magic bytes for Gzip files as well.

ApprenticeofEnder avatar Feb 02 '24 08:02 ApprenticeofEnder

was kinda surprised this was still missing, but to be fair I've only seen it in other frameworks that don't roll their own solution here. If you can integrate axum/tower then I've used https://docs.rs/tower-http/latest/tower_http/services/struct.ServeDir.html

Flow is:

  1. they are static assets, so you precompress as part of deploy process
  2. your static file handler knows to serve those if they exist and the request accepts the type in the Accept header
let serve_dir = tower_http::services::ServeDir::new("public/assets").precompressed_gzip();

jakswa avatar Jul 27 '24 18:07 jakswa

@jakswa There is a solution merged recently, see https://github.com/the10thWiz/rocket-caching-layer for the implementation. It's only on master right now (although it should be coming with 0.6).

the10thWiz avatar Jul 27 '24 21:07 the10thWiz