不正な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的に正しいので, 空白を削除してリクエストを投げてもらうことで解決.