node.js zlib在gunzipping流时返回'Check Headers'错误

时间:2015-07-09 19:37:26

标签: node.js zlib

所以我正在开发nodeschool.io流冒险教程,我遇到了最后一个问题。说明说:

An encrypted, gzipped tar file will be piped in on process.stdin. To beat this
challenge, for each file in the tar input, print a hex-encoded md5 hash of the
file contents followed by a single space followed by the filename, then a
newline.

You will receive the cipher name as process.argv[2] and the cipher passphrase as
process.argv[3]. You can pass these arguments directly through to
`crypto.createDecipher()`.

The built-in zlib library you get when you `require('zlib')` has a
`zlib.createGunzip()` that returns a stream for gunzipping.

The `tar` module from npm has a `tar.Parse()` function that emits `'entry'`
events for each file in the tar input. Each `entry` object is a readable stream
of the file contents from the archive and:

`entry.type` is the kind of file ('File', 'Directory', etc)
`entry.path` is the file path

Using the tar module looks like:

    var tar = require('tar');
    var parser = tar.Parse();
    parser.on('entry', function (e) {
        console.dir(e);
    });
    var fs = require('fs');
    fs.createReadStream('file.tar').pipe(parser);

Use `crypto.createHash('md5', { encoding: 'hex' })` to generate a stream that
outputs a hex md5 hash for the content written to it.

到目前为止,这是我尝试的方法:

var tar = require('tar');
var crypto = require('crypto');
var zlib = require('zlib');
var map = require('through2-map');

var cipherAlg = process.argv[2];
var passphrase = process.argv[3];

var cryptoStream = crypto.createDecipher(cipherAlg, passphrase);
var parser = tar.Parse(); //emits 'entry' events per file in tar input
var gunzip = zlib.createGunzip();

parser.on('entry', function(e) {
    e.pipe(cryptoStream).pipe(map(function(chunk) {
        console.log(chunk.toString());
    }));
});

process.stdin
    .pipe(gunzip)
    .pipe(parser);

我知道它还没有完成,但我的问题是,当我尝试运行它时,输入永远不会被传递到tar文件解析部分。它似乎挂在gunzip的管道上。这是我的确切错误:

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: incorrect header check
    at Zlib._binding.onerror (zlib.js:295:17)

我完全难以接受,因为Zlib的节点文档没有提到标题,除非它有http /请求模块的示例。关于节点的这个错误还有很多其他问题,但大多数使用缓冲区而不是流,所以我找不到问题的相关答案。非常感谢所有帮助

1 个答案:

答案 0 :(得分:0)

我实际上想通了,我应该在解压缩之前解密流。

所以而不是:

process.stdin
    .pipe(gunzip)
    .pipe(parser);

它应该是:

process.stdin
    .pipe(cryptoStream)
    .pipe(gunzip)
    .pipe(parser);