INTEGRITY Dokumentace

Hodnoty

Když HTTP požadavek dorazí do globální sítě Cloudflare, Cloudflare vytvoří tabulku párů pole-hodnota, vůči které se porovnávají výrazy. Tato tabulka existuje po celou dobu zpracování aktuálního požadavku.

Hodnoty, které naplňují vyhledávací tabulky Rules language, pocházejí z různých zdrojů:

Kromě těchto hodnot mohou výrazy obsahovat i doslovné hodnoty. Jde o statické, předem známé hodnoty, které do výrazů vkládáte, abyste je porovnali s hodnotami z polí požadavku nebo odpovědi, ať už transformovanými, nebo ne.

Při práci s hodnotami ve výrazech pravidel mějte na paměti informace uvedené v následujících částech.

Řetězcové hodnoty a regulární výrazy

Řetězce jsou posloupnosti bajtů ohraničené specifickými oddělovači.

Pravidla Cloudflare podporují dva formáty zápisu doslovných řetězců, včetně regulárních výrazů: uvozené řetězcové literály a surové řetězce. Tyto formáty mají odlišné oddělovače a mechanismy escapování.

K zadání regulárních výrazů ve výrazu můžete použít kterýkoli ze dvou formátů řetězců. Cloudflare však doporučuje použít syntaxe surových řetězců, protože syntaxe řetězce v uvozovkách má složitá pravidla pro escapování a při nedostatečném otestování může vést k neočekávanému chování.

Porovnávání pomocí regulárních výrazů se provádí pomocí enginu regulárních výrazů jazyka Rust.

Syntaxe řetězce v uvozovkách

Při použití syntaxe řetězce v uvozovkách je řetězcový literál ohraničen " (znaky dvojité uvozovky). Tento formát vyžaduje escapování speciálních znaků " a \ pomocí \" a \\, v uvedeném pořadí.

Syntaxe řetězce v uvozovkách má následující další požadavky na escapování:

Příklady
# Test if URI path contains 'a"b'
http.request.uri.path matches "a\"b"

# Test if URI path contains 'a"#b'
http.request.uri.path matches "a\"#b"

# Replace 'a' with '\' (backslash)
regex_replace(http.host, "a", "\\")

Syntaxe nezpracovaného řetězce

Chcete-li zadat řetězec (nebo regulární výraz) pomocí syntaxe nezpracovaného řetězce, použijte speciální oddělovače:

V surovém řetězci (raw string) nejsou žádné speciální znaky, takže všechny znaky až po koncový oddělovač se interpretují doslovně (nejsou zde žádné escape sekvence).

Na rozdíl od syntaxe řetězce v uvozovkách je syntaxe nezpracovaného řetězce vždy stejná bez ohledu na kontext, ve kterém se používá (například jako regulární výraz s operátor regex nebo jako parametr volání funkce).

Příklady
# Test if URI path contains 'a"b'
http.request.uri.path matches r#"a"b"#

# Test if URI path contains 'a"#b'
http.request.uri.path matches r##"a"#b"##

# Replace '\' (backslash) with 'a'
# You must still escape the '\' character in the following raw string because it has a special meaning in regular expressions
regex_replace(http.host, r"\\", "a")

# Test if URI path ends with '/api/login.aspx'
# You must still escape the '.' character in the following raw string because it has a special meaning in regular expressions ("any character")
http.request.uri.path matches r"/api/login\.aspx$"

Rozlišování velkých a malých písmen při porovnávání řetězců

Vyhodnocování řetězcových literálů ve výrazech rozlišuje velká a malá písmena, proto pro zachycení různých variant velikosti písmen ve výrazu zvažte některou z následujících možností:

Limity regulárních výrazů

Cloudflare uplatňuje pro regulární výrazy několik omezení. Jedním z nich je, že každé pravidlo podporuje maximálně 64 regulárních výrazů (regexů), a to bez ohledu na plán vaší domény.

Počet regulárních výrazů v pravidle můžete snížit pomocí následujících postupů:

Booleovské hodnoty

Jednoduché výrazy používající booleovská pole nevyžadují zápis operátoru ani hodnotu. Stačí vložit samotné pole, jak ukazuje ssl příklad níže.

ssl

Tento jednoduchý výraz odpovídá požadavkům, u kterých hodnota ssl pole je true.

Chcete-li porovnávat požadavky, kde ssl je false, použijte booleovský not operátor :

not ssl

Pole

Cloudflare Rules language obsahuje pole z Array typu a funkce hodnotou Array argumenty a návratové hodnoty.

K jednotlivým prvkům pole můžete přistupovat pomocí indexu (nezáporné hodnoty) v hranatých závorkách ([]). Indexy pole začínají na 0 (nula).

Použijte speciální notaci [*] při zadávání výrazu, který se vyhodnotí pro každý prvek pole (například map funkce vyššího řádu ↗). Tato speciální indexová notace rozbalí pole, zavolá obklopující funkci pro všechny jeho prvky jednotlivě a vrátí nové pole obsahující všechny jednotlivé návratové hodnoty.

Příklady

Podívejte se na http.request.headers.names pole s typem Array<String> v následujících příkladech:

V posledním příkladu lower() funkce obsahuje [*] notaci, aby se funkce vyhodnotila pro každý prvek pole. Tato funkce, použitá spolu s [*], vrátí nové pole, ve kterém je každý prvek vstupního pole převeden na malá písmena. Poté se při porovnání řetězců použije [*] k transformaci pole, které vznikne použitím lower() na název každé hlavičky do pole booleovských hodnot. Nakonec any() vyhodnotí jako true, pokud je true alespoň jeden z prvků tohoto pole.

Poznámky

Vlastní pole (arrays) není možné definovat. Můžete používat pouze pole vrácená poli (fields), přímo nebo upravená funkcemi.

Přístup k indexu pole mimo rozsah vytvoří „chybějící hodnotu“. Chybějící hodnota se chová takto:

Můžete použít pouze [*] vícekrát ve stejném výrazu, pokud se použije na stejné pole. Rovněž lze použít pouze [*] v prvním argumentu volání funkce.

Rules language operátory přímo nepodporují pole ani [*] operátor. Podporují však indexované prvky pole, jako je array_value[0]. Nemůžete například použít [*] hodnotou == operátor mimo kontext obklopujícího volání funkce:

Mapy

Mapa, také nazývaná asociativní pole, je datová struktura, která uchovává kolekci párů klíč-hodnota, přičemž klíč musí být String a hodnota může být libovolného typu (například String nebo pole hodnot). Všechny hodnoty v mapě musí mít stejný typ.

Cloudflare Rules language obsahuje několik pole z Map datový typ. Zápis typu pro pole typu map, například Map<Array<String>>, udává datový typ hodnot přiřazených ke klíčům (typu Array z String prvků). To znamená, že když přistupujete k hodnotě klíče "foo" získáte buď pole String prvků nebo chybějící hodnota.

Chcete-li přistoupit k hodnotě v mapě, zadejte klíč do hranatých závorek ([]):

<MAP_FIELD>[<KEY>]

U map, jejichž hodnoty mají Array typu nemůžete přímo použít operátory se získanou hodnotou (polem), protože tyto operátory nepodporují pole přímo. Chcete-li použít operátor na prvek pole, použijte speciální notaci [*] při zadávání výrazu. Tato speciální indexová notace rozbalí pole, zavolá obklopující funkci pro všechny jeho prvky jednotlivě a vrátí nové pole obsahující všechny jednotlivé návratové hodnoty.

Příklady

Následující příklad vychází z http.request.headers pole s datovým typem Map<Array<String>>, kde jsou prvky pole typu String datový typ.

Pokud příchozí HTTP požadavek obsahoval jeden Accept: application/json HTTP hlavička, by se následující výrazy vyhodnotily na uvedené hodnoty:

http.request.headers["accept"]     # ==> ["application/json"]
http.request.headers["accept"][0]  # ==> "application/json"

any(http.request.headers["accept"][*] == "application/json") # ==> true
any(http.request.headers["accept"][*] == "text/plain")       # ==> false

Následující příklad vychází z http.request.uri.args pole s datovým typem Map<Array<String>>, kde jsou prvky pole typu String datový typ.

Pokud HTTP požadavek obsahoval tři filter argumenty URI waf, botm, a cdn, by se následující výrazy vyhodnotily na uvedené hodnoty:

# Example request URL:
# https://example.com/?filter=waf&filter=botm&filter=cdn

http.request.uri.args["filter"]          # ==> ["waf", "botm", "cdn"]

len(http.request.uri.args["filter"][1])  # ==> 4

# Check if the length of all 'filter' values is always 3 or 4
all(len(http.request.uri.args["filter"][*])[*] in {3 4})      # ==> true

# Check if the length of 'filter' values (if any) is never 3 or 4
all(not len(http.request.uri.args["filter"][*])[*] in {3 4})  # ==> false

# Check if the http.request.uri.args map contains a "filter" key
len(http.request.uri.args["filter"]) >= 0     # ==> true

# Check if the http.request.uri.args map does not contain an "order" key
not len(http.request.uri.args["order"]) >= 0  # ==> true

Více informací o any(), all(), len(), a dalších dostupných funkcích najdete v Funkce.

Poznámky

Vlastní mapy (maps) není možné definovat. Můžete používat pouze mapy vrácené poli (fields).

Přístup k neexistujícímu klíči v mapě vytvoří „chybějící hodnotu“. Chybějící hodnota se chová takto:

Seznamy

Seznamy (lists) umožňují vytvořit skupinu položek a odkazovat se na ně ve výrazech společně, pod jedním názvem. Každý typ seznamu podporuje položky konkrétního datového typu. Všechny položky v seznamu musí mít stejný datový typ. Podrobnosti o dostupných typech seznamů najdete v Seznamy.

Chcete-li odkázat na seznam ve výrazu pravidla, použijte $<list_name> a zadat in provozovatel. Stačí, aby se jedna hodnota ze seznamu shodovala s levou stranou výrazu (před in operátor), aby se jednoduchý výraz vyhodnotil na true. Pokud nedojde ke shodě, výraz se vyhodnotí na false.

Následující příklad výrazu filtruje požadavky z IP adres, které se nacházejí v Seznam IP adres s názvem office_network:

(ip.src in $office_network)

Názvy seznamů mohou obsahovat pouze malá písmena, číslice a podtržítko (_) znak. Pokyny k vytváření a správě seznamů najdete v Seznamy.

Vložené seznamy

Vložené seznamy umožňují přímo zahrnout seznam hodnot do jednoduchého výrazu, který používá in operátor.

Prvky vloženého seznamu mohou být řetězce, celá čísla nebo IP adresy/rozsahy. Všechny prvky vloženého seznamu musí mít stejný datový typ a musí jít o literální hodnoty. Chcete-li zadat prvky vloženého seznamu, zadejte je jednotlivě a oddělte je mezerou. Vložené seznamy mohou obsahovat duplicitní hodnoty.

U některých datových typů navíc můžete jako prvky použít rozsahy:

Příklady
http.host in {"example.com" "example.net"}

ip.src in {198.51.100.1 198.51.100.3..198.51.100.7 192.0.2.0/24 2001:0db8::/32}

tcp.dstport in {8000..8009 8080..8089}