Page is a not externally linkable
- Code, Content, and Presentation
-- Apache Web Server
---- Weird thing with a rule


g1smd - 12:03 pm on Feb 13, 2013 (gmt 0)


Consider this simple scenario:

RewriteCond %{QUERY_STRING} ^digits=([0-9]+)&letters=([a-z]+)$
RewriteRule ^(index\.php)?$ http://www.example.com/%1-%2? [R=301,L]


RewriteRule ^([0-9+])-([a-z]+) /index.php?digits=$1&letters=$2 [L]

The first rule redirects requests for
example.com/index.php?digits=123&letters=abc or for example.com/?digits=123&letters=abc to www.example.com/123-abc

The browser then requests
www.example.com/123-abc which is internally rewritten by the second rule to /index.php?digits=123&letters=abc

This internal request should then invoke the index.php file, pass the parameters to it and the PHP should then deliver the page of HTML and content.

Unfortunately, the internally rewritten pointer now matches the pattern in the redirecting rule and
www.example.com/index.php?digits=123&letters=abc is exposed back out on to the web as a URL and the user is redirected again in a loop. The PHP file never gets invoked.

The redirecting rule should test that THE_REQUEST contained query string parameters. This stops the rule being invoked when the internal pointer has parameters as a result of a previous internal rewrite. In that case, the requested URL was
www.example.com/123-abc without parameters.

The pattern for matching
THE_REQUEST is necessarily more complex. It usually begins ^[A-Z]{3,9}\ / and often ends \ HTTP/ with various other stuff in the middle to match optional index.php, e.g. /(index\.php)? followed by parameters. Rather than use \?digits=[0-9]+&letters=[a-z]+ here, the parameters part can often be generalised to \?[^\ ]+ or similar.

REQUEST_URI is modified as a result of internal rewrites, THE_REQUEST is not.


Thread source:: http://www.webmasterworld.com/apache/4544878.htm
Brought to you by WebmasterWorld: http://www.webmasterworld.com