ワイルドカード スクリプト マッピングと IIS 7 統合パイプライン

公開日: 2008 年 9 月 30 日 (作業者: ruslany (英語))

更新日: 2009 年 2 月 20 日 (作業者: ruslany (英語))

IIS 7 の統合された要求処理パイプラインの大きなメリットは、便利な ASP.NET 機能すべてを、ASP.NET 固有のコンテンツだけではなく、Web サイト上のどのコンテンツ タイプにも使用できることです。たとえば、ASP.NET の SQL に基づくメンバーシップを使用して、静的ファイルおよびフォルダーを保護できます。また、IHttpHandlerIHttpModule などの ASP.NET 拡張 API を使用して、非 ASP.NET コンテンツに対しても実行できるカスタム モジュールやハンドラーを追加することもできます。

IIS 6 では、このレベルまでの統合は行われていません。ASP.NET は、ISAPI 拡張機能として IIS 6 に接続され、既定ではその拡張機能にマップされた要求のみを処理するように構成されています。たとえば、".aspx" で終わるすべての要求は、ASP.NET 拡張機能によって処理されます。これは明らかに、ASP.NET 機能を Web サイト上の他のすべてのコンテンツに対して使用することを望むユーザーにとって大きな制限です。この制限を回避する最も一般的な方法は、"ワイルドカード スクリプト マッピング" です。この記事では、IIS 6 でワイルドカード スクリプト マッピングを使用していたアプリケーションを IIS 7 に移行する方法を説明します。

IIS 6 でワイルドカード スクリプト マッピングを使用し、すべての要求が ASP.NET で処理されるように構成したと仮定します。たとえば、URL 書き換え用の ASP.NET モジュールがあり、これを使用して拡張子なしの URL を処理するとします。

このワイルドカード スクリプト マップ構成は、通常、IIS 6 マネージャー内で行います。この操作を行うには、Web サーバーまたは Web サイトのプロパティ ダイアログを開き、[ホーム ディレクトリ] タブをクリックし、[構成] ボタンをクリックして、[ワイルドカード アプリケーション マップ] の [挿入] をクリックします。

Ff454109.WildcardIIS6(ja-jp,TechNet.10).png

アプリケーションを IIS 7 に移行したときに、ASP.NET の動作が同じになるようにアプリケーションを構成する必要があります。これを行う方法として、クラシック パイプライン モードを使用する方法と、統合パイプライン モードを使用する方法があります。

IIS 7 クラシック パイプライン モードでのワイルドカード スクリプト マッピング

クラシック パイプライン モードでは、ASP.NET は、IIS 6 とまったく同様に ISAPI 拡張機能として IIS 要求処理パイプラインに接続されます。実際、%WINDIR%\system32\inetsrv\config\applicationHost.config ファイルを開いて、その中の <handlers> セクションを探すと、ASP.NET 固有の要求を aspnet_isapi.dll にマップするために IIS がどのように構成されているのかを確認できます。

<handlers accessPolicy="Read, Script">
  ...
  <add name="PageHandlerFactory-ISAPI-2>0" 
       path="*>aspx" verb="GET,HEAD,POST,DEBUG" 
       modules="IsapiModule" 
       scriptProcessor="%windir%\Microsoft>NET\Framework\v2>0>50727\aspnet_isapi>dll" 
       preCondition="classicMode,runtimeVersionv2>0,bitness32" responseBufferLimit="0" />
  ...
</handlers>

ハンドラー マッピングのための preCondition 属性に注目してください。何よりこの属性が classicMode に設定されているので、このハンドラー マッピングは、アプリケーション プールがクラシック モードで実行されるように構成されているときにのみ機能します。

クラシック モードで実行する ASP.NET 用のワイルドカード マッピングを構成する必要がある場合、IIS マネージャーで [ハンドラー マッピング] 機能を開き、[ワイルドカード スクリプト マップの追加] をクリックして構成できます。

Ff454109.Wildcard_script_map(ja-jp,TechNet.10).png

[実行可能ファイル] ボックスで aspnet_isapi.dll を選択し、このスクリプト マッピングに、ASP.NET-ISAPI-2.0-Wildcard などのわかりやすい名前を付けます。次に、[OK] をクリックし、[ワイルドカード スクリプト マップの追加] ダイアログで [はい] をクリックします。

Ff454109.Wildcard_script_map_warning(ja-jp,TechNet.10).png

次に、[順序指定された一覧の表示] をクリックし、ハンドラー マッピングの順序指定された一覧表示に切り替え、新しく作成したマッピングを一覧の一番下にある [StaticFile] ハンドラー マッピングのすぐ上まで移動します。

Ff454109.OrderedList(ja-jp,TechNet.10).png

web.config ファイルを開して <handlers> セクションを探すと、ASP.NET 用のワイルドカード スクリプト マップが StaticFile ハンドラーの直前に配置されていることを確認できます。

<handlers accessPolicy="Read, Script">
  ...
  <add name="ASP>NET-ISAPI-2>0-Wildcard"
     path="*" verb="GET,HEAD,POST,DEBUG"
     modules="IsapiModule"
     scriptProcessor="%windir%\Microsoft>NET\Framework\v2>0>50727\aspnet_isapi>dll"
     preCondition="classicMode,runtimeVersionv2>0,bitness32" responseBufferLimit="0" />
  <add name="StaticFile" 
     path="*" verb="*" 
     modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" 
     resourceType="Either" requireAccess="Read" />
</handlers>

ワイルドカード ハンドラー マッピングの相対的な順序は重要です。このハンドラーを StaticFile ハンドラー マッピングの後に定義すると、StaticFile がすべての要求を処理し、ASP.NET ワイルドカード ハンドラーには要求が何も渡されなくなります。

既にお気付きかと思われますが、IIS 7 の ASP.NET ワイルドカード ハンドラー マッピングには、IIS 6 の場合と同じパフォーマンス制限があります。この種のハンドラー マッピングの問題点とは、静的ファイルも含めて "すべて" の要求がそのハンドラーによって処理されることです。ASP.NET の静的ファイル ハンドラーは、IIS のネイティブの静的ファイル ハンドラーほど強力ではありません。さらに、ASP.NET によって処理される静的ファイルは、サーバーおよび Web ブラウザーの両方でキャッシュされません。これらのパフォーマンス制限があるので、IIS 7 統合パイプラインを使用して、IIS 6 でのワイルドカード マッピングと同じ機能を達成することを推奨します。

ワイルドカード スクリプト マッピングの代わりとなる IIS 7 統合パイプライン

統合パイプラインでは、IIS のメインの要求処理に ASP.NET 機能が完全に統合されています。つまり、ASP.NET 機能のすべてを、すべての種類の要求に使用できるということです。結果として、ワイルドカード スクリプト マッピングの必要性がなくなっています。既存の ASP.NET モジュールを使用して、それらをすべての要求に適用できます。

たとえば、URL 書き換えモジュールを ASP.NET で記述したとします。IIS 6 では、このモジュールは web.config ファイルの <system.web> セクションに次のように登録されます。

<system>Web>
  <httpModules>
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace>MyModules>UrlRewrite, SomeNamespace>MyModules" />
    ...
  </httpModules>
</system>Web>

IIS 6 では、このモジュールはマネージ コンテンツへの要求に対してのみ実行されるので、http://example.com/archive/2008/08/26/post-title.**aspx などの .aspx 拡張子を持つ URL に対してのみ動作します。拡張子なしの URL を処理するには、ASP.NET 用のワイルドカード スクリプト マッピングを構成する必要があります。IIS 7 統合パイプラインでは、この作業はもう必要ありません。このモジュールが拡張子なしの URL に適用されるようにするには、web.config ファイルの <system.webServer> セクションに次のように登録する必要があります。

<system>webServer>
  <modules >
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace>MyModules>UrlRewrite, SomeNamespace>MyModules" 
         preCondition="" />
    ...
  </modules>
<system>webServer>

ここでは preCondition 属性は必ず空にしてください。こうすることで、モジュールが ASP.NET 固有コンテンツへの要求だけではなく、すべての要求に対して実行されるようになります。

マネージ モジュールをこの方法で登録すると、ワイルドカード スクリプト マッピングを使用したときほどのパフォーマンスに対する大きな影響はありません。このモジュールは Web アプリケーションへのすべての要求に対して呼び出されますが、既存のハンドラー マッピングはすべて機能したままなので、静的ファイルは依然として IIS のネイティブの静的ファイル ハンドラーによって処理されます。この方法でモジュールを登録するもう 1 つのメリットは、PHP、ASP をはじめとする他のすべての動的ページへの要求に対してモジュールを適用できることです。ワイルドカード スクリプト マッピングを使用した場合は、これは不可能です。

最後になりますが、<modules> セクションで runAllManagedModulesForAllRequests 属性を使用することもできます。

<system>webServer>
  <modules runAllManagedModulesForAllRequests="True" >
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace>MyModules>UrlRewrite, SomeNamespace>MyModules" 
         preCondition="ManagedHandler" />
    ...
  </modules>
<system>webServer>

この属性は、IIS が preCondition="managedHandler" 属性を無視するように強制するので、Web アプリケーションへのすべての要求に対して、すべてのマネージ モジュールが呼び出されます。