[英]Node.js: write after end error while writing on file decompressed gzip post data
我在这里写作的原因是遇到了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);
先感谢您。
我解决了它,在与Gunzip相关的“结束”事件中找到了与ws相关的代码。 编辑代码:
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.