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
Default: on
Context: http, server
Reference: merge_slashes

http://wiki.nginx.org/HttpCoreModule#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 を使っていると、スラッシュの数がバックエンドで少なくなってるということがある。設定で直せるけど、設定場所にも罠があるよ!!!