QA@IT

サブドメイン名をServletのパラメーターにするリダイレクト方法(Rewrite)

3382 PV

お世話になります。

CentOS5+Apache2.2系+Tomcat6系において、下記のような要求仕様があります。

http://www.domain.jpの場合はリダイレクト除外
http://sub.domain.jp→http://domain.jp/apl/servlet?para=sub

Apache側のRewriteでリダイレクトさせようとしていますが、上手く動作してくれません。

[httpd.conf]の記述
....
RewriteEngine On
RewriteCond %{HTTP_HOST} !www.domain.jp [NC]
RewriteCond %{HTTP_HOST} (.).domain.jp [NC]
RewriteRule ^/(.
) ajp://localhost:8009/apl/servlet?para=$1 [L]
....
ProxyPass /apl/ ajp://localhost:8009/apl/
....

正規表現書式の理解不足と色々試した結果、混乱しています。
多分、とんでもない凡ミスを犯しているような気がしますが、
どなたかご指摘願えれば助かります。
※"http://domain.jp/apl/servlet?para=sub"は正常動作しています。

回答

動いていない理由の一つとしては

RewriteRule ^/(.*) ajp://localhost:8009/apl/servlet?para=$1 [L]

^/(.*) の部分が $1にしたい内容になっていないからですね。

^/(.*) の箇所は http://sub.domain.jp/ abc/efg/hij* の太字の部分に対するパターンマッチを指定する場所です。

/で始めるか /なしで始めるかはVirtualHostかどうかだったと思いますが、いずれにしてもホスト名はここでは取れなかったと思います。

他にもやりようはあるかもしれませんし検証もできてませんが、別のルールで環境変数に逃がしてそれを

RewriteRule ^/(.*) ajp://localhost:8009/apl/servlet?para=${ENV:myEnvName} [L]

というように書き換えればいけるかもしれません(サーブレットに飛ばすときにドキュメントへのパスはどうするかは書いてないのでわかりません)。

あと !www.domain.jpだと、sometextwww.domain.jpもはじかれそうな気がします。


追記

RewriteRule (.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+).domain.jp http://domain.jp/apl/servlet?para=$1 [L]

この部分ですが、
たとえば http://sub.domain.jp/abc/efg とアクセスしたとき、

/abc/efgの部分が以下の様に変化して動いています

# RewriteRule (.*) %{HTTP_HOST}$1 [C] により
sub.domain.jp/abc/efg
# これはつまり、http://sub.domain.jp/sub.domain.jp/abc/efg とアクセスされたことにしている。
# 二回ホスト名があるのは間違いではありません。二回目のはパスです。

# RewriteRule ^([^.]+).domain.jp http://domain.jp/apl/servlet?para=$1 [L] により
sub.domain.jp/abc/efg (ホスト名ではなくパス) が評価され、 ^([^.]+) の部分つまり $1になる部分が sub にマッチする。

最終的に
http://domain.jp/apl/servlet?para=sub
になる。

これは認識されてますか?公開前であればまずは動けばいいと思いますので、一旦うまくいったらまた整理されるといいかもしれません。

あと書きながら気付いたんですけど
^([^.]+).domain.jp ではなく ^([^.]+)\.domain\.jpが正しいですね。

編集 履歴 (3)
  • 回答ありがとうございます。
    よく見るとご指摘のとおりですね...
    今ひとつ納得できていないのですが、何となく動作しているようです。
    -

[追記]
→flied_onion様
ご指摘の通り、何か冗長だなとは思っておりますが、log見ながら修正したら上手く変換されていたので、
とりあえずテストサーバーでパターンチェックしています。

※4行目だけで良い気がしますが...
--- script ----------
RewriteCond %{HTTP_HOST} (.).domain.jp [NC]
RewriteCond %{HTTP_HOST} !w[3].domain.jp [NC]
RewriteRule (.
) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+).domain.jp http://domain.jp/apl/servlet?para=$1 [L]

--- rewrite.log -------------
...
RewriteCond: input='sub.domain.jp' pattern='(.*).domain.jp' [NC] => matched
RewriteCond: input='sub.domain.jp' pattern='!w{3}.domain.jp' [NC] => matched
rewrite '/' -> 'sub.domain.jp/'
applying pattern '^([^.]+).domain.jp' to uri 'sub.domain.jp/'
rewrite 'sub.domain.info/' -> 'http://domain.jp/apl/servlet?para=sub'
....

編集 履歴 (0)
  • いや、私の指摘は冗長ということではなく、どういう動きか理解してますか?というものです。 4行目だけでは動きません。4行目のパターンにマッチしているのはホスト名ではありません(というか4行目で正規表現で検索する対象にホスト名は含まれない)。
    その辺りの動きを前の回答の追記部分で説明してみたつもりです。
    -
  • あと、最初にも書きましたが、abcdwww.domain.jp がサーブレットにいかないような気がします。 !^w{3}.domain.jp ではないかと思います。 -

[解決]
とりあえず基本パターンでの動作は確認できました。
色々なパターンで検証する必要があります。

RewriteEngine On
RewriteCond %{HTTP_HOST} (.).domain.jp [NC]
RewriteRule (.
) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+).domain.jp http://domain.jp/apl/servlet?para=$1 [L]
...
ProxyPass /apl/ ajp://localhost:8009/apl/

Rewriteの前に正規表現ですね...

編集 履歴 (0)
  • ちょっと気になったので回答に追記しました。 -
  • 重ねてご指摘ありがとうございます。
    私も??なのですが、RewriteLogを確認してみると、
    上手く変換されている様子なのです。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。