Tuesday, November 18, 2014

mod rewrite - RewriteCond ignored in httpd.conf



Put simply this works in htaccess:




RewriteEngine on

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d

RewriteRule ^([^/]+)/?$ https://example.net?u=$1 [L,NC,R=301]


But when I move it to httpd.conf it does nothing. I have tried in the directory directive and that also makes no difference.




As a test the below in httpd.conf does have an affect, it re-directs, but does so to all pages i.e the condition is ignored.



RewriteEngine on

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d

RewriteRule ^(.*)$ https://example.net?u=$1 [L,NC,R=301]

Answer





RewriteRule ^([^/]+)/?$ https://example.net?u=$1 [L,NC,R=301] 


But when I move it to httpd.conf it does nothing.




Because in a server context the RewriteRule pattern will never match. In a server context the URL-path is root-relative, starting with a slash. In .htaccess the URL-path is less the directory-prefix, so never starts with a slash.





I have tried in the directory directive and that also makes no difference.




That should have worked, providing you included the correct directory path. (And restarted Apache.) However, if you still had a .htaccess file that enabled the rewrite engine then this would have overridden the server directives in the container, so the directives wouldn't have done anything still.




As a test the below in httpd.conf does have an affect, it re-directs, but does so to all pages i.e the condition is ignored.



RewriteEngine on


RewriteCond %{SCRIPT_FILENAME} !-f
:



Because in a server context the request has not yet been mapped to the filesystem, so SCRIPT_FILENAME (or REQUEST_FILENAME) does not yet contain the full filesystem path (it simply contains the URL-path), so this condition always evaluates to true (the "URL-path" being tested is not a physical file - which is probably correct).



You need to use a look-ahead instead in order to determine the final value. ie. %{LA-U:REQUEST_FILENAME}.



So, in a server (or virtualhost) context you would need to use the following instead:




RewriteEngine on

RewriteCond %{LA-U:REQUEST_FILENAME} !-f
RewriteCond %{LA-U:REQUEST_FILENAME} !-d

RewriteRule ^/([^/]+)/?$ https://example.net?u=$1 [L,R=301]


Note the slash prefix on the RewriteRule pattern.




The NC flag is superfluous here.


No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...