muumoo.jp


ニュース記事検索


過去ログ 2007年07月14日 - ニュース過去ログ

ニュース過去ログ

2007/07/14 管理人日記 IISでURL rewriteをやりたいときのISAPI_Rewrite (管理人日記)

最近ASP.NET 2.0でWebサイト作ってるんですが、URLのrewriteをやりたい。

拡張子.aspxとかがそのままURLに丸見えなのも単純にダサいし、その後ろにパラメータ(QUERY_STRING)がゾロゾロつながっているのもイヤだ。URLはUIの一部であるから、ユーザが扱いやすいものを提供したい。ソースコードの配置構成とイコールである必要は全く無い。こっちがわの(開発者の)都合でURLが決まってはいけない。ユーザのために設計されて実装されるべき。

JavaやPerlやRubyなどならば、WebサーバはApacheだったりするので、URL設計をしたらmod_rewriteを使って実装するのがよくあるやり方です。さらにJavaの場合はURL Rewrite Filterというサーブレットフィルタがあって、これ使うとoutbound、つまりWebサーバからブラウザへレスポンスとして返すhtmlの中のURLを逆方向に書き換えることもできる。

それほどURL rewriteは重要なわけです。なので、ぜひASP.NETでもやりたい。

ISAPI_Rewrite

ASP.NETってことはWebサーバはIISなわけですが(まあ厳密にはそうとも限らないけどそこは許して)、IISにはmod_rewriteみたいな機能は標準では備わっていません。

そこで、ISAPI_RewriteというISAPIフィルタを使ってみました。

有償版と無償版

ISAPI_Rewrite Fullは$99ですが、無償版のISAPI_Rewrite Liteもあります。Lite版はFull版に比べて、

という違いがあります。とりあえずLite版を使ってみることにします。でもまあFull版を買ったとしても$99ですから、どうしても困ったときは買えばいいよね。Apache使ってれば無償なのに、こんなんで金取るのかっていう気もするけど。

使い方

インストールすると自動でIISのISAPIフィルタに割り当てられます。あとは、インストールしたディレクトリ内のhttpd.iniというファイルにrewriteの定義を記述すれば、動きます。書いた定義が反映されるタイミングが不明。数秒で反映されてるっぽいけど。

httpd.iniの書き方は、先頭に

[ISAPI_Rewrite]

という宣言(iniファイルなので「セクション」ですね)を書く以外は、mod_rewriteの書き方と同じです。

RewriteRule ^/hoge([0-9]+)$ /Hoge.aspx?id=$1

こんな感じで書いていくだけ。簡単。

ハマった点

実際使ってみると、いくつかハマるポイントがありました。とりあえずメモ。

インストーラを使ったインストール作業が必要

まあ当たり前といえば当たり前なのですが、インストーラによるインストールが必要です。

最初、開発用の環境にはインストーラを使って入れてうまく動いていたのですが、テスト用の環境や本番用の環境では、開発環境からDLLをコピーして手動でISAPIフィルタに設定していました。そしたら動かなかった。

あんまり本番環境等でインストーラが必要な作業はやりたくなかったのですが、こればっかりは仕方ないようです。

httpd.iniが読み取り専用

これ相当ハマったんですが、インストール直後のhttpd.iniは、なぜか読み取り専用属性になっています。

私はこれに気づかずに編集・保存しようとして、「ファイルが使用中です」みたいなエラーになって、かなり悩みました。iniファイルの性質上、てっきりIIS(またはISAPIフィルタ)がファイルを掴んでるんだと思って、IISを止めてみたりISAPIフィルタを解除してみたり、再起動してみたり、かなりアレコレやったのに状況は変わらず、ホント困り果てました。そしたらなんと読み取り専用だったというわけです。

読み取り専用属性を解除してもISAPI_Rewriteは動作します。

微妙にmod_rewriteと書式が違う

httpd.iniの書き方は基本的にmod_rewriteと同じですが、ちょっとだけ違うようです。

mod_rewriteで301リダイレクト(moved permanently)をしたいときは、RewriteRuleの末尾に

[R=301]

と書きますが、ISAPI_Rewiteでは、

[RP]

と書かなきゃいけないようです。まあ短く書けるのはいいけど、本当は互換にして欲しかった。

Lite版の制限 : サイト別に設定を持てない

無償のLite版を使ってるのが悪いんですが、rewriteの設定をサイト別に持てません。IIS全体でひとつだけになります。そのため、複数のサイト(バーチャルホスト)を立てていると、httpd.iniの定義が全てのサイトで有効になってしまいます。

なので、ホストを限定してRewriteRuleを適用させるために、RewriteCondを使いました。

RewriteCond Host: hoge\.example\.com
RewriteRule ^/hoge([0-9]+)$ /Hoge.aspx?id=$1

RewriteCondを書くと、その次に登場するRewriteRuleの適用範囲を限定できます。上記の例ではホスト(IIS用語で言うところのホスト ヘッダー)がhoge.example.comの場合だけRewriteRuleが適用されます。

RewriteCondは直後のRewriteRuleにしか適用されないので、複数のRewriteRuleを書いている場合はその全ての定義の直前にRewriteCondを記述する必要があって、めんどくさいです。別途定義ファイルを持ってhttpd.iniを自動生成させるなどの工夫ができると良いかと思います。

また、動作としてはこれでOKでも、全てのリクエストでこれらの正規表現のマッチング処理等が走ってしまうので、もしかしたらパフォーマンスに影響するかもしれません。そういう問題がガマンできない場合は有償版を買った方がいいですねたぶん。

まだよくわからない点
この記事のURI:
http://muumoo.jp/news/2007/07/14/0isapirewrite.html


Copyright© 2002-2007 muumoo.jp All Rights Reserved.