قوانین مسیریابی چه کمکی می‌کند؟

Routing Rules به شما اجازه می‌دهد بر اساس مشخصات درخواست (مثل کشور، مسیر، هدر، IP و …) تنظیمات CDN را در لحظه‌ی دریافت همان درخواست تغییر بدهید؛ مهم‌ترین کاربرد رایج آن انتخاب upstream متفاوت برای بخشی از ترافیک است (مثلاً هدایت کاربران غیرایرانی به یک upstream خارجی).

  • ترتیب اجرا مهم است؛ درخواست‌ها با هر قانون به ترتیب تعریف‌شده بررسی می‌شوند.
  • در حال حاضر تنها action مجاز setUpstream می‌باشد.

ساختار کلی RoutingRules

RoutingRules یک آرایه از Ruleهاست. هر Rule این فیلدها را دارد:

  • name: نام قانون (حداکثر 64 کاراکتر)
  • enabled: فعال/غیرفعال بودن قانون
  • constraints: شرط‌ها (حداکثر 10 گروه OR، و داخل هر گروه حداکثر 10 شرط AND)
  • actions: عمل‌ها (حداقل 1 و حداکثر 10)

منطق constraints (Disjunctive Normal Form - DNF)

ساختار constraints از Disjunctive Normal Form (DNF) استفاده می‌کند؛ یعنی یک آرایه‌ی دوبعدی که به شکل OR از چند گروه AND تفسیر می‌شود.

تعریف DNF

  • لایه بیرونی (Disjunction / OR): گروه‌ها
  • لایه داخلی (Conjunction / AND): شرط‌ها داخل هر گروه

فرمول کلی DNF:

(A₁ AND A₂ AND ...) OR (B₁ AND B₂ AND ...) OR (C₁ AND C₂ AND ...)

مثال‌ها

  1. constraints: [ [A, B], [C] ]

    معادل:

    (A AND B) OR (C)
  2. constraints: [ [A, B], [C, D], [E] ]

    معادل:

    (A AND B) OR (C AND D) OR (E)
  3. constraints: [ [A] ]

    معادل:

    A

نکته مهم: اگر حداقل یکی از گروه‌های AND برقرار باشد، Rule اجرا می‌شود.

negate (NOT)

هر شرط می‌تواند negate: true داشته باشد تا نتیجه‌ی آن شرط معکوس شود (عملگر NOT).

انواع شرط‌ها (Constraint Types) و operatorهای مجاز

هر constraint یک type دارد و دقیقاً یکی از آبجکت‌های مربوط به همان type را پر می‌کند.

country

  • operator: equals
  • expected: لیست کد کشور (مثلاً ['IR','US'])

path (فقط مسیر بدون query)

  • operator: equals | contains | starts_with | ends_with | matches
  • expected: لیست مسیرها

uri (مسیر + query)

  • operator: equals | contains | starts_with | ends_with | matches
  • expected: لیست URIها

host

  • operator: equals | contains | starts_with | ends_with | matches
  • expected: لیست hostها
  • operator: equals | contains | starts_with | ends_with | matches | exists
  • name: نام هدر
  • expected: (اختیاری) لیست مقدارها
  • operator: equals | contains | starts_with | ends_with | matches | exists
  • name: نام کوکی
  • expected: (اختیاری)

args (Query String)

  • operator: equals | contains | starts_with | ends_with | matches | exists
  • name: نام پارامتر
  • expected: (اختیاری)

ip

  • operator: ip_matches
  • expected: (اختیاری) لیست CIDRها
  • ipSet: (اختیاری) نام IPSet

method

  • operator: equals
  • expected: متدهای HTTP (GET, POST, PUT, …)

port

  • operator: equals
  • expected: ['80'] یا ['443']

http_version

  • operator: equals
  • expected: مثل ['HTTP/2'], ['HTTP/3']

tls

  • operator: equals
  • expected: true / false

known_bots

  • operator: equals
  • expected: true / false

asn

  • operator: equals | lesser | greater
  • expected: لیست عددی ASN

edge

  • operator: equals | contains | starts_with | ends_with | matches
  • expected: لیست نام edge

actionها در Routing Rules

در حال حاضر تنها action مجاز:

setUpstream

  • setUpstream.upstreamName: نام upstream مقصد (حداکثر 64 کاراکتر)
  • upstream باید در همین CDN تعریف شده باشد

مثال عملی

هدف: اگر کاربر ایران نبود و مسیر درخواست با /blog یا /news شروع نمی‌شد، upstream را روی default-foreign بگذار.

routingRules:
  - name: ir
    enabled: true
    actions:
      - type: setUpstream
        setUpstream:
          upstreamName: default-foreign
    constraints:
      - - type: country
          negate: true
          country:
            operator: equals
            expected: [IR]
        - type: path
          negate: true
          path:
            operator: starts_with
            expected: [/blog, /news]

تفسیر منطقی (DNF):

(country ≠ IR) AND (path NOT starts_with (/blog OR /news))

چون فقط یک گروه AND وجود دارد، در صورت برقرار بودن آن، Rule اجرا می‌شود.

API و نمونه curl برای Patch کردن RoutingRules

مسیر API

https://api.sotoon.ir/delivery/v2.1/global/workspaces/{workspaceUUID}/cdns/{resourceId}

دریافت CDN (مشاهده مقدار فعلی RoutingRules)

curl -sS \
  -H "Authorization: Bearer $TOKEN" \
  "https://api.sotoon.ir/delivery/v2.1/global/workspaces/$WORKSPACE_UUID/cdns/$RESOURCE_ID"

PATCH با Merge Patch — جایگزینی کامل آرایه spec.routingRules

curl -sS -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/merge-patch+json" \
  "https://api.sotoon.ir/delivery/v2.1/global/workspaces/$WORKSPACE_UUID/cdns/$RESOURCE_ID" \
  -d '{
    "spec": {
      "routingRules": [
        {
          "name": "ir",
          "enabled": true,
          "actions": [
            {
              "type": "setUpstream",
              "setUpstream": { "upstreamName": "default-foreign" }
            }
          ],
          "constraints": [
            [
              {
                "type": "country",
                "negate": true,
                "country": { "operator": "equals", "expected": ["IR"] }
              },
              {
                "type": "path",
                "negate": true,
                "path": { "operator": "starts_with", "expected": ["/blog", "/news"] }
              }
            ]
          ]
        }
      ]
    }
  }'