Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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/
<Directory "/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]
</Directory>

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 <Directory> tag within my <VirtualHost> tag. I'm currently testing moving the rewrite outside of the <Directory> 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 <Directory> 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 <VirtualHost> level.

share|improve this question

2 Answers 2

I suggest adding the following to your configuration, which will give you a detailed log of what mod_rewrite is doing, and why. That may help clear up why you have such behavior:

RewriteLog /tmp/rewrite.log
RewriteLogLevel 9

Once you're done analyzing this, make sure to remove these lines though, as they do impact performance.

share|improve this answer
    
Yes, what I stated in my edit is certainly what is being shown in the log. An INTERNAL REDIRECT occurs, at which point the rewrite process restarts, and the first rule gets applied to the internally rewritten rule. I've tried using the 'NS' flag to no affect. Sorry, I can't up-vote your answer at this point, my reputation is too low. –  chris Jan 28 '10 at 9:41
up vote 0 down vote accepted

I've settled on the following solution, placing the rewrites outside of any <Directory ...> 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).

<VirtualHost ...>
  ...
  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]
  ...
</VirtualHost>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.