不正なHTTPヘッダ
リバースプロキシとしてアプリケーションの前にnginxを置いている.
あるとき, アプリケーションにリクエストヘッダが渡らないんですけど, という問い合わせがきた.
うーん, 自分が使っている分にはヘッダは渡ってきてるんだけどな...
とりあえず, どんなリクエストを投げてるのか教えてもらったので, 試してみたところ, 報告通りヘッダが渡ってこない.
nginx を通さずに直接アプリケーションにそのリクエストを投げるとヘッダが渡ってきた. 原因はnginxにあることが判明した.
どうなっているかを把握するため debug ログを出すことにした.
/etc/nginx/nginx.conf
- error_log /var/log/nginx/error.log warn; + error_log /var/log/nginx/error.log debug;
すると以下のログが出た.
2015/01/21 09:00:16 [info] 3057#0: *2 client sent invalid header line: "X-Hoge : 1234" while reading client request headers, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
client sent invalid header line
...不正なヘッダを送っているため、nginx で落とされているようだ.
rfc2616 によると Message Header は
message-header = field-name ":" [ field-value ] field-name = token
となっていて, token は
token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
となっている.
field-name と ":" の間にコントローコードやセパレータががあってはいけない.
今回は field-name と ":" の間に空白があるため, 不正なヘッダとして扱われたようだ.
nginx の設定で ignore_invalid_headers をoff にすればヘッダを落とさずにアプリケーション側に投げてくれる.
けど, まあ空白なしがRFC的に正しいので, 空白を削除してリクエストを投げてもらうことで解決.