読者です 読者をやめる 読者になる 読者になる

うまいぼうぶろぐ

linuxとhttpdとperlのメモ

nginx wikiのproxy_redirect の順番が間違っている気がする件

proxy_redirect

apacheのProxyPassRervese のようなことをする設定。defaultの設定は

proxy_redirect default;

で、これはLocationヘッダのHostとportの書き換えまででやってくれる。

apacehだとproxypassするときに

ProxyPass        / http://myapp:8080/
ProxyPassReverse / http://myapp:8080/

とセットでProxyPassReverseを書かないとダメだけど、nginxはdefaultの設定でここまでしてくれるのでproxypassだけで良い。

proxypass http://myapp:8080;

proxy_redirect で一部のURLだけ書き換える場合

(nginxのlistenは80のときの例)
おそらくproxy_redirectは設定の上から順番に評価されるようなので、例えばbackendから/foo で返ってきたときにclientに/bar を返したい場合はこう設定する必要があるのでは。

proxypass      http://myapp:8080;
proxy_redirect http://myapp:8080/foo http://$host/bar;
proxy_redirect default;


wikiの例のようにdefaultを先に書くと、書き換えしたい/foo の設定が反映されない。

proxypass      http://myapp:8080;
proxy_redirect default;
proxy_redirect http://myapp:8080/foo http://$host/bar;
default の設定がない場合

また、default の設定を書き忘れると、proxy_redirectに書いていないURLは書き換えされなくなるのでたぶんまずいことになる。

proxypass      http://myapp:8080;
proxy_redirect http://myapp:8080/foo http://$host/bar;

これだと http://server/foo => http://server/bar となるまではいいんだけど、それ以外のURLにアクセスした場合に書き換えされなくなる。 http://server/directory にアクセスした場合

client => nginx  : http://server/directory
nginx  => myapp  : http://myapp:8080/directory
myapp  => nginx  : http://myapp:8080/directory/
nginx  => client : http://myapp:8080/directory/

と返ってきてしまうのでclientは直接myapp:8080 にアクセスしようとしてしまう。

こういうの調べるとき curl -I とngrep -q -W byline は大活躍ですね。