为什么请求管道在此代码中包含 headers?
Why does the request pipe includes the headers in this code?
关于 http 服务器和管道请求,我有一个奇怪的情况。
根据我过去的经验,当将 http 服务器的请求 object 传送到某种可写流时,它不包括 headers,只包括有效负载。
但是今天,我写了一些非常简单的代码,出于某种原因,我花了过去 2 个小时试图弄清楚为什么它将 headers 写入文件(超级混乱!)
这是我的代码:
server = http.createServer((req, res) => {
f = '/tmp/dest'
console.log(`writing to ${f}`)
s = fs.createWriteStream(f)
req.pipe(s)
req.on('end', () => {
res.end("done")
})
})
server.listen(port)
我用下面的 curl
命令测试它:
curl -XPOST -F 'data=@test.txt' localhost:8080
这就是我在阅读时得到的结果 /tmp/dest
:
--------------------------993d19e02b7578ff
Content-Disposition: form-data; name="data"; filename="test.txt"
Content-Type: text/plain
hello - this is some text
--------------------------993d19e02b7578ff--
为什么我会在这里看到 headers?我希望它只写有效负载
我有一段大约一年前写的代码,它直接流式传输到一个没有 headers 的文件,我不明白有什么不同,但这个代码成功了:
imageRouter.post('/upload', async(req, res) => {
if(!req.is("image/*")) {
let errorMessage = `the /upload destination was hit, but content-type is ${req.get("Content-Type")}`;
console.log(errorMessage);
res.status(415).send(errorMessage);
return;
}
let imageType = req.get("Content-Type").split('/')[1];
let [ err, writeStream ] = await getWritableStream({ suffix: imageType });
if (err) {
console.log("error while trying to write", err);
return res.status(500).end();
}
let imageName = writeStream.getID();
req.on('end', () => {
req.unpipe();
writeStream.close();
res.json({
imageRelativeLink: `/images/${imageName}`,
imageFullLink: `${self_hostname}/images/${imageName}`
});
});
req.pipe(writeStream);
});
有什么不同?为什么我一年前的代码(最后一个块)没有写 form-data/headers?结果文件只是一个图像,没有文本,但是这次(第一个块)在结果文件
中显示了 http headers
尝试使用 on('data') 并参考 req.data 来提取内容,而不是使用管道。这将允许 http 库处理 HTTP body 格式并为您处理“headers”(实际上:表单部分描述符)。
server = http.createServer((req, res) => {
f = '/tmp/dest'
console.log(`writing to ${f}`)
s = fs.createWriteStream(f)
req.on('data', chunk) => {
s.write(chunk);
}
req.on('end', () => {
s.close();
res.end("done")
})
})
server.listen(port)
原来是我理解有误,所以答错了。
我以为是 headers,实际上是 http multipart 规范。这就是 curl
使用此语法时上传文件的方式。
我真正需要的是将我使用 curl 测试代码的方式更改为以下方式之一:
cat /path/to/test/file | curl -T - localhost:8080
# or
curl -T - localhost:8080 < /path/to/test/file
# or
curl -T /path-/to/test/file localhost:8080 < /path/to/test/file
使用 -T
(或 --upload-file
)标志,curl
上传文件(或标准输入)而不用 http 形式包装它。
关于 http 服务器和管道请求,我有一个奇怪的情况。
根据我过去的经验,当将 http 服务器的请求 object 传送到某种可写流时,它不包括 headers,只包括有效负载。
但是今天,我写了一些非常简单的代码,出于某种原因,我花了过去 2 个小时试图弄清楚为什么它将 headers 写入文件(超级混乱!)
这是我的代码:
server = http.createServer((req, res) => {
f = '/tmp/dest'
console.log(`writing to ${f}`)
s = fs.createWriteStream(f)
req.pipe(s)
req.on('end', () => {
res.end("done")
})
})
server.listen(port)
我用下面的 curl
命令测试它:
curl -XPOST -F 'data=@test.txt' localhost:8080
这就是我在阅读时得到的结果 /tmp/dest
:
--------------------------993d19e02b7578ff
Content-Disposition: form-data; name="data"; filename="test.txt"
Content-Type: text/plain
hello - this is some text
--------------------------993d19e02b7578ff--
为什么我会在这里看到 headers?我希望它只写有效负载
我有一段大约一年前写的代码,它直接流式传输到一个没有 headers 的文件,我不明白有什么不同,但这个代码成功了:
imageRouter.post('/upload', async(req, res) => {
if(!req.is("image/*")) {
let errorMessage = `the /upload destination was hit, but content-type is ${req.get("Content-Type")}`;
console.log(errorMessage);
res.status(415).send(errorMessage);
return;
}
let imageType = req.get("Content-Type").split('/')[1];
let [ err, writeStream ] = await getWritableStream({ suffix: imageType });
if (err) {
console.log("error while trying to write", err);
return res.status(500).end();
}
let imageName = writeStream.getID();
req.on('end', () => {
req.unpipe();
writeStream.close();
res.json({
imageRelativeLink: `/images/${imageName}`,
imageFullLink: `${self_hostname}/images/${imageName}`
});
});
req.pipe(writeStream);
});
有什么不同?为什么我一年前的代码(最后一个块)没有写 form-data/headers?结果文件只是一个图像,没有文本,但是这次(第一个块)在结果文件
中显示了 http headers尝试使用 on('data') 并参考 req.data 来提取内容,而不是使用管道。这将允许 http 库处理 HTTP body 格式并为您处理“headers”(实际上:表单部分描述符)。
server = http.createServer((req, res) => {
f = '/tmp/dest'
console.log(`writing to ${f}`)
s = fs.createWriteStream(f)
req.on('data', chunk) => {
s.write(chunk);
}
req.on('end', () => {
s.close();
res.end("done")
})
})
server.listen(port)
原来是我理解有误,所以答错了。
我以为是 headers,实际上是 http multipart 规范。这就是 curl
使用此语法时上传文件的方式。
我真正需要的是将我使用 curl 测试代码的方式更改为以下方式之一:
cat /path/to/test/file | curl -T - localhost:8080
# or
curl -T - localhost:8080 < /path/to/test/file
# or
curl -T /path-/to/test/file localhost:8080 < /path/to/test/file
使用 -T
(或 --upload-file
)标志,curl
上传文件(或标准输入)而不用 http 形式包装它。