nginxのログに499(レスポンスコード)が記録される場合

最近nginxのログに499とかいう見慣れないレスポンスコードが記録されていたのでどういう状況で記録されるのか試してみた。

499が定義されてる場所

ソースコードの以下ファイルに記載されています。

  • {ソース展開dir}/src/http/ngx_http_request.h

中身を抜粋したのは以下

/*
 * HTTP does not define the code for the case when a client closed
 * the connection while we are processing its request so we introduce
 * own code to log such situation when a client has closed the connection
 * before we even try to send the HTTP header to it
 */
#define NGX_HTTP_CLIENT_CLOSED_REQUEST     499

ということなので変なポイントでクライアントから切断されると出力されるんだろうなぁ、と当たりが付く。

出力されるか試してみる

最初割りと大きいファイルのダウンロード中にブラウザ閉じたりしたら出力されるかな、と思ったら出ない。

ってことで単純にsleepして直ぐに応答返さないようなphpを作成して、Proxy先のApacheに設置して確認する。

<?php
sleep (10);
print "test php";

これをindex.phpとして保存してアクセスし、test phpが出力される前にブラウザの停止、更新ボタン、そしてブラウザの停止を試してみました。

結果、以下のように499がログに記録されました。

192.168.1.240 - - [06/Mar/2013:17:12:48 +0900] "GET /index.php HTTP/1.1" 499 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MALC)" "-"
192.168.1.240 - - [06/Mar/2013:17:14:22 +0900] "GET /index.php HTTP/1.1" 499 0 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22" "-"

念のため複数ブラウザで確認したけど同様の結果に。

この際、nginx側は499で記録されるけど時間はかかったとしてApacheはnginxに対して応答を返すようで200でログに記録されていました。Apache側で200を返すかはその時の処理次第だと思うので、必ず200で記録する分けではないかと。実際に確認出来たわけじゃないけど…
そういう意味だと間違えてボタンとか押して、間違えた、と慌てて停止ボタンを押したとしてもProxy先のApacheまでGETなりが到達していれば処理は行われるだろうなぁ、と推測。

まとめ

サイズの大きいファイルのダウンロード中だと499は記録されなかったため、以下のような時に記録されると考えられます。

  • nginx <-> Apache(proxy先)間での処理中、かつクライアントにデータを送信する前にクライアントから切断された場合

本当はソースコードの中までしっかり確認した方が良いんだけど、最近忙しくてそこまで手を出せず… ざっくりとしか確認してないので興味のある方は{ソース展開dir}/src/http/ngx_http_upstream.c当たりを見ると良いと思います。