vite icon indicating copy to clipboard operation
vite copied to clipboard

Dev server should send pre-compressed static files without `Content-Encoding: gzip`

Open mz8i opened this issue 2 years ago • 8 comments

Description

I am serving some pre-compressed .csv.gzip files from the public directory.

The dev server automatically serves these with Content-Type: text/csv and Content-Encoding: gzip.

This seems somewhat overzealous, especially when the requested file explicitly has a .csv.gzip extension and the client code expects the content it receives to be compressed.

The problem is mostly that this doesn't seem to be configurable, which leads to inconsistencies when later deploying to sites without such a behaviour. Consider that GitHub Pages sends the same files as Content-Type: application/gzip which is definitely less unexpected.

For example, I ran into this issue because it turned out that my code was not decompressing the CSV files correctly, but I only realised this after deploying to a server because locally I didn't realise the browser was actually doing the decompression based on Content-Encoding. Now, I know that a lot of hosting services like GH Pages gzip content automatically and send it with Content-Encoding so that the compression is transparent to user code, but when the user specifically requests files that are hosted pre-compressed, the services usually don't interfere, and I think Vite dev server should act the same way.

I personally think this should not be the default behaviour, but at least should be possible to turn off.

Suggested solution

Change the default behaviour to not set Content-Encoding: gzip and Content-Type: [...] but rather send as Content-Type: application/gzip for files that are stored as already compressed.

Alternative

Expose a server configuration toggle to allow for turning the current behaviour off.

Additional context

No response

Validations

mz8i avatar Mar 02 '23 14:03 mz8i

I was also tripped by this behavior. See this question on StackOverflow.

xiaohk avatar Jul 15 '23 03:07 xiaohk

Ran into the same issue. Our application uses JS fetch to get the file contents and expects them to be gzip data that is later extracted with Pako (JS gzip library). But since Vite added the header the browser already extracted the data.

amw avatar Jan 16 '24 23:01 amw

I have the same issue due to vite adding the following response header: (The left side is the abnormal case for vite, the right side is the normal case) image

This answer on Stackoverflow doesn't solve my problem because I can't change the filename. I found a VERY hacky way to fix it:

const gzipFixPlugin = () => {
  const fixHeader = (server) => {
    server.middlewares.use((req, res, next) => {
      if (req.originalUrl?.includes(".dat.gz")) {
        res.setHeader("Content-Type", "application/x-gzip");
        // `res.removeHeader("Content-Encoding")` does not work
        res.setHeader("Content-Encoding", "invalid-value");
      }
      next();
    });
  };

  return {
    name: "gzip-fix-plugin",
    configureServer: fixHeader,
    // vite dev and vite preview use different server, so we need to configure both.
    configurePreviewServer: fixHeader,
  };
};

In the header of the middleware the Content-Encoding is undefined, and setting a value explicitly prevents it from being overwritten by "gzip", but I don't know how that works at all.

I'd appreciate it if someone could explain this.

aiktb avatar May 25 '24 13:05 aiktb

Is the issue with .gzip or .gz? If it's the latter, there's an upstream issue for that https://github.com/lukeed/sirv/issues/158. I'm not sure Vite is affecting it otherwise.

It would be nice to fix the issue upstream fix, before needing Vite to patch it.

bluwy avatar May 27 '24 06:05 bluwy

It's been a while since I originally ran into this, but if my original description is to be trusted, I encountered this with .gzip. I can see the issue you linked mentions .gz only, but I presume this was simply the extension the issue poster was using and the behavior is the same for both extensions. Hopefully the proposed fix tackles both cases.

mz8i avatar May 27 '24 10:05 mz8i

I don't think so based on https://github.com/lukeed/sirv/blob/50b1964b8a8342e14a711d47f793298c2a7aeeb7/packages/sirv/index.js#L95 (also tested locally)

bluwy avatar May 27 '24 10:05 bluwy

Experiencing this with .gz. The CDN serves these files differently so the dev environment gets the content auto gunzipped by the browser but in production it's crashing.

jektvik avatar Jun 12 '24 11:06 jektvik

FYI, I just attempted a PR on upstream to fixed this https://github.com/lukeed/sirv/pull/161. Upstream fix is a little more involved, but if Vite needs to fix this for own usage, then it would be a one liner to comment out Content-Encoding since Vite doesn't use sirv's gzip: true, brotli: true options.

hi-ogawa avatar Aug 13 '24 00:08 hi-ogawa