2016-09-07 9 views
1

状況は次のとおりです。Node.js httpサーバー:POSTリクエストの未読本体はどうなりますか?

HTTP接続オプション:接続:キープアライブ。

  1. HTTPクライアントが無効な認証でPOST要求を送信します。 POST要求には、本体にかなりの量のコンテンツが含まれています(たとえば、80KB)。
  2. HTTPサーバー(高速およびhttp-authノードモジュールを使用)は、要求ヘッダー(本文ではない)を読み取り、この要求が許可されていないと判断し、401応答を送信します。
  3. ボディはまだサーバーによって読み取られませんが、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:接続して

:キープアライブ、とき> = 6700 DUP(つまり、POSTデータのサイズ> = 67,000バイト)、サーバーは2回目の要求から応答しなくなりました。

Node.jsのhttpサーバコードが明示的に残りのPOSTデータを食べていないと推測できますが、1つのソケット読み込みでヘッダ付きのPOSTデータ全体を読み込んだときhttpパーサーに渡すか、それと同様のことが起こります。

+0

体は読まれないと誰が言う?あなたはそれについてどのような参照をしていますか? – jfriend00

+0

@ jfriend00私は、アプリケーションが本文を読み込まないことを意味しました。 (たぶんHTTPモジュールが実際にそれを読んでいるかもしれません) – zeodtr

+0

だから、誰もがTCPソケットから身体のデータを読んでいないのに、実際にそれが本当かどうかわからないという仮定があるようです。それが実際に真実であるかどうかを調べることから始めなければならないようです。 httpライブラリーがそのデータをメモリーに入れると(入力ストリームの誰かがそれを読み取るのを待っている)、あなたはすでに答えを得ています。 – jfriend00

答えて

0

すべてのリクエストは新しいリクエストです。以前の要求や今後の要求とは関係がありません。

キープアライブ: サーバからの応答が次のリクエストはキューから来ます(同じTCP接続の場合のみ)。

キープアライブなしの場合: サーバーにリクエストするたびに接続が作成されます。

したがって、何も破棄する必要はなく、要求に対してただ応答します。

+0

重要な点は、TCPはパケットの順序付けられた配信を提供するため、大量のボディデータが送信され、誰もそれを読み取らない場合、接続を介して来る可能性のある次の要求のTCP接続上にあります。同じ接続で別の要求を読み取ることができるようになる前に中断してください。 – jfriend00

+0

@ jfriend00ノードのhttpソースコードの残りの部分を読み込んで破棄する関連するコードを見つけようとしていますが、現在見つからないコードです。 – zeodtr

関連する問題