Transform Rules とは
以下の4つのルールを定義して、各フェーズで実行することができます。
-
Rewrite URL rules
- HTTPリクエストのURLパスとクエリー文字列を書き換える
-
HTTP request header modification rules
- HTTPリクエスト・ヘッダーの値を設定するか、リクエスト・ヘッダーを削除する
-
HTTP response header modification rules
- HTTPレスポンス・ヘッダーの値を設定するか、レスポンス・ヘッダーを削除する
-
Managed Transforms
- ボタンをクリックするだけで、HTTPリクエストとレスポンスヘッダの一般的な調整を実行できる
適用順
評価
以下のように評価されます。
- 順番に実行される
- 後の順番のルールは、前のルールによって行われた変更を上書きできる
- リクエストとレスポンスのフィールドは、リクエスト/レスポンスのルールを評価する間、各フェーズ内で不変
Transform Rules run in order.
Rules that appear later in the list of Transform Rules can overwrite changes done by previous rules.
You can define the rule order in the dashboard or via API.Request and response fields are immutable within each phase while evaluating Transform Rules for a request/response.
Rewrite URL rules の適用動作を確認
https://example.com/photos/index.html?w=500&h=500
を対象に
Rewrite URL rules の適用動作を確認します。
以下のように HTTP request header modification rules で
適用前フィールド値 raw.http.request.uri.path
, raw.http.request.uri.query
と
適用後フィールド値 http.request.uri.path
, http.request.uri.query
が確認できるように準備します。
http.request.uri.query
のみリライト
ルール1追加: w
から width
へリライト
% curl -s 'https://example.com/photos/index.html?w=500&h=500' | grep -e Query
Rewrite-Before-Raw-Http-Request-Uri-Query: w=500&h=500 <br />
Rewrite-After-Http-Request-Uri-Query: width=500&h=500 <br />
ルール2追加: h
から height
へリライト
% curl -s 'https://example.com/photos/index.html?w=500&h=500' | grep -e Query
Rewrite-Before-Raw-Http-Request-Uri-Query: w=500&h=500 <br />
Rewrite-After-Http-Request-Uri-Query: w=500&height=500 <br />
この結果から、以下のことが確認できました。
- どちらのルールも
http.request.uri.query
は元々のものを参照し、リライトフェーズを終えるまで変更を受けない - ルール評価の結果、ルール2のみが結果として反映される
http.request.uri.path
のみリライト
ルール1追加: /photos/
から /photos/rewrite1/
へリライト
% curl -s 'https://example.com/photos/index.html?w=500&h=500' | grep -e Path
Rewrite-Before-Raw-Http-Request-Uri-Path: /photos/index.html <br />
Rewrite-After-Http-Request-Uri-Path: /photos/rewrite1/index.html <br />
ルール2追加: /photos/
から /photos/rewrite2/
へリライト
% curl -s 'https://example.com/photos/index.html?w=500&h=500' | grep -e Path
Rewrite-Before-Raw-Http-Request-Uri-Path: /photos/index.html <br />
Rewrite-After-Http-Request-Uri-Path: /photos/rewrite2/index.html <br />
この結果から、クエリ同様に以下のことが確認できました。
- どちらのルールも
http.request.uri.path
は元々のものを参照し、リライトフェーズを終えるまで変更を受けない - ルール評価の結果、ルール2のみが結果として反映される
パスとクエリを同時にリライト
上記で使用した4つのルールを以下のように並べ、適用動作を確認します。
% curl -s 'https://example.com/photos/index.html?w=500&h=500' | grep -e Path -e Query
Rewrite-Before-Raw-Http-Request-Uri-Query: w=500&h=500 <br />
Rewrite-Before-Raw-Http-Request-Uri-Path: /photos/index.html <br />
Rewrite-After-Http-Request-Uri-Query: w=500&height=500 <br />
Rewrite-After-Http-Request-Uri-Path: /photos/rewrite2/index.html <br />
この結果から、以下のことが確認できました。
-
path
とquery
は独立してそれぞれ上書きされる
Request Trace API による検証
Request Trace API を使って、どのルールにマッチするかを簡単にテストできます。
export EMAIL='YOUR_EMAIL'
export APIKEY='YOUR_APIKEY'
export ACCOUNT_ID='YOUR_ACCOUNT_ID'
curl -s --request POST \
--url https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/request-tracer/trace \
-H 'Content-Type: application/json' \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" \
--data '{
"method": "GET",
"protocol": "HTTP/1.1",
"url": "https://example.com/photos/index.html?w=500&h=500"
}' | jq -r '.result.trace[]| select ( .step_name == "http_request_transform")|.trace[0].trace'
リライトフェーズ http_request_transform
では、
以下の4つのルールがマッチすることが検証できます。
[
{
"step_name": "aaa",
"type": "rule",
"matched": true,
"action_parameter": {
"uri": {
"query": {
"expression": "regex_replace(http.request.uri.query, \"w=\", \"width=\")"
}
}
},
"expression": "(starts_with(http.request.uri.path, \"/photos/\"))",
"description": "w query to width query",
"action": "rewrite"
},
{
"step_name": "bbb",
"type": "rule",
"matched": true,
"action_parameter": {
"uri": {
"query": {
"expression": "regex_replace(http.request.uri.query, \"h=\", \"height=\")"
}
}
},
"expression": "(starts_with(http.request.uri.path, \"/photos/\"))",
"description": "h query to height query",
"action": "rewrite"
},
{
"step_name": "ccc",
"type": "rule",
"matched": true,
"action_parameter": {
"uri": {
"path": {
"expression": "regex_replace(http.request.uri.path, \"/photos/\", \"/photos/rewrite1/\")"
}
}
},
"expression": "(starts_with(http.request.uri.path, \"/photos/\"))",
"description": "photos path to rewrite1 path",
"action": "rewrite"
},
{
"step_name": "ddd",
"type": "rule",
"matched": true,
"action_parameter": {
"uri": {
"path": {
"expression": "regex_replace(http.request.uri.path, \"/photos/\", \"/photos/rewrite2/\")"
}
}
},
"expression": "(starts_with(http.request.uri.path, \"/photos/\"))",
"description": "photos path to rewrite2 path",
"action": "rewrite"
}
]
また、jq
による JSON マージを使えば、Transform Rules の適用動作に従う形で、以下のように上書きされた最終的な action_parameter
を確認することができます。
- How to merge 2 JSON files including objects and arrays using jq? - Stack Overflow
- 複数のjsonファイルをjqを使ってmergeする | DevelopersIO
- jq Manual (development version)
Objects are added by merging, that is, inserting all the key-value pairs from both objects into a single combined object. If both objects contain a value for the same key, the object on the right of the + wins. (For recursive merge use the * operator.)
curl -s --request POST \
--url https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/request-tracer/trace \
-H 'Content-Type: application/json' \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" \
--data '{
"method": "GET",
"protocol": "HTTP/1.1",
"url": "https://example.com/photos/index.html?w=500&h=500"
}' | jq -r '.result.trace[]| select ( .step_name == "http_request_transform")|.trace[0].trace| reduce .[].action_parameter as $i ({}; . * $i)'
{
"uri": {
"query": {
"expression": "regex_replace(http.request.uri.query, \"h=\", \"height=\")"
},
"path": {
"expression": "regex_replace(http.request.uri.path, \"/photos/\", \"/photos/rewrite2/\")"
}
}
}
まとめ
リライト処理はどうしても複雑になってしまいがちなことや、複数ルールがあった場合に意図しない動きになっていないかどうか等の確認は、実装のタイミングで確実にチェックしておきたいところかと思います。
今回は、Transform Rules の Rewrite URL rules をピックアップして適用動作の検証をしましたが、同様のルール適用動作は Cache Rules や Origin Rules でも採用されているため、Request Trace API による検証が役立ちます。
Cache Rules are stackable. This means that multiple matching rules will be combined and applied. So if multiple cache rules match the same URL, then the features set in those cache rules will all be applied. If several matching rules set a value for the same setting, the value in the last matching rule wins. For an example of a similar scenario where multiple rules match, refer to the Origin Rules FAQ.