Skip to content

moja0316/browser_retry_test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTP 再送検証

目的

POSTリクエストが再送される条件を探って再現する 同様の現象がstackoverflowで報告されていたため Express + 簡易HTMLで再現

関連しそうな資料

起きてたこと

  • HTTPは以下の条件を満たすとクライアントが再送を試みるようになっている(RFC 2616 8.2.4章に記述)
    • Expect リクエストヘッダがない
    • サーバから何の応答も帰ってこない
    • クライアント <=> サーバのコネクションが切れる
  • 基本ブラウザからのリクエストにはExpect リクエストヘッダはついていないらしい。curlはついているらしい
  • 「応答を返さない」は、node + expressの場合はサーバの実装でres.send()などを一切記述していないエンドポイントにリクエストを飛ばすと出来る
  • またコネクションが切断する要件としてはサーバがLinuxの場合、TCPの再送タイムアウトの最大値が120秒に設定されている(少なくとも実験環境に用いたCentOS7.7のカーネルでは)ため、2分でコネクションが切れる
  • 上記3つの事象が相まって「2分おきに」サーバ側にブラウザからのリクエストのログが残り続ける事象が発生すると考えられる

再現方法

このコードを適当なLinuxにデプロイし

docker build -t moja0316/node-web-app .
docker run --name node-web-app -p 3000:3000  moja0316/node-web-app

とかでいける

再現結果

1つのsleep requestに対し2分後に2つめのrequestをサーバ側で受信している

ブラウザ

スクリーンショット 2021-03-23 2 35 20

サーバ

[root@apps browser_retry_test]# docker run --name node-web-app -p 3000:3000  moja0316/node-web-app
listening on 3000
[Mon Mar 22 2021 17:30:28 GMT+0000 (Coordinated Universal Time)] /hi requrst recieved!!
{ hello: 'world' }
[Mon Mar 22 2021 17:30:38 GMT+0000 (Coordinated Universal Time)] /sleep requrst recieved!!
{ hello: 'world' }
[Mon Mar 22 2021 17:32:38 GMT+0000 (Coordinated Universal Time)] /sleep requrst recieved!!
{ hello: 'world' }