404エラーになる場合は別のURLに書き換えてみてください

404エラーになる場合は別のURLに書き換えてみてください

ローカル IIS インスタンスをプロキシとして使用するために開発しているローカル Tomcat サーバーがあります。

こうするのは、多くのコンテンツが (私が言うところの) 自己完結型ではないため、サーバーの展開が面倒なプロセスだからです。異なるプロジェクトのコンテンツは基本的にサーバーのルートにコピーされます。その設定の面倒な作業はやりたくなかったので、書き換えモジュールの助けを借りて、大部分の URL を仮想ディレクトリに書き換えることができました。

例えば、

/js/* -> /someproject/js/*
/css/* -> /someproject/css/*
/**/*.pdf -> /someotherproject/pdf/*

ただし、このスキームが機能しないまれなケースがいくつかあります。特に、宛先ディレクトリが重複している場合です。デプロイメントでは、一部のリソースが同じディレクトリに配置されるため、どれがどれであるかを区別する方法はありません。これらのファイルには厳密なパターンはなく、すべてが混在しています。

例えば、

/someproject1/file1.txt -> /file1.txt
/someproject2/book2.doc -> /book2.doc

したがって、URL が与えられた場合、または/file1.txtに移動するように書き換えることができるかどうかはわかりません。したがって、書き換えを試みる URL に何らかの階層があれば、これを機能させることができるのではないかと考えています。したがって、 のような URL を取得し、有効と思われる最初のパターンに書き換える可能性があります。someproject1someproject2/file3.txt

/someproject1/file3.txt     # if 404, try the next
/someproject2/file3.txt     # if 404, try the next
/someotherproject/file3.txt # if 404, try the next
/file3.txt                  # fallback

これは URL 書き換えモジュールを使用してのみ表現できるものなのでしょうか?

答え1

これを動作させることができました。

最初のハードルは、すべての条件付き一致タイプがグローバル スコープ (ルールを記述していた場所) で使用できるわけではないことに気付かなかったことです。 のみが使用可能でした。 一致タイプと一致タイプPatternにアクセスするには、スコープを「分散」スコープ (サイトごとのルール) に変更する必要がありました。IsFileIsDirectory

そこから、ある種の階層構造でルールを書き出すことができます。まず最初に試したいパターンに一致するように書き換え、それがファイルに解決されない場合は次のパターンに書き換えて、これを繰り返します。

<rule name="try in project/content" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="project/content/{R:0}" />
</rule>
<rule name="verify project/content" stopProcessing="false">
    <match url="(project)/content(/.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}{R:2}" />
</rule>

私の場合、まず特定のサブディレクトリを試し、親ディレクトリが存在しない場合は試したいと考えていました。しかし、どの順序で試すかがわかっていれば、理論的にはどのパスのセットでもこれを実行できます。


したがって、質問の例では、次のルールを設定します。

<rule name="try in someproject1" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="someproject1/{R:0}" />
</rule>
<rule name="try in someproject2 otherwise" stopProcessing="false">
    <match url="someproject1/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someproject2/{R:1}" />
</rule>
<rule name="try in someotherproject otherwise" stopProcessing="false">
    <match url="someproject2/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someotherproject/{R:1}" />
</rule>
<rule name="fallback to root otherwise" stopProcessing="false">
    <match url="someotherproject/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}" />
</rule>

関連情報