← Všetky články

Ako jedno nadbytočné lomítko spôsobovalo slučky presmerovaní a ako sme našli príčinu v CDN

Niektoré problémy vidí iba časť návštevníkov. Na vašom počítači web funguje, preto sa chyby ťažko hľadajú. Takýto problém zasiahol web klienta počas spustenia produktu.

Hodnotenia Webgate na Clutch

Dôveruje nám 50+ marketingových tímov

StaffinoOktagonCloudTalkAONVacuumlabsBloomreach
Ako jedno nadbytočné lomítko spôsobovalo slučky presmerovaní a ako sme našli príčinu v CDN

Rozdiel nebol v stránke. Spôsoboval ho jeden nenápadný znak v adrese, s ktorou prichádzali niektorí návštevníci, a predvolené nastavenie cache, ktoré z neho vytvorilo slučku.

Čo sa stalo?

Uprostred spustenia produktu prišlo hlásenie: nová stránka časti návštevníkov zobrazovala ERR_TOO_MANY_REDIRECTS. Situácia bola vážna a problém sme navyše nevedeli zopakovať. Nám sa stránka načítala zakaždým.

Obrátili sme sa preto priamo na origin server a obišli všetky vrstvy pred ním:

curl -I --resolve client.com:443:<origin-ip> https://client.com/en/page/
HTTP/2 200

Čistá odpoveď 200. Vyskúšali sme verziu s www, bez koncového lomítka, cez obyčajné HTTP aj množstvo prehliadačov a zariadení. Vždy 200. Súhlasil aj prístupový log servera: od zverejnenia stránky vracal pre túto URL iba odpovede 200. Nevydal jediné presmerovanie.

Stránka sa teda niektorým návštevníkom zacyklila, hoci server ju nikdy nepresmeroval. Odkiaľ presmerovanie prichádzalo?

Čo sme našli

Odpoveď bola o vrstvu vyššie, v CDN Cloudflare. Príčinou bolo jedno nadbytočné lomítko.

Malá časť požiadaviek prichádzala s dvojitým lomítkom za jazykovým prefixom:

/en/page/     <- what everyone types
/en//page/    <- what some links and tools were generating

Cloudflare štandardne pred hľadaním v cache uprace dvojité lomítka. Obe adresy preto smerujú na rovnakú položku cache. Origin serveru však odošle pôvodnú neupravenú adresu. Riadi sa to dvoma nastaveniami: Normalize incoming URLs je predvolene zapnuté, Normalize URLs to origin vypnuté.

WordPress uvidí /en//page/, určí správnu adresu /en/page/ a odpovie presmerovaním. Samo osebe je to neškodné. Problém bol v rozdiele medzi odpoveďou presmerovania a skutočnej stránky:

# the doubled-slash request - a REDIRECT, and cacheable for an hour
GET /en//page/
HTTP/2 301
location: https://client.com/en/page/
cache-control: max-age=3600
cf-edge-cache: cache

# the real page - a 200 that is never cached
GET /en/page/
HTTP/2 200
cache-control: no-store, no-cache, must-revalidate

Cloudflare uložil odpoveď 301 do cache. Keďže pre kľúč cache už odstránil dvojité lomítko, presmerovanie uložil pod čistú adresu. Potom nasledovalo:

  1. Návštevník požiada o bežnú adresu /en/page/.
  2. Cloudflare vráti uložené presmerovanie 301 na /en/page/.
  3. Prehliadač ho nasleduje späť na rovnaké uložené presmerovanie na tej istej adrese.
  4. Vznikne slučka.

Preto sa chyba javila ako náhodná. Cache Cloudflare je rozdelená podľa regiónu a zariadenia, takže zasiahla iba návštevníkov smerovaných cez „otrávené“ miesto. Každá položka po hodine vypršala a pri ďalšej požiadavke s dvojitým lomítkom sa znova pokazila. Problém sa sám opravoval aj vracal — presne také správanie sa opakovaným obnovovaním stránky hľadá najťažšie.

Navyše nešlo iba o jednu stránku. V prístupových logoch sme našli 540 požiadaviek s dvojitým lomítkom na 199 rôznych URL vrátane jazykových homepage. Každá sa mohla nenápadne zacykliť.

Riešenie

Cloudflare nemožno prikázať, aby prestal zlučovať lomítka v kľúči cache. Môžeme však zapnúť úpravu adresy aj cestou k serveru:

Rules → Settings → Normalization → Normalize URLs to origin: On

Server potom dostane /en/page/ aj vtedy, keď návštevník poslal /en//page/. Vráti bežnú odpoveď 200, nevytvorí kanonické presmerovanie a cache už nemá čím kontaminovať. Overili sme to označenou požiadavkou s dvojitým lomítkom a kontrolou toho, čo server skutočne prijal:

sent to Cloudflare:   /en//page/?check=1
arrived at server:    GET /en/page/?check=1   ->   200

Jedno lomítko, odpoveď 200, žiadne presmerovanie. Potom sme vyčistili štyri už kontaminované URL pri spustení, jednu pre každý jazyk, a overili návrat skutočnej stránky:

JazykPred opravouPo oprave
ENSlučka presmerovaní200 (cache HIT)
ESSlučka presmerovaní200 (cache HIT)
ITSlučka presmerovaní200 (cache HIT)
BRSlučka presmerovaní200 (cache HIT)

Dve veci nás stáli čas. Takto sa im vyhnete:

  • Najprv opravte príčinu, až potom čistite cache. Vyčistenie kontaminovanej URL pomôže približne na štyri minúty, kým ďalšia požiadavka s dvojitým lomítkom slučku neobnoví. Najprv zapnite normalizáciu, potom vymažte cache. Inak uvidíte, ako oprava chvíľu „funguje“ a vzápätí opäť zlyhá.
  • Cache CDN netestujte tvrdým obnovením stránky. Vynútené obnovenie, cache: "reload" alebo hlavička Cache-Control: no-cache prikáže Cloudflare obísť vlastnú cache a načítať čerstvú odpoveď zo servera. V skutočnosti tak meriate origin, vidíte funkčný web a môžete nesprávne uzavrieť, že problém neexistuje. Obsah cache zistíte normálnou požiadavkou:
   // "opaqueredirect" here means a redirect really is sitting in the cache
   fetch(url, { redirect: "manual" })

Toto nás nechalo skúmať nesprávnu vrstvu dlhšie, než by sme chceli.

Prečo si občasné problémy zaslúžia pozornosť

Opakované obnovovanie by túto chybu nenašlo. Bola medzi návštevníkom a serverom, vo vrstve, ktorá pri priamom dopyte zakaždým odpovedala správne. „Mne to funguje“ neznamenalo nesprávne hlásenie. Bola to najdôležitejšia stopa, kde problém hľadať.

Museli sme preskúmať prehliadač, CDN a server samostatne a zistiť, čo skutočne robí každá vrstva. Keď sme porovnali odpoveď servera — čistú 200 — s presmerovaním, ktoré dostávali návštevníci, príčina sa ukázala.

Odhaľujte problémy včas a opravujte ich rýchlo. Najmä tie, ktoré vidí iba časť návštevníkov — tie zostávajú nenahlásené najdlhšie.

Riešite problém, ktorý zažíva iba časť návštevníkov? Ozvite sa nám.

← Späť na Blog

KONTAKT

Máte záujem o spoluprácu?

Napíšte nám alebo si dohodnime online hovor, kde si povieme viac o možnostiach spolupráce.

Tomáš a Roman – zakladatelia Webgate

Porozprávajte sa priamo
so zakladateľmi Webgate.