slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.94k stars 1.95k forks source link

Case insenitive routes v3 #1449

Closed neilmillard closed 9 years ago

neilmillard commented 9 years ago

Issue 697 for slim v2 gave an option for case insensitive routes. could we have this for v3? this could be via the settings array with $request->getUri()->withPath(strtolower($request->getUri()->getPath())) in the request class, or some code added to the Uri class. what would the preferred way to code it?

akrabat commented 9 years ago

You can quite easily create your own middleware that does this.

Something like this (untested):

$app->add(function($request, $response, $next) {
    $uri = $request->getUri();
    $uri = $uri->withPath(strtolower($uri->getPath());
    $request = $request->withUri($uri);

    return $next($request, $response);
});
neilmillard commented 9 years ago

I would expect this to work. I'm missing something obvious maybe?

$app->add( function (\Slim\Http\Request $request, \Slim\Http\Response $response, callable $next)use($container){
    $basePath = $request->getUri()->getBasePath();
    $uri = $request->getUri()->withBasePath(strtolower($basePath));
    $newreq = $request->withUri($uri);
    $response = $next($newreq,$response);

    return $response;
});
JoeBengalen commented 9 years ago

Is it on purpose you update the basePath instead of the path?

neilmillard commented 9 years ago

yes, the issue I have is Slim running from a subdirectory and for some reason (IIS setup) it is returning 404 if the case is used.

JoeBengalen commented 9 years ago

So what url are you trying to change?

Edit; For me this works fine

// requesting: http://localhost/dev/Slim/hello/me
// where my index is in dev\Slim\

$app->add(function (\Slim\Http\Request $request, \Slim\Http\Response $response, callable $next) {
    var_dump($request->getUri()->getBasePath());
    // -> /dev/Slim

    var_dump($request->getUri()->getPath());
    // -> hello/me

    var_dump((string) $request->getUri());
    // -> http://localhost/dev/Slim/hello/me

    $basePath = $request->getUri()->getBasePath();
    $uri = $request->getUri()->withBasePath(strtolower($basePath));
    $newreq = $request->withUri($uri);
    $response = $next($newreq,$response);

    var_dump((string) $newreq->getUri());
    // -> http://localhost/dev/slim/hello/me

    return $response;
});

But I am not sure what you are trying to solve by making it lower case. Because if the directory is has a capital in it, you have to put that capital in the url or he wont find it. So if I called http://localhost/dev/slim/hello/me, I would also get Page not found, because the basePath if not extracted from the path.

neilmillard commented 9 years ago

This is on a windows server, so in theory the os is case insensitive. The public directory is showing as 'Apps' and the url '/Apps/' or '/apps/' returns okay. The base route '/' works regardless of what case is used in the url; whereas when I specify a route /Apps/oncall gives the Slim page not found 404 (not the IIS one) and /apps/oncall works. So it is getting to the index.php for Slim. but the router is not able to match the route. The Basepath is not specified in the routes. The 404 function, the var_dump($request->getUri()->getBasePath()); gives a blank string. on an active route the string is as I would expect. (all lowercase) Does this code need to be invoked before $route->finalize() I am not certain when the valid routes are checked..

JoeBengalen commented 9 years ago

Yeah that is indeed the current behaviour.

Slim will not recognize the basePath, because the url does not match the path (as the case is different) https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php#L198

Because windows is case insensitive the index.php is indeed found.

neilmillard commented 9 years ago

Would completely agree with you but, filepath=e:\Apps\index.php uri=localhost/Apps/profile - fails uri=localhost/apps/profile - works.

$app->get('/profile', 'App\Action\ProfileAction:dispatch');
JoeBengalen commented 9 years ago

Really? For me its the other way around: http://localhost/dev/Slim/hello/joe - works http://localhost/dev/slim/hello/joe - fails (aka not found)

neilmillard commented 9 years ago

yeah, real odd. but in your case is it getting to the Slim app? or the webserver returning 404

JoeBengalen commented 9 years ago

Its gets to slim because I'm running windows too so case doesn't matter. But I cannot reproduce your situation.

neilmillard commented 9 years ago

so Slim should not care about the case of the baseurl, that is for the webserver to worry about. ? Can we make it case insensitive?

akrabat commented 9 years ago

I would guess that https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php#L198 needs to be stripos rather than strpos.

@neilmillard can you locally change line 198 of Slim\Http\Uri.php and see if that fixes it?

JoeBengalen commented 9 years ago

For me is fixes it! :)

neilmillard commented 9 years ago

Yes, that fixed it

neilmillard commented 9 years ago

Thanks guys