うまいぼうぶろぐ

linuxとhttpdとperlのメモ

apache 2.2 LocationMatch 内ではProxyPassではなくProxyPassMatch (ただし、ProxyPassReverseの制限付き)

2.4は不明。2.2ではProxyPassではダメだった。

Location 内でProxyPassしているURLを増やしたくて、
そのままLocationMatchで正規表現で書いてもProxyしてるところがbackendに渡らなくて困った。

セクションの中で使われた場合は、 最初の引数は省略され、正規表現 から取得されます。

ProxyPassMatch の場合は渡す引数を正規表現でとってこないといけないので
URL /foo/

<Location /foo/>
   ProxyPass http://backend/foo/
</Location>

URL /fooもしくは/bar

<LocationMatch ^/(?:foo|bar)/(.*)>
   ProxyPassMatch http://backend/foo/$1
</Location>

最初のカッコはfooとbarをグループしたいだけで変数はキャプチャしたくないので?: つけている。


これで動作はする。ただしProxyPassReverse の扱いがやっかい。
Locationで使っていた

ProxyPassReverse http://example.com/foo 

をそのままLocationMacthで利用すると、backendでredirectが発生したときに正規表現の文字列のまま返ってきてしまう。

$ curl -I http://example.com/foo/hoge
(抜粋)
Location: http://example.com^/(?:foo|bar)/(.*)/hoge/

これはProxyPassReverseのドキュメントにも書いている

セクション内でも起きますが、 おそらく意図どおりに動きません。
と言うのも、ProxyPassReverse が正規表現をそのまま文字列でパスとして解釈しようとするからです。
もしこのような状況で必要なら、セクションの外で ProxyPassReverse を指定するか、あるいは別の セクション内で指定してください。

ここまでくるとアプリケーションやどのURLでアクセスがきたときにどうしたいかなどによるけど
一つのProxyPassReverse ではたぶん綺麗に解決できないので、
ProxyPassReverseが必要な状況なら素直にLocation を個別に書いた方が良いかな。