情況如下:Node.js http服務器:POST請求的未讀主體會發生什麼?
HTTP連接選項:連接:保持活動狀態。
- HTTP客戶端發送帶有無效驗證的POST請求。 POST請求在內容中有相當數量的內容 - 例如80KB。
- HTTP服務器(使用express和http-auth節點模塊)讀取請求頭(但不是主體),並確定此請求不是授權請求,併發送401響應。
- 現在身體仍然未被服務器讀取,但由於HTTP連接選項爲Connection:keep-alive,TCP連接未關閉。
現在會發生什麼?未讀機構是否會被放棄,或者應用程序代碼是否必須顯式讀取並放棄它以接收來自當前TCP連接的進一步HTTP請求?
UPDATE
我已經寫了簡單的測試腳本。
客戶:
'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);
通過該測試程序,以下行爲wwas觀察:
隨着連接:保持活動,DUP> = 6700時(也就是說,POST數據的大小> = 67,000字節),服務器不再響應第二個請求。
通過這個,我可以猜測Node.js的http服務器代碼並沒有明確地將剩餘的POST數據吃掉,但是當它通過一個套接字讀取頭來讀取整個POST數據時,它可能會意外地執行它並把它交給http解析器,或者發生類似的事情。
誰說身體永遠不會被讀取?你有什麼參考? – jfriend00
@ jfriend00我的意思是應用程序不會讀取正文。 (也許http模塊實際上讀取它) – zeodtr
因此,看起來你有一個假設,沒有人從TCP套接字讀取身體數據,但你不知道這是否是真的。看來你應該首先弄清楚這是否是真的。如果http庫在內存中排列這些數據(等待它由傳入流中的某人讀取),那麼您已經有了答案。 – jfriend00