🤕

HTTPレスポンスボディを返す途中でわざとECONRESETを発生させる

2023/02/04に公開

あるHTTPのプロキシサーバーをテストする際に、レスポンスボディを返し始めた後にTCPレベルのエラーが発生するという状況を再現したくなり、そのような挙動をするHTTPサーバーをNode.jsで作ってみました。

なお、Node.js v16.17.0, v18.3.0 以降で追加された socket.resetAndDestroy() 関数を使っています。動作は v16.19.0 で確認しました。

const net = require('net');

const port = 9000
net.createServer()
  .on('connection', handleConnection)
  .on('listening', () => {console.log(`listening on post ${port}`)})
  .listen(port);

function handleConnection(socket) {
  // クライアントからのリクエストをコンソールに表示する。
  socket.on('data', (chunk) => {
    console.log('Received chunk:\n', chunk.toString());
  });
  // Content-Length: 13のうち最初の6バイトだけ返す。
  socket.write('HTTP/1.1 200 OK\r\nServer: my-web-server\r\nContent-Length: 13\r\n\r\nHello,');
  // RSTパケットを送信してTCPコネクションをクローズする。
  socket.resetAndDestroy();
}

適当に broken-server.js などと名前をつけて実行するとポート9000で起動します。

% node broken-server.js
listening on post 9000

このサーバーに対してcurlでリクエストを送ると、レスポンスボディを処理する途中でエラーが発生していることがわかります。

% curl -i http://localhost:9000/
HTTP/1.1 200 OK
Server: my-web-server
Content-Length: 13

curl: (56) Recv failure: Connection reset by peer
Hello,%

参考

Discussion