the auto urldecode in apache mod_rewrite

2019-09-17 16:05发布

this is my apache .htaccess setting with a search page redirect

(RewriteRule ^search/(.*)$ /index.php?c=index&m=search&keywords=$1 [L,QSA]),

if I set the search query in url without %, it works success request without '%' but if a % char added to the string, apache with return a bad request with % , howerver instead of adding % but %25, the urlencoded string of %, success request when pre encode % to %25

I want to know about the reason of this situation. I guess in the RewriteRule of .htaccess an urldecode function worked from Pattern to Substitution, that's why % char cannot be recognized by the server, but %25 can. How can I disable this urldecode function?

1条回答
贼婆χ
2楼-- · 2019-09-17 16:48
  • Because the percent ("%") character serves as the indicator for percent-encoded octets, it must be percent-encoded as "%25" for that octet to be used as data within a URI (RFC 3986)
  • I think it's because Apache follows the standards, mod_rewrite has to unescape URLs before mapping them.. (https://httpd.apache.org/docs/current/rewrite/flags.html#flag_b)

Easy workaround for "disable" auto url decoding is to use Server-Variables like REQUEST_URI or THE_REQUEST in RewriteCond Directive (http://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteCond)

RewriteEngine on
RewriteCond %{REQUEST_URI} /search/(.*)
RewriteRule . test.php?c=index&m=search&keywords=%1 [L,QSA]

If you use REQUEST_URI, in PHP you must use $_SERVER['REQUEST_URI']. Do not use $_SERVER['QUERY_STRING'] or $_GET, otherwise you will get the decoded url. If you want all $_SERVER doing what you need, use THE_REQUEST instead:

RewriteEngine on
RewriteCond %{THE_REQUEST} \s/search/([^\s]*)
RewriteRule . test.php?c=index&m=search&keywords=%1 [L,QSA]

And we just need to put . (dot) in RewriteRule pattern and use %1 instead of $1

查看更多
登录 后发表回答