Как можно избежать таких ситуаций, т.е. страница доступна по след. URL
https://invo.phalcon.io/////session///register https://invo.phalcon.io/session/register///////////
Заранее, спасибо!
|
Nov '13 |
15 |
1738 |
1 |
Как можно избежать таких ситуаций, т.е. страница доступна по след. URL
https://invo.phalcon.io/////session///register https://invo.phalcon.io/session/register///////////
Заранее, спасибо!
Ошибки нет. Эти маршруты соответствуют маске маршрутов при поведении по умолчанию. См. https://docs.phalconphp.ru/ru/latest/reference/routing.html#id11 This default behavior corresponds to the default mask /:controller/:action/:params https://docs.phalcon.io/en/latest/reference/routing.html#default-behavior
Я задаю вот такой марушрут
$router->add('/home/hello', [...]);
И получает что страница доступна по всем возможным комбинациям /
https://localhost/home/hello https://localhost///home//hello https://localhost/home///////hello и т.д.
Показывать особо нечего
$di['router'] = function() {
$router = new Phalcon\Mvc\Router(false);
// $router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI); // Специально законметил чтобы была понятна суть проблемы, т.к. это решило мою проблему
$router->removeExtraSlashes(false);
$router->add('/home/hello', [
'controller' => 'index',
'action' => 'hello'
]);
return $router;
};
Да, наблюдается такое. Стало интересно, сделал тестирование ситуации:
<?php
header('Content-Type: text/html; charset=utf-8');
$router = new \Phalcon\Mvc\Router(false);
//$router->setUriSource(\Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI); // Специально законметил чтобы была понятна суть проблемы, т.к. это решило мою проблему
$router->removeExtraSlashes(false);
$router->add('/home/hello', [
'controller' => 'index',
'action' => 'hello'
]);
$testRoutes = [
'/home/hello',
'/',
'/home//////hello',
'home/hello////////',
];
foreach ($testRoutes as $testRoute) {
$router->handle($testRoute);
echo 'Test route : ', $testRoute, '<br>', PHP_EOL;
if ($router->wasMatched()) {
echo 'Controller : ', $router->getControllerName(), '<br>', PHP_EOL;
echo 'Action : ', $router->getActionName(), '<br>', PHP_EOL;
} else {
echo "The route was't matched...<br>", PHP_EOL;
}
echo '<br>', PHP_EOL;
}
echo '<hr><pre>';
var_dump($_SERVER);
echo '<hr>';
var_dump($router->getRoutes());
echo '</pre>';
Result:
Test route : /home/hello
Controller : index
Action : hello
Test route : /
The route was't matched...
Test route : /home//////hello
The route was't matched...
Test route : home/hello////////
The route was't matched...
array(21) {
["DOCUMENT_ROOT"]=>
string(40) "/projects/phalcon"
["REMOTE_ADDR"]=>
string(3) "::1"
["REMOTE_PORT"]=>
string(5) "45666"
["SERVER_SOFTWARE"]=>
string(28) "PHP 5.5.6 Development Server"
["SERVER_PROTOCOL"]=>
string(8) "HTTP/1.1"
["SERVER_NAME"]=>
string(9) "localhost"
["SERVER_PORT"]=>
string(4) "9000"
["REQUEST_URI"]=>
string(11) "/client.php"
["REQUEST_METHOD"]=>
string(3) "GET"
["SCRIPT_NAME"]=>
string(11) "/client.php"
["SCRIPT_FILENAME"]=>
string(51) "/projects/phalcon/client.php"
["PHP_SELF"]=>
string(11) "/client.php"
["HTTP_HOST"]=>
string(14) "localhost:9000"
["HTTP_USER_AGENT"]=>
string(66) "Mozilla/5.0 (X11; Linux i686; rv:25.0) Gecko/20100101 Firefox/25.0"
["HTTP_ACCEPT"]=>
string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
["HTTP_ACCEPT_LANGUAGE"]=>
string(23) "en-us,en;q=0.7,ru;q=0.3"
["HTTP_ACCEPT_ENCODING"]=>
string(13) "gzip, deflate"
["HTTP_DNT"]=>
string(1) "0"
["HTTP_CONNECTION"]=>
string(10) "keep-alive"
["REQUEST_TIME_FLOAT"]=>
float(1384622395.9004)
["REQUEST_TIME"]=>
int(1384622395)
}
array(1) {
[0]=>
object(Phalcon\Mvc\Router\Route)#2 (9) {
["_pattern":protected]=>
string(11) "/home/hello"
["_compiledPattern":protected]=>
string(11) "/home/hello"
["_paths":protected]=>
array(2) {
["controller"]=>
string(5) "index"
["action"]=>
string(5) "hello"
}
["_methods":protected]=>
NULL
["_hostname":protected]=>
NULL
["_converters":protected]=>
NULL
["_id":protected]=>
int(0)
["_name":protected]=>
NULL
["_beforeMatch":protected]=>
NULL
}
}
У вас есть прекрасная возможность оформить ошибку на GitHub.
Вот еще интересность... https://www.yiiframework.com//////////tutorials/ https://www.yiiframework.com//////////doc/guide/
Вот такое поведение должно быть нормальным https://www.artlebedev.ru/////////////////////////everything/ Т.е. редирект на нормальный URL
Думаю, нормально. Symfony так поступает. Есть опасность зациклиться с редиректом. К тому же, откуда мы знаем, откуда лишний слеш, и что подразумевалось в таком адресе - контроллер/данные, модуль/контроллер/действие/данные, контроллер/действие. Т.е. где ошибка? Что именно пропущено во вводе? Поэтому мое мнение - отдать 404.
Как говорится - с ходу. RFC 3986 Part 3.3 Path. ... If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//"). Т.е. двойной слеш должен быть только в начале authority. Более того, ...When authority is not present, the path cannot begin with two slash characters ("//"). Т.е. во всех остальных случаях сдвоенные слеши не допускаются и трактуются как ошибочные. https://tools.ietf.org/html/rfc3986#appendix-A Именно поэтому, наверное, в Symfony такие path и не пропускают.
Это неточная трактовка RFC, двойные слеши не могут быть на начале пути, но могут быть например в середине, RFC ничего не говорит по этому поводу. Теоретически второй слеш может отделять директорию с пустым именем и это будет идентификатор другого ресурса, e.g., /some/path != /some//path. Но это все полемика, на деле все обстоит по-другому.
Фишечки типа "а под ссылочкой /babe-with-big-boobs мы будем отдавать из базы фото тетки с сиськами о-о-о-ооотакого размера!" придумали SEOшники. Изначальные правила трактовки путей в ссылках работают по принципам навигации в файловой системе. Где dublicate slashes, dot segments, trailing slashes и прочее относится к path normalization.
Path normalization в свою очередь может проводиться на нескольких уровнях: браузер - прокси - веб-сервер (см. первый пример) - CGI - скрипт (роутер). Первое и возможно второе вне нашего контроля, поэтому давай рассмотрим нормализацию пути в скрипте или как ты логично указал - в Раутере. Во-первых, раутер нифига не знает о конечном ресурсе ибо его задача всего-навсего определить кто именно может обработать путь и вернуть эту информацию в dispatcher. Уже немного нелогично получается и совсем некрасиво если мы задумаемся "а чё делать дальше то?". Давай с тобой почешем репки:
Какой вариант выбрать, вот вопрос?! Я думаю, тот который удобнее по ситуации и тут сразу назревает второй вопрос, а откуда будет Раутер знать что он Анна Каренина и под какой поезд из пяти выше перечисленных бросаться? Нет, можно конечно, учитывая что круглое не впихнуть в квадратное, сделать их оба треугольными и использовать какое-то generic решение, 404 например, но рано или поздно появится второй Иван и скажет что его это не устраивает...
Теперь задумаемся о таком: а правда ли нам надо нагружать приложение бессмысленной логикой с перенеправлениями, блекджеком и шлюхами, если это может делать сервер?
Наверное, это вечная тема. В RFC я ничего не нашел о разрешении двойных слэшей, хотя и явного запрета там нет. Но, мне кажется, здесь не стооит применять принцип разрешения всего, что не запрщено явно. С другой стоорны, я не встречал в своей практике ресурсов с двойным слешем. Смотрел, как Symfony относится к тому - не пропускает. Yii - пропускает. Для себя решил - не пропускать. В двойных слешах все-таки вижу неоднозначность. Если мы проверяем URI на соответствие /:module/:controller/:action/:params , то, в случае двойного слеша справедливо предположить, что пропущена какая-то часть адреса ресурса. Т.е. лучше отдать 404. Хотя такая адресация и возможна в файловой системе (Linux), Но, опять же, смысла в этом не вижу. Пустых (в смысле с пустым именем) директорий не встречал. Т.е. test/bar/foo == test///////bar///foo И в том, и вдругом случае, откроется маршрут test/bar/foo. Какой смысл в дублированных слешах?