node-unzipper icon indicating copy to clipboard operation
node-unzipper copied to clipboard

Open.url sample causes Error: Missing content length header

Open yotamshacham opened this issue 3 years ago • 1 comments

When running the sample for extracting from a zip:

const request = require('request'); const unzipper = require('unzipper');

async function main() { const directory = await unzipper.Open.url(request,'http://www2.census.gov/geo/tiger/TIGER2015/ZCTA5/tl_2015_us_zcta510.zip'); const file = directory.files.find(d => d.path === 'tl_2015_us_zcta510.shp.iso.xml'); const content = await file.buffer(); console.log(content.toString()); }

main();

Receiving the following error:

(node:90142) UnhandledPromiseRejectionWarning: Error: Missing content length header at Request. (/Users/yotamshacham/WORK/zip-file-collector/node_modules/unzipper/lib/Open/index.js:63:22) at Request.emit (events.js:375:28) at Request.onRequestResponse (/Users/yotamshacham/WORK/zip-file-collector/node_modules/request/request.js:1059:10) at ClientRequest.emit (events.js:375:28) at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:647:27) at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17) at TLSSocket.socketOnData (_http_client.js:515:22) at TLSSocket.emit (events.js:375:28) at addChunk (internal/streams/readable.js:290:12) at readableAddChunk (internal/streams/readable.js:265:9) at TLSSocket.Readable.push (internal/streams/readable.js:204:10) at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23)

I'm using node v14.17.1, "request": "2.88.2", "unzipper": "0.10.11"

yotamshacham avatar Oct 24 '21 02:10 yotamshacham

This would happen when the remote url doesn't return you the content-length header. There is a method which was recently added to the library

https://github.com/ZJONSSON/node-unzipper/blob/7f83183d4475abeaaa9251d3511c840647bca788/lib/Open/index.js#L98

which can be helpful to provide custom implementation, however that code version is not yet released.

In current version of this library, you can call the library internal function which is not exposed directly to get the desired result you want

const directoryService = require("unzipper/lib/Open/directory");
const got = require('got');

const directory = await directoryService({ 
    size: () => Promise.resolve(1000) /*return size of the object using whatever method*/, 
    stream: () => got.stream(url, { headers })/*return your stream*/ 
});

mnsrulz avatar Jan 19 '22 03:01 mnsrulz