How to allow dots in Slim 3 or nikic/FastRoute parameters?

785 views Asked by At

I am using Slim 3, which uses nikic/FastRoute, and am having trouble with an endpoint like so:

$app->get('/count/{url}', function ($request, $response) use ($curl) {
    $controller = new Proximate\Controller\CountUrl($request, $response);
    $controller->setCurl($curl);
    return $controller->execute();
});

My plan is to pass an urlencoded URL into {url} and inject that into the controller. For example, for http://www.example.com, the request would be:

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww.example.com%2F

However, this fails with a 404, so is evidently not matched. This also fails:

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww.

However, oddly, this does match (i.e. without the trailing dot):

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww

I originally thought it was the urlencoded slashes that was confusing it (%2F) but having tried it without these characters, I find that in fact it is the dot, anywhere in the string. Why does this not match, and do I need a regex match in order to get this to work?

I am using the PHP built-in web server for this app.

1

There are 1 answers

0
halfer On BEST ANSWER

After a bit more digging, I find that this is caused by the PHP built-in web server, and is not a Slim or FastRoute issue at all. Here is the Slim bug report and here is one for PHP.

Sadly the core PHP team have marked as Won't fix, since the server is only for testing. Personally, I think the warnings about not using this server for production are a bit overblown (my Docker containers remain of a reasonably manageable size because I am not throwing Apache in there as well).

Thankfully there is a fix for this - specifying the script name in the URL will cause PHP to pass the rest of it correctly to the routing system. Like so:

curl \
    --verbose \
    http://localhost:8080/index.php/count/http%3A%2F%2Fwww.example.com%2F
#                         ^^^^^^^^^
#                         Script name

Of course, this is not very elegant, so I may yet switch to another solution. I've not tried it yet, but this PHP-only web server looks quite promising.