vlucas / bulletphp

A resource-oriented micro PHP framework
http://bulletphp.com
BSD 3-Clause "New" or "Revised" License
418 stars 50 forks source link

Bullet doesn't fully support periods in URIs #67

Open acicali opened 9 years ago

acicali commented 9 years ago

There are times when one might like to have periods in the URI, but not a file extension. One such use case is for tokens, e.g. http://jwt.io/

Here's the offending source: https://github.com/vlucas/bulletphp/blob/master/src/Bullet/App.php#L179

One quick solution would be to wrap that line in a check for a match against the listed mime types.

<?php

if(isset($this->_request->_mimeTypes[$ext])) {
    $this->_requestPath = substr($this->_requestPath, 0, -(strlen($this->_request->format())+1));
}

This is just for illustration, the _mimeTypes array is protected. This approach passes existing unit tests, but would mean support for any additional extensions would need to be added to the _mimeTypes array. Perhaps a method for that?

OR... probably the better solution would be to only strip the extension from the path if there's a matching call to $app->format('.ext'). This approach won't pass existing unit tests.

For my token example, I'll either need to append a faux extension to the path (yuck), pass it using a POST call (yuck), pass it via a query string (yuck), or pass it via a request header (yuck). I'll end up moving forward using the least yucky of these... not sure which that is yet though :)

sam2332 commented 9 years ago

i encountered this bug when i was trying to server a js file from bullet!

seanmft commented 9 years ago

This is especially confusing after reading the documentation on Param Callbacks which shows that there is a built in email param type. Looking at the source there is indeed a built in Param Type in App::__construct , but its callback function which returns the return value of filter_var($value, FILTER_VALIDATE_EMAIL) can never return true because the top level domain of the email is removed causing the email to be invalid. So when using email as the only param type, a URL that ends with user@host.com causes a 404 Not Found to be returned. When using slug and email filters with Param Callbacks on the same level, the slug filter will match user@host after the supposed file extension .com is removed from the URL. Even more confusing is that since the supposed file extension .com is used to override the format, if you're specifying an application format e.g. json, you'll get a perplexing 406 Not Acceptable because Bullet assumes that it's returning some mysterious .com file instead of JSON.

As it stands I don't think there is a possible workaround (at least for supporting periods in the URL) as long as anything after a period is assumed to be an extension. Even affixing a faux extension won't work because strpos is used to find a period instead of strrpos. I don't see why extensions have to be handled in this way. The client code should be responsible for registering extensions.

netom commented 7 years ago

I think that extension should only be parsed and executed if there is a matching format() handler.

Since this is a breaking change, it can only be done at v2.