Recently I have encontered a strange problem about urlencode, I happened to have a "+" in my both pathinfo and querystring parts of the url.
For exampele:
http://example.com/A + B?s=C + D
I use tamperdata in firefox and can make sure thant firefox has encoded the url to the following:
http://example.com/A%20+%20B?s=C%20+%20D
While on the server side, I have apache url rewrite enabled with the following instruction:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Then, in php, I got the following:
$_REQUEST['q'] = 'A B';
$_REQUEST['s'] = 'C D';
$_SERVER['QUERY_STRING'] = 'q=A + B&s=C%20+%20D';
As we known, the php will automatically use urldecode to parese query string to $_REQUEST super variable, that explains why 'A + B' became 'A B' and 'C + D' became 'C D'.Then, I relize that apache url rewrite has to decode all the characters in order to do the rewirte mapping. FLAG B will help reencde them after mapping.So the rewrite rules became following with B FLAG applied.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [B,L,QSA]
Then,the resuelt became:
$_REQUEST['q'] = 'A + B';
$_REQUEST['s'] = 'C D';
$_SERVER['QUERY_STRING'] = 'q=A+%2B+B&s=C%20+%20D';
What I expected is the follow:
$_SERVER['QUERY_STRING'] = 'q=A%20+%20B&s=C%20+%20D';
Then, I could use rawurldecode mannully parse the query string the the following, also this is how firefox originally
$_REQUEST['q'] = 'A + B';
$_REQUEST['s'] = 'C + D';
But instead apache mod-rewrite B glag make q became 'A+%2B+B' which is differently from the original firefox's encoding 'A%20+%20B'.Of course, apache's encode is compatible withe php urlencode function.
So the question is why firefox and apache behave so differently?Why firefox does not encode 'A + B' to 'A+%2B+B' as common use but 'A%20+%20' which cause so many incompatible with the PHP and the server side?
0 Answers