Friday, May 12, 2017

How to prevent apache from restarting the rewrite processing within a "directory context"



I have the following in my virtualhost for SSL connections (my non ssl virtual host looks the same, but without the first rule set for redirecting).



DocumentRoot /var/www/example.com/public/

#only mod_rewrite configuration is shown here

RewriteEngine on
RewriteBase /


RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico

RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]



My intention is to have any page request not matching (signup|login|welcome|thankyou) to be redirected to the non ssl virtual host without further processing, otherwise do not redirect, but process the request within the SSL virtual host.



The first RewriteRule set takes care of the redirect, while the second RewriteRule set takes care of normal page processing.



Without the first rule set, all requests load correctly under the SSL virtual host.




With the first rule set, redirects works just fine that do not match the listed resources. eg. a request for



https://example.com/about


redirects to



http://example.com/about



But when requesting the signup, login, welcome, and thankyou pages, the problem occurs. Those requests are also redirected to the non ssl site, but in a broken manner. A request for



https://example.com/signup


redirects to



http://example.com/index.php?q=signup



It would seem that the first rule set goes unmatched (as would be expected), then after the second rule set is processed, the first rule set gets applied again (not expected).



I can not match this unexpected behavior to any documented functionality.



Any ideas?



Edit



I've found some obscure references in the documentation to apache re-running the rules when a rule match occurs within a "directory context", however, the reference was in regards to .htaccess. My rewrite is occurring inside of a tag within my tag. I'm currently testing moving the rewrite outside of the context - this certainly seems to change the behavior, but I have not yet made it work as I need.




Edit2



The issue is certainly caused by apache restarting the rewrite processing when the rule processing exists within a directory context. I've moved the rule processing outside of the tag. However, now the RewriteCond lines do not work... eg.



RewriteCond %{REQUEST_FILENAME} -f


because apache has not yet resolved the requested resource to a file mapping using the DocumentRoot. What a mess.



So, I then manually prepend the value I specify in DocumentRoot to the RewriteCond. However, this seems like a poor hack. eg.




RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f


So, now I'm looking for a way to prevent apache from restarting the rewrite process when within a directory context, or second best, a better way to specify the necessary RewriteConds at the level.


Answer



I've settled on the following solution, placing the rewrites outside of any sections. This allows me to redirect any request that shouldn't be SSL to the non SSL site, while at the same time allowing any static content to be served over SSL (images, css, js etc).




...

RewriteEngine on

RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]


RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
...


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...