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

バーチャルホストとリライト

OpenBSD Apache oogatta.com設定

サイト設計

意気揚々と取得した oogatta.com ドメインARP Networks の VPS ですが、実に順調な滑り出しとなっており小生大満足であります。

基本的な設定はあと OpenBSD にパッチを当てていく作業があるのですが、あれはだるいので、一旦気分を変えて Apache …というか OpenBSD httpd でバーチャルホストを切ったりして、サイトの設計をします。今のところ、 oogatta.com サーバの運用は次のように考えています。

www.oogatta.com(oogatta.com)
トップページを置いたりするくらい。今のところあんまり予定がない。
blog.oogatta.com
oogatta の勉強日記をここに移行予定。
diary.oogatta.com
oogatta の日記、cafemomo.adam.ne.jp、および裏cafemomo.adam.ne.jp全部まとめてここに移行予定(カオス)。

ウェブアプリケーションなどをもしうっかり作ることがあったらその都度サブドメインを切ろうと思っています。

というわけで、バーチャルホストです。 OpenBSD httpd は Apache1 ベースですが、バーチャルの設定くらいそんなに変わらないでしょう、とたかをくくる小生。

設定ファイルのコメントを全て消す

まず、僕のいつもの通り、 httpd.conf のコメント行を全て消します。あった方が逆に見通しが悪くなるもんで、その昔小山さんの Apache のスライドを見て以来そうしています。

# cd /var/www/conf
# cp httpd.conf httpd.conf.back.20100507
# sed -e '/^#/{d;}' httpd.conf > httpd.conf.seded
# mv httpd.conf.seded httpd.conf
# mg httpd.conf

概ね次のようなことをやります。

  • Icon 系削除( directoryIndex させないので)
  • 自分が判りやすいように場所を変えたり

一旦これで再起動して、問題ないことを確かめます。OKでした。

次は名前ベースのバーチャルホストの設定。

<VirtualHost *>
    ServerName blog.oogatta.com

    Alias /static/ "/htdocs/blog/"

    <Directory "/htdocs/blog/">
        Options FollowSymLinks Indexes
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>

    RewriteEngine on    
    RewriteRule ^/$ /promenade.cgi [PT]   
    ScriptAlias / "/cgi-bin/blog/"

    <Directory "/cgi-bin/blog/">
        Options FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
        <Files "/cgi-bin/blog/password.txt">
            Order allow,deny
            Deny from all
        </Files>
    </Directory>
</VirtualHost>

本体の httpd.conf からは include する形にして、こんなもんかなと。うーん、あとは ScriptAlias で設定したディレクトリに DirecoryIndex が効かない問題をどうするかで困っていたんですが、 rewrite で強引に解決させちゃった。てへ。てか RewriteRule のパターン部に / が来る環境と来ない環境があるのはなんでだろう…。マニュアルをみる限り来る方が正しいような気がするな…。あ、ひょっとしてコンテキストによって違うのかな。設定ファイルコンテキストだと / が先頭に来て、ディレクトリコンテキストだと来ないのかな?。うーん…。

あと、 [PT] を初めて理解して使った。

http://blog.oogatta.com/

まま、とりあえずバーチャルホストは完了。

RewriteRule の Pattern がマッチする対象について

Note: Pattern matching in per-directory context
Never forget that Pattern is applied to a complete URL in per-server configuration files. However, in per-directory configuration files, the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done. This feature is essential for many sorts of rewriting - without this, you would always have to match the parent directory which is not always possible.

There is one exception: If a substitution string starts with ``http://'', then the directory prefix will not be added, and an external redirect or proxy throughput (if flag P is used) is forced!

やっぱりそうでした。ディレクトリコンテキストではディレクトリ名までにあたる prefix は取り除かれて Pattern との比較にかけられるので、先頭のスラッシュも無いみたい。いやーこれまで知らなかったっていう方がお恥ずかしい。

PT フラグについて

RewriteRule の第3引数に使える PT フラグですが、こいつが何をしているかというと

This flag forces the rewrite engine to set the uri field of the internal request_rec structure to the value of the filename field. This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias, ScriptAlias, Redirect, and other directives from various URI-to-filename translators.

If you omit the PT flag, mod_rewrite will rewrite uri=/abc/... to filename=/def/... as a full API-compliant URI-to-filename translator should do. Then mod_alias will try to do a URI-to-filename transition, which will fail.

Apache さんには、 URI を実際の File に結びつけるまでに mod_rewrite をはじめ mod_alias など無数の処理を挟むことができるわけですが、それらの間では request_rec 構造体というクソでっけえ構造体の uri と filename というフィールドを変更しながら引きずり回しているということです。

で、基本 mod_rewrite 君も uri から各種ルールに基づいて filename をセットする仕事する。例えば上の僕の例だと、 "/" という URI から "/promenade.cgi" という filename を導き出していることになるみたいだ。なるほど。で、次の ScriptAlias さんもまた URI フィールドの中に "/" オンリーを見つけたら、これを 元に filename フィールドを "/cgi-bin/blog/" に書き換える。

PT フラグが無いとこれをやってしまうわけで、結果どうなるかというと RewriteRule がやったことは完全に無視されて "/cgi-bin/blog/" へのリクエストになって完了してしまう。こりゃあかん。

PT フラグがあると、 RewriteRule が URI から filename を導き出す時に、一緒に URI も filename の値で書き換えてしまうのだとか。結果、 URI フィールドも "/promenade.cgi" という値を持つので、これが ScriptAlias の手によって "/promenade.cgi" から "/cgi-bin/blog/promenade.cgi" という filnename フィールドに書き換えられ、実際にこのファイルがそこにあるので、リクエスト成功になると、そういうわけです。

いやー、本当に mod_rewrite って面白いですね。それでは、さよなら、さよなら、さよなら。