Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Mod_rewrite and URL-encoded symbols - only can use either of them but not both?

The mod_rewrite seems to convert the symbol of plus before I get it into $_REQUEST, and I don't know what to fix it...

RewriteRule ^invite/([a-zA-Z0-9\-\+\/]+)/?$   invite.php?key=$1 [L,QSA]

For instance, I input this into my URL,

http://mywebsite/invite/xPo8lUEXpqg8bKL%2B32o6yIOK

i get this,

xPo8lUEXpqg8bKL 32o6yIOK

but if I input this request without passing through the mod_rewrite,

http://mywebsite/invite.php?key=xPo8lUEXpqg8bKL%2B32o6yIOK

i get this what I want,

xPo8lUEXpqg8bKL+32o6yIOK

What can I do? Or is it that I only can use either them but not both??

Thanks.

like image 671
Run Avatar asked Jan 24 '11 00:01

Run


2 Answers

Try adding the [B] flag (escape backreferences):

RewriteRule ^invite/([a-zA-Z0-9\-\+\/]+)/?$   invite.php?key=$1 [L,B,QSA]
like image 66
Brian Avatar answered Oct 09 '22 22:10

Brian


The "+" character is reserved in the query string part of an URL as a space. Actually, "+" status as a reserved character is documented in rfc3986 and its (now legacy) use as a space replacement character is documented in rfc1630.

Since Apache tries to avoid any conflict, it automatically escapes "+" as a string before passing it over.


Using the [NE] (NoEscape) flag on your rewrite should prevent that behavior from happening.

RewriteRule ^invite/([a-zA-Z0-9\-\+\/]+)/?$   invite.php?key=$1 [L,NE,QSA]

However, by using this, unescaped "+" WILL be replaced by a space if the user types the URL manually. To be on the safe side, simply replace all spaces in your input by "+" signs.


Quite frankly, since you do not accept spaces in your input, simply replace all spaces with a "+" symbol. Using the [NE] flag can bring out bigger issues then a simple character substitution. A simple $_GET['key'] = str_replace($_GET['key'], ' ', '+'); should suffice.

like image 1
Andrew Moore Avatar answered Oct 09 '22 23:10

Andrew Moore