route🔗
ディレクティブのグループを文字通り、単一のユニットとして評価します。
routeブロックに含まれるディレクティブは、内部的に並べ替えられません。 HTTPハンドラディレクティブ(ハンドラまたはミドルウェアをチェーンに追加するディレクティブ)のみがrouteブロックで使用できます。
このディレクティブは、そのサブディレクティブも通常のディレクティブであるという点で特殊なケースです。
構文🔗
route [<matcher>] {
<directives...>
}
- <directives...> は、routeブロックの外側と同じように、1行に1つずつディレクティブまたはディレクティブブロックのリストです。ただし、これらのディレクティブは並べ替えられません。 HTTPハンドラディレクティブのみを使用できます。
ユーティリティ🔗
route
ディレクティブは、特定の高度なユースケースやエッジケースで、HTTPハンドラチェーンの一部を絶対的に制御するために役立ちます。
HTTPミドルウェアの評価の順序は重要であるため、Caddyfileは通常、解析後にディレクティブを並べ替えて、Caddyfileを使いやすくします。入力する順序を気にする必要はありません。
組み込みの順序はほとんどのサイトと互換性がありますが、場合によっては、サイト全体またはその一部に対して手動で順序を制御する必要がある場合があります。それがroute
ディレクティブの目的です。
例として、redir
とfile_server
という2つの終端ハンドラーを考えてみましょう。どちらもクライアントに応答を書き込み、チェーン内の次のハンドラーを呼び出さないため、特定の要求に対してはどちらか1つのみが実行されます。では、どちらが先に来るのでしょうか?通常、redir
は、特定のケースでのみリダイレクトを発行し、一般的なケースではファイルを提供する必要があるため、file_server
よりも前に実行されます。
ただし、2番目のディレクティブ(redir
)が2番目(file_server
)よりも具体的なマッチャーを持っている場合があります。言い換えれば、一般的なケースでリダイレクトし、特定のファイルのみを提供したいということです。
したがって、次のようなCaddyfileを試すかもしれません(しかし、これは期待どおりに動作しません!)
example.com {
file_server /specific.html
redir https://anothersite.com{uri}
}
問題は、ディレクティブがソートされた後、redir
がfile_server
の前に来るということです。
しかし、この場合、redir
のマッチャー(暗黙的な*
)は、file_server
のマッチャー(*
は/specific.html
のスーパーセット)のスーパーセットです。
幸いなことに、解決策は簡単です。これらの2つのディレクティブをroute
ブロックでラップして、file_server
がredir
の前に実行されるようにします。
example.com {
route {
file_server /specific.html
redir https://anothersite.com{uri}
}
}
これで、順序が文字通りに解釈されるため、file_server
はredir
の前にチェーンされるようになります。
類似のディレクティブ🔗
HTTPハンドラディレクティブをラップできる他のディレクティブもありますが、それぞれが伝えたい動作に応じて使用されます。
-
handle
は、route
のように他のディレクティブをラップしますが、2つの違いがあります。1)handleブロックは互いに排他的であり、2)handle内のディレクティブは通常並べ替えられます。 -
handle_path
はhandle
と同じですが、ハンドラーを実行する前にリクエストからプレフィックスを削除します。 -
handle_errors
はhandle
に似ていますが、Caddyがリクエスト処理中にエラーが発生した場合にのみ呼び出されます。
例🔗
/api
へのリクエストはそのままプロキシし、それ以外のすべてのリクエストは、ディスク上のファイルと一致するかどうかに基づいて書き換え、それ以外の場合は/index.html
を書き換えます。次に、そのファイルが提供されます。
try_files
はreverse_proxy
よりもディレクティブの順序が高いため、通常はソートされて最初に実行されます。これにより、APIリクエストがすべて/index.html
に書き換えられ、/api*
と一致しなくなるため、プロキシされなくなり、代わりにfile_server
から404
になります。すべてをroute
でラップすると、リクエストが書き換えられる前に、常にreverse_proxy
が最初に実行されるようになります。
example.com {
root * /srv
route {
reverse_proxy /api* localhost:9000
try_files {path} /index.html
file_server
}
}