Node.js:在文件解压缩gzip发布数据

时间:2017-03-27 19:05:00

标签: javascript node.js http gzip zlib

我在这里写作是因为我遇到了一个我自己无法解决的Node.js问题。让我们只关注我写的简单服务器的POST请求。 我的服务器必须只接受包含gzip压缩数据的POST请求,然后解压缩它们并将提取的内容写入名称位于变量“path”内的本地文件中。 我几乎完成了我刚才解释的所有内容,我也想出了如何解压缩gzip数据,但我无法理解如何将内容写入文件。

POST请求(在Debian上执行)总是如下:

curl -sS -X POST -H "Content-Type: application/gzip" --data-binary @<(echo "Uncompressed data" | gzip) http://192.168.1.66:8080/?path=test.txt

我尝试过多次不同的方式,但尽管在我看来是正确的,执行总是给我这个输出:

Adding Uncompressed data
 to buffer..
Entering ws on finish...
buffer: 'Uncompressed data
'
events.js:163
      throw er; // Unhandled 'error' event
      ^

Error: write after end
    at writeAfterEnd (_stream_writable.js:191:12)
    at WriteStream.Writable.write (_stream_writable.js:238:5)
    at Gunzip.<anonymous> (C:\Users\Public\exercise2.js:54:14)
    at emitNone (events.js:91:20)
    at Gunzip.emit (events.js:188:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)

我的代码就是这个:

const fs   = require('fs');
const http = require('http');
const url  = require('url');
const zlib = require('zlib');
const home = 'C:\\Users\\Public\\server_dir'

function handle_get(path,cb){
    fs.readdir(path,
           (err,files) => {
               if(err) cb(500,JSON.stringify({error : err.message, files: files||null})+'\n')
               else cb(200,JSON.stringify({error : null, files : files})+'\n')
           })
}

function handle_post(req,path,cb){
    function warn(err,event){
        if(err) console.warn(`Request ${event}, could not close ${path}`)
        else console.warn(`Request ${event}, ${path} closed succesfully`)
    }

    console.log("\n\nHeaders="+req.headers+"\n\n")
    var encoding  = req.headers['content-encoding']
    var cont_type = req.headers['content-type']

    if ((encoding == undefined || encoding.indexOf("gzip") <= 0) && cont_type.indexOf("gzip") <= 0)
      return cb(400, JSON.stringify({error : "Bad request: gzip encoding requested"})+'\n')

    fs.open(path,'w',0o644,
        (err,fd)=>
        {
            if(err) return cb(500,JSON.stringify({error : err.message})+'\n')
            const ws=fs.createWriteStream(null,{fd:fd})

            ws.on('finish',() => {
            console.log("Entering ws on finish...");
            cb(200, JSON.stringify({error : null, "written bytes":ws.bytesWritten})+'\n')
            })
            req.on('aborted',()=>fs.close(fd,err=>warn(err,'aborted')))
            req.on('error',(err)=>{
                fs.close(fd,err=>warn(err,'error'))
                cb(500,JSON.stringify({error : err.message, "written bytes":ws.bytesWritten})+'\n')
            })

            var buffer = [];
            var gunzip = zlib.createGunzip();
            gunzip.on('data',function(data) {
            var uncompressed = data.toString();
            console.log("Adding '"+uncompressed+"' to buffer..")
            buffer.push(uncompressed);
            //ws.write(uncompressed); // I've also tried this but it does not work
            }).on('end', function() {
                console.log("buffer: '"+buffer+"'");
                ws.write(buffer.join(""));
                ws.end();
            }).on('error',function(e) {
                console.log("error: "+e);
            })

            req.pipe(gunzip);
            req.pipe(ws);
        })
}

var s=http.createServer(
    (req,res) => {
        console.log("Request: "+req.method+" URL: "+req.url)

        function send(code,json_string){
            res.writeHead(code,{"Content-Type" : "application/json"})
            res.end(json_string)
        }

        if(req.method=='GET') handle_get(home+req.url,send)
        if(req.method=='POST') {
            var parsed_url=url.parse(req.url,true)
            var path=parsed_url.query.path
            console.log(parsed_url);
            if(!path)
                return send(400, JSON.stringify({error : 'Missing path'})+'\n')
            handle_post(req,home+path,send)
        }
  })

s.listen(8080);

提前谢谢。

1 个答案:

答案 0 :(得分:0)

我解决了它,在&#34; end&#34;中找到与ws相关的代码。与Gunzip有关的事件。 编辑代码:

var buffer = [];
var gunzip = zlib.createGunzip();
gunzip.on('data',function(data) {
  var uncompressed = data.toString();
  console.log("Adding "+uncompressed+" to buffer..")
  buffer.push(uncompressed);
  //ws.write(uncompressed); // I've also tried this but it does not work
}).on('end', function() {
  const ws=fs.createWriteStream(null,{fd:fd})
    ws.on('close',() => {
    console.log("Entering ws on finish...");
    cb(200, JSON.stringify({error : null, "written bytes":ws.bytesWritten})+'\n')
  })
  console.log("buffer: '"+buffer+"'");
  ws.write(buffer.join(""));
  ws.end();
}).on('error',function(e) {
  console.log("error: "+e);
})

req.pipe(gunzip);