Node.js http服务器:POST请求的未读主体会发生什么?

时间:2016-09-07 05:00:32

标签: node.js http express

情况如下:

HTTP连接选项:连接:keep-alive。

  1. HTTP客户端发送带有无效身份验证的POST请求。 POST请求在正文中有相当多的内容 - 例如,80KB。
  2. HTTP服务器(使用express和http-auth节点模块)读取请求标头(但不是正文),并确定此请求不是授权请求,并发送401响应。
  3. 现在服务器仍未读取正文,但TCP连接未关闭,因为HTTP连接选项为Connection:keep-alive。
  4. 现在发生了什么?是否会以静默方式丢弃未读取的主体,或者应用程序代码必须显式读取并丢弃它以从当前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数据的大小&gt; = 67,000字节)时,服务器不再响应第二个请求。

    通过这个,我可以猜测Node.js的http服务器代码没有明确地消除其余的POST数据,但是当它用头读取整个POST数据时它可能会意外地执行此操作。一个套接字读取并将其交给http解析器,或类似的东西发生。

1 个答案:

答案 0 :(得分:0)

每个请求都是新请求。它与先前的请求或未来的请求无关。

为了保持活力: 一旦您从服务器响应,下一个请求将来自队列(仅适用于相同的TCP连接)。

没有保持活力: 每次您向服务器请求时,它都会创建连接。

所以你不需要丢弃任何东西,只需要回复请求。