(ne)kanonizace lomítek v URL
- Elijen
- Člen | 171
Narazil jsem na takovou osklivost v routovani:
Routa:
$frontRoutes[] = new Route('<city>/<category>', 'Homepage:default');
Matchujici url:
"http://example.com/mesto/kategorie" //OK - kanonicka
"http://example.com/mesto/kategorie/" //OK - presmeruje na kanonickou
"http://example.com////mesto/kategorie/" //OK - matchuje a presmeruje na kanonickou (i kdyz by teoreticky mohlo hodit 404)
"http://example.com////mesto/kategorie" //FAIL - matchuje ale nepresmeruje na kanonickou (resp. nehodi 404)
"http://example.com////mesto/////kategorie" //FAIL - stejny pripad jako vyse
Ocividne Nette URL kanonizovat umi, ale v pripade, ze na konci neni lomitko se o to nepokousi, lenoch! :-) Da se toto vyresit na strane aplikace (jinak nez implementovanim IRoute) nebo je to chyba ve Frameworku?
Zkousel jsem v Nette 0.9, 2.0 beta i 2.0 stable.
Editoval Elijen (14. 2. 2012 17:15)
- frosty22
- Člen | 373
Pravda nyní jsem zkusil na několika projektech a je to to samé, v podstatě je to i zde:
<?php
https://nette.org/cs/packages
?>
Co se týče BadRequestException VS kanonizace, tak bych se asi též přikláněl k 404ce, jelikož u výchozí routy např:
<?php
<presenter>/<action>
?>
bych logicky při URL:
http://www.example.com//test
očekával, že presenter je null/empty než-li zkanonizovat.
Dokonce jsem tedy i našel již téma, kde to řešilo, a prý se to bude
řešit?
https://forum.nette.org/…obna-lomitka
Editoval frosty22 (14. 2. 2012 17:14)
- frosty22
- Člen | 373
Hledal jsem jádro problému a nalezl jsem ho v RequestFactory, kde je přímo uveden filter, který odstraňuje vícenásobná lomítka:
https://api.nette.org/…ory.php.html#31
29: /** @var array */
30: public $urlFilters = array(
31: 'path' => array('#/{2,}#' => '/'), // '%20' => ''
32: 'url' => array(), // '#[.,)]$#' => ''
33: );
Tento je tedy přímo odstraní z requestu, tudíž se vždy routa matchne jako korektní, při odstranění filtru je vyhozen BadRequest, což by mohlo být korektní .. avšak jistě ten filtr zde bude mít nějaké opodstatnění, bohužel mě zatím nenapadá jaké ;(
Editoval frosty22 (16. 2. 2012 11:43)
- Filip Procházka
- Moderator | 4668
Nikoho to netrápí. Jaktože to nevidím v https://github.com/…nette/issues ?
- David Grudl
- Nette Core | 8218
Věc se má tak, že filtrování URL probíhá na nejnižší vrstvě, proto Presenter už pracuje s upravenou URL a nepřesměruje. Což sice není úplně ideální, ale jde o vcelku nepodstatnou věc, že se mi to nikdy nechtělo řešit.
- Elijen
- Člen | 171
URL se korektne kanonizuje (odstrani se duplicitni lomitka) v pripade, ze konci lomitkem. Z toho bych soudil, ze oprava by mohla byt trivialni ⇒ kanonizovat URL i v pripade, ze nekonci lomitkem.
Zatim se mi ale nepodarilo poradne vykoumat kde se toto deje … takze to mozna nebude az tak trivialni :-D
Editoval Elijen (29. 2. 2012 23:36)
- David Grudl
- Nette Core | 8218
To nesouvisí s tím, jestli to končí lomítkem, ale s tím, že znásobené lomítka se jednoduše nepřesměrovávají. Pokud se přesměruje, tak to je z jiného důvodu, než že tam jsou znásobená lomítka.
- frosty22
- Člen | 373
No jak psal David, tak URL se předá do HttpRequestFactory, kde se rozdělí na jednotlivé části a právě zde dojde k onomu odstranění násobných lomítek díky onomu regulárnímu výrazu (viz výše), a poté se již tyto části předají routování, které matchne danou URL a zavolá korektní presenter. V případě, že však je lomítko na konci/není, tak to je součást URL i v tuto chvíli, a dle rout se poté buď přesměruje na URL s lomítkem či bez. Zároveň se i znovu složí URL z těch částí (kromě defaultních) a pokud se tyto části neshodují s příchozí URL, tj. obsahují defaultní parametr, tak se přesměruje na onu kanonickou URL.
No asi jsem to podal trošku nesrozumitelně, ale špatně se to vysvětluje. Ale ve finále je tedy problém, v onom převedení URL na její části. Při odstranění onoho filtru na vícenásobná lomítka z HttpRequestFactory se problém vyřeší (a asi i bez jiných následků), ale spíše je otázka, zda-li by objekt, který zpracovává URL na její části by se měl takto chovat, že je zachová. Takže logičtější by asi bylo, kdyby ještě obsahoval validaci URL, metodu isValid() ? a poté by se při před předáním HttpRequestFactory vracel i stav, zda-li je korektní URL a pokud ne, tak přesměrovat na 404.
Oproti tomuto však vícenásobná lomítka v URL nejsou nevalidní, jen spíše nežádaná, takže hlavní problém asi tkví v tom, v jaké fázi toto řešit. Opravdu asi zatím se mi jeví jako nejsympatičtější to řešit v .htaccessu.