I'm trying to create a restful API using mod_rewrite.
I have the rule:
RewriteRule v2/(.*)$ v1/index.php?request=$1 [QSA,NC,L]
However the path could contain base64 encoded strings (i.e. can have + or /) and they are being decoded before it gets to PHP.
For example, if I go to
/v2/cards/9VwQLli%2Bf0ogFl19AVRFLuztbp8cP0rYCgXBu3H9%2BDc%3DBe
PHP gets $_REQUEST['request']
as cards/9VwQLli f0ogFl19AVRFLuztbp8cP0rYCgXBu3H9 Dc=Be'
.
And to make things worse, if I add a slash in there (e.g. 9VwQLli%2Bf0ogFl19AVRFLuztbp8c%2FP0rYCgXBu3H9%2BDc%3DBe
- the %2F
is the slash) I get a 404.
How can I prevent this from happening?
Note: I tried the B
and NE
flags but they didn't have any effect. I suppose as a hack I could just convert all +
characters to _
and all /
to -
, or maybe even double url encoding it, but I was wondering if there was a better way.
You don't. The web server is allowed to decode percent-encoded characters which don't decode to special characters before applying rewrite rules, and is allowed to decode the remainder of percent-encoded characters before passing the data to your web application. (See RFC 3986.)
What you should be doing is applying the front controller pattern in your web application, and handling all the percent decoding (and request routing) yourself. In this case you will simply redirect all requests that don't match a file or directory to
/index.php
and then read the URL out of$_SERVER['REQUEST_URI']
. This is how major PHP-based web apps like WordPress and MediaWiki handle this.