情况如下:
HTTP 连接选项:连接:保持事件。
- HTTP 客户端发送带有无效身份验证的 POST 请求。 POST 请求在正文中包含相当多的内容 - 例如 80KB。
- HTTP 服务器(使用 express 和 http-auth Node 模块)读取请求 header (但不是正文)并确定此请求不是授权请求,并发送 401 响应。
- 现在正文仍未被服务器读取,但 TCP 连接未关闭,因为 HTTP 连接选项是连接:保持事件状态。
现在发生了什么?未读主体会被静默丢弃,还是应用程序代码必须显式读取并丢弃它才能从当前 TCP 连接接收更多 HTTP 请求?
更新
我已经编写了简单的测试脚本。
客户:
'use strict';
var http = require('http');
function doIt()
{
var postData;
(function ()
{
var i, baseData;
var dup = 6700;
baseData = 'dummy text';
postData = '';
for (i = 0; i < dup; i++)
postData += baseData;
console.log('data length = ' + postData.length);
})();
var agent = new http.Agent(
{
keepAlive: true,
keepAliveMsecs: 30000,
maxSockets: 1
});
var options =
{
host: 'localhost',
port: '9876',
path: '/',
method: 'POST',
headers:
{
'Content-Type': 'plain/text',
'Content-Length': Buffer.byteLength(postData)
},
agent: agent
};
var count = 1;
function doReq()
{
console.log((count++) + ' =========================');
var req = http.request(options, function (res)
{
console.log('status code = ' + res.statusCode);
console.log('headers', res.headers);
res.setEncoding('utf8');
res.on('data', function (chunk)
{
console.log('Response: ' + chunk);
});
res.on('end', function ()
{
setTimeout(doReq, 1000);
});
});
req.on('socket', function (socket)
{
console.log('socket.keepAliveTestId', socket.keepAliveTestId);
if (socket.keepAliveTestId === undefined)
socket.keepAliveTestId = Date.now();
});
req.on('error', function (err)
{
console.log('error:', err);
});
req.write(postData);
req.end();
}
doReq();
}
doIt();
服务器:
'use strict';
var http = require('http');
var express = require('express');
var app = express();
var httpServer = http.createServer(app);
app.use(function (req, res, next)
{
console.log(req.headers);
setTimeout(function ()
{
next(new Error('test error'));
}, 1);
});
app.use(function (err, req, res, next)
{
console.log('returning');
res.status(401).end();
});
httpServer.listen(9876);
通过这个测试程序,观察到以下行为:
使用connection: keep-alive,当dup >= 6700(即POST数据的大小 >= 67,000字节)时,服务器不再响应第2次请求。
据此,我可以猜测 Node.js 的 http 服务器代码并没有显式地吃掉其余的 POST 数据,但是当它通过一个套接字读取带有 header 的整个 POST 数据时,它可能会意外地吃掉并且将它交给 http 解析器,或者发生类似的事情。
最佳答案
每个请求都是一个新请求。它与之前的请求无关,也与 future 的请求无关。
为了保持活力: 一旦您从服务器响应,下一个请求将来自队列(仅针对相同的 TCP 连接)。
对于没有keep-alive的情况: 每次您向服务器请求时,它都会创建连接。
所以你不需要丢弃任何东西,只是对请求的响应。
关于Node.js http 服务器 : what happens to the unread body of the POST request?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39361515/