Search code examples
javascriptnode.jszlib

How can I ungzip a file and send it in response in Node.js?


I have endpoint where I just serve a file by it's name. The file has .gz format so I have to unzip it before sending in response.

This is a part of the code:

const unzip = zlib.createGunzip();
const rs = fs.createReadStream(filePath);
rs.pipe(unzip).pipe(response);

And with this code I'm getting the size of the file in a browser but it doesn't start downloading, repeats GET request on server and eventually throws an error.

If I remove .pipe(unzip) and just leave it as rs.pipe(response) it serves the file but (obviously) unzipped.

Could you please point out on what I'm doing wrong.


Solution

  • What type of object/stream is response in your question? If it's a native node http.ServerResponse, you'll still need to write the HTTP headers first, perhaps with response.writeHead.

    There's an official example (albeit reversed, compressing the HTTP response instead of decompressing it) in the zlib documentation page. It uses the pipeline function from the node streams API instead of just .pipe but it should give you a good model to follow. Refer to the server bit near the bottom for the writeHead followed by the pipeline:

      /* ... */ {
        response.writeHead(200, { /* whatever headers you need here */ });
        pipeline(raw, zlib.createGzip(), response, onError);
      }
    

    Does this help?