我正在编写一个Node.js PUT端点,允许用户上传大型文件。当我通过一个cURL命令测试服务器时,我发现在我的Node.js请求触发之前,整个文件已经“上传”了:
cURL命令
cat ./resource.tif \
| curl \
--progress-bar \
-X PUT \
--data-binary @- \
-H "Content-Type: application/octet-stream" \
https://server.com/path/to/uploaded/resource.tif \
| cat通过测试,我知道https://server.com/path/to/uploaded/resource.tif已经存在了。在我的Node.js代码中,我对此进行测试,并使用409进行响应。
if (exists) {
const msg = 'Conflict. Upload path already exists'
res.writeHead(409, msg)
res.write(msg)
res.end()
return
}我发现只有在上传了整个文件的之后才发送响应。但我不确定该文件是在客户端(即cURL)还是在服务器端缓冲。
无论如何..。如何配置cURL将文件流传递给不需要缓冲的Node.js?
我看到的其他问题/答案--例如,这个(use pipe for curl data)使用了与cat的管道输出相同的方法,或者类似于--binary-data的参数。但在我看到冲突错误之前,这仍然会导致整个文件的处理。
使用mbuffer,如https://stackoverflow.com/a/48351812/3114742中所述
mbuffer \
-i ./myfile.tif \
-r 2M \
| curl \
--progress-bar \
--verbose \
-X PUT \
--data-binary @- \
-H "Content-Type: application/octet-stream" \
http://server.com/path/to/myfile.tif \
| cat这清楚地表明,只有在将整个文件内容读入本地计算机上的内存后,cuRL才会执行请求。
发布于 2022-07-22 06:00:16
当curl收到409响应并结束响应时,它将退出,至少在我的测试中是这样。
允许curl启动上传的是,请求包括标题Expect: 100-continue,这会导致节点http(s)使用默认的checkContinue处理程序。它使用HTTP/1.1 100 Continue和curl对客户端进行响应。
若要阻止客户端启动上载,请通过Expect: 100-continue事件处理checkContinue事件中的请求:
server.on('checkContinue', (req, res) => {
console.log('checkContinue', req.method, req.url)
res.writeHead(409, {'Content-Type':'text/plain'})
res.end('Nope')
})nginx
您希望从nginx获得的流可以通过proxy_request_buffering off;获得。
1 client > proxy : PUT /blah
2a proxy > client : 100 continue
2b proxy > app : PUT /blah
3a client > proxy : start PUT chunks
3b app > proxy : 409/close
4 proxy > client : 409/close
5 client bails with error与客户端接近的409/只应在100继续正常操作后的毫秒范围内(或该应用程序响应的正常延迟)。
流nginx提供的请求缓冲如下:
1 client > proxy : PUT /blah
2 proxy > client : 100 continue
3 client > proxy : PUT _all_ chunks
4 proxy > app : PUT /blah with all chunks
5 app > proxy : 409/close
6 proxy > client : 409/close
7 client completes with errorhttps://stackoverflow.com/questions/73075130
复制相似问题