https://forum.phalcon.io////discussion///////////////1189/////-#C4248 Why this route is matched? And https://phalcon.io/en///////////support
Look, please https://forum.phalcon.io/discussion/1189/-
|
Nov '13 |
4 |
2029 |
2 |
https://forum.phalcon.io////discussion///////////////1189/////-#C4248 Why this route is matched? And https://phalcon.io/en///////////support
Look, please https://forum.phalcon.io/discussion/1189/-
In other words Router allows multiple backslashes. See test here https://forum.phalcon.io/discussion/1189/-#C4250
:) This test was done by me. This post is duplicated from russian https://forum.phalcon.io/discussion/1189/- for community. I am interested in how this will comment on Phalcon.
It's not a bug. On one hand, as per RFC URL path segments must be separated with a single forward slash. So it looks like RFC violation. On the other hand, URL path is a path in a hierarchical structure where each adjacent slash points to a folder named with an empty string, which is not valid for a file system. Phalcon Router may skip duplicate slashes or it does "path normalisation", which is correct behaviour. That's why using REQUEST_URI works as expected and it does not work if _uri=xxx URL attribute is used.
But the thing is, it's not the Router's job to decide on action should be taken in case of malformed URL path. My suggestion is to add a URL rewrite rule to your web server to redirect 302 to correct URL or fail with 404 on malformed URLs. It's better for SEO and doesn't put load on the application if handled by the web server.
RFC 3986 Part 3.3 Path. ... If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//"). ...When authority is not present, the path cannot begin with two slash characters ("//"). https://tools.ietf.org/html/rfc3986#appendix-A
I doubt that Router should perform URL path normalization, it can be quite complicated some times. For example:
/test/blah/../Frank765 -> /test/Frank765
/test/./Frank765 -> /test/Frank765
/test//Frank765 -> /test/Frank765
Frank765 is a file -> /test/blah/Frank765
Frank765 is a directory -> /test/blah/Frank765/
It should be done by the web server itself or rewrite rules. Router does not have enough knowledge of the end resource and correct behavior if resource is not there. So, following your example, possible actions can be:
Each option is different and should be chosen according to the situation.
Guys, this is how Apache works, not Phalcon :-)
index.php:
<?php
class IndexController
{
public function indexAction()
{
echo __METHOD__, PHP_EOL;
print_r($_SERVER);
}
public function helloAction()
{
echo __METHOD__, PHP_EOL;
print_r($_GET);
}
}
$di = new Phalcon\DI();
$di['router'] = function() {
$router = new Phalcon\Mvc\Router(false);
// $router->setUriSource(Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI); // This line solve the bug
$router->removeExtraSlashes(false);
$router->add('/home/hello', array(
'controller' => 'index',
'action' => 'hello'
));
return $router;
};
$di['dispatcher'] = new \Phalcon\Mvc\Dispatcher();
$di['response'] = new \Phalcon\Http\Response();
$di['view'] = new \Phalcon\Mvc\View();
header('Content-Type: text/plain');
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();
.htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>
Now if you go to site/home/////hello, you will see something like this:
IndexController::helloAction
Array
(
[_url] => /home/hello
)
That is, Apache internally normalizes the request and this is why Phalcon is passed the correct string — /home/hello and not /home/////hello.
If you uncomment $router->setUriSource(Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI);
, you will see something like
...
[REDIRECT_QUERY_STRING] => _url=/home/hello
[REDIRECT_URL] => /home///hello
[QUERY_STRING] => _url=/home/hello
[REQUEST_URI] => /home///hello
[SCRIPT_NAME] => /index.php
[PHP_SELF] => /index.php
...
REQUEST_URI is not normalized by Apache and this is why the behavior differs.
Don't know about Apache, but for nginx you can control the behavior with merge_slashes
directive (https://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes)