nginx はデフォルトで merge slash する
久しぶり技術ネタを一つ。
問題
nginx を reverse proxy として使っていると
original | http://example.com/hoge/huga//path |
proxied | http://example.com/hoge/huga/path |
みたいな感じに重なったslash を merge してから proxy される。path最後の '//path' が '/path' となって、状況によってはありがたい。これが default なのが良いかは分からないが。slash は 2 以上連続していると、1つになる。
さらに、
original | http://example.com/entry/http%3A%2F%2Fwww.hatena.com%2F |
proxied | http://example.com/entry/http%3A%2Fwww.hatena.com%2F |
と、パーセントエンコーディングされている slash もmerge されてしまう。
backend で http://www.hatena.com/ をエンコードした文字列が来ると期待しているとはまる。
解決策
で、これを解決するには nginx.conf の設定に
Syntax: merge_slashes on | off
http://wiki.nginx.org/HttpCoreModule#merge_slashes
Default: on
Context: http, server
Reference: merge_slashes
というのがあるので、これを設定すればよい。
しかし!'Context: http, server' と書いておきながら、この設定は、default server の設定に書くか、http context に書かないと有効にならない。see(http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes)
default server の設定に書くと、すべての virtual host で有効になるようである。ある virtual host だけ有効/無効 にというのが出来ないわけだ。
まとめ
nginx を使っていると、スラッシュの数がバックエンドで少なくなってるということがある。設定で直せるけど、設定場所にも罠があるよ!!!