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

I'm trying to set up a web site to allow the creation of a semaphore file to close the site. The logic I want to follow is:

  1. when the semaphore file exists
  2. and the request is not for /style.css or /favicon.icon
  3. show the content of /closed.html

I have 1 and 3 working, but my exceptions for 2 result in a processing loop when style.css or favicon.ico are requested. This is my most recent attempt:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/style.css
RewriteCond %{REQUEST_URI} !^/favicon.ico
RewriteCond /usr/local/etc/site/closed -f
RewriteRule ^.*$ /closed.html [L]

This is in a VirtualHost block, not in a Directory. There is no .htaccess file in play.

I have also recently tried this, based on an answer I found elsewhere, but with the same (looping) result:

RewriteCond %{REQUEST_URI} ^/style.css [OR]
RewriteCond %{REQUEST_URI} ^/favicon.ico
RewriteRule ^.*$ - [L]
RewriteCond /usr/local/etc/site/closed -f
RewriteRule ^.*$ /closed.html [L]

I expect a request for /style.css or /favicon.ico to fail to match one of the first two rewrite conditions, which should prevent the URI from being rewritten, which should stop the mod_rewrite iteration. However, mod_rewrite seems to think the URI has been rewritten in those cases, and iterates over the rules again (and again, and again). The above works properly in all cases except for style.css or favicon.ico. In those cases I exceed the loop limits.

What am I missing here to cause the rewrite iteration to stop when someone requests style.css or favicon.ico?

EDIT: Here's a loglevel 9 example of what happens using the first ruleset when a request arrives for /style.css. This is just the first two iterations.. it continues to loop identically until the limit is reached.

2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1db0a0/initial] (2) init rewrite engine with requested uri /style.css
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1db0a0/initial] (3) applying pattern '^.*$' to uri '/style.css'
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1db0a0/initial] (4) RewriteCond: input='/style.css' pattern='!^/style.css' => not-matched
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1db0a0/initial] (1) pass through /style.css  
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1dd0a0/initial] (2) init rewrite engine with requested uri /style.css
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1dd0a0/initial] (3) applying pattern '^.*$' to uri '/style.css'
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1dd0a0/initial] (4) RewriteCond: input='/style.css' pattern='!^/style.css' => not-matched
2001:4900:1044:0:145f:826e:6436:dc1 - - [29/May/2014:15:29:26 +0000] [host.example/sid#80c1c48b0][rid#80c1dd0a0/initial] (1) pass through /style.css
share|improve this question
    
"In those cases I exceed the loop limits", is it Apache that complains about this, or your browser? –  yorn May 29 at 21:00

3 Answers 3

I tried your setup in an Apache setup on an up-to-date CentOS 6.

Here is my config

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/style.css
RewriteCond %{REQUEST_URI} !^/favicon.ico
RewriteCond /tmp/closed -F
RewriteRule ^.*$ /closed.html [L]

Following is a log that proves that it works:

$ curl https://localhost/
<!DOCTYPE html>
<title>It works!</title>
<p>It works!</p>

$ curl https://localhost/style.css
html {
background: black;
color: white;
}

$ touch /tmp/closed
$ curl https://localhost/
<!DOCTYPE html>
<title>We're closed</title>
<p>We're closed</p>

$ curl https://localhost/style.css
html {
background: black;
color: white;
}

EDIT this is not what you want for your question, I leave it here so it may help others with similar problems.

Another way to solve your problem is like this

<LocationMatch "^/(?!410\.html)">
    RedirectMatch gone .*
</LocationMatch>
ErrorDocument 410 /410.html

Where 410.html is your error page. This will send the 410 Gone status code to the client, indicating that the site is gone and is not coming back.

share|improve this answer
    
And [R] sends back a redirect to the browser. An [L] should end processing and internally substitute content. If I request anything other than the two excepted files this works exactly as expected. Removing the [L] affects nothing, and I still get the loop on a request for /style.css –  mpounsett May 29 at 15:45
    
Yep, my bad. httpd.apache.org/docs/current/rewrite/flags.html I was thinking of Location –  yorn May 29 at 15:48
    
I removed the wrong portion. After re-reading the flags document, isn't [PT] a better choice than [L] in your case? The fact that you're getting a loop suggests that a redirect is actually happening. –  yorn May 29 at 15:51
    
No, I don't want any other substitution processing to occur. Also, just on the off-chance I tried that, and it results in a redirect, which is also not what I want. A redirect also then results in a loop for all requests, not just the two exceptions. –  mpounsett May 29 at 15:54
    
heh, found it! the -F for RewriteCond is case sensitive. –  yorn May 29 at 16:00

/closed.html is the cause of this endless loop.

I think this might solve your problem. I just added one line to your first attempt (see line 4) :

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/style.css
RewriteCond %{REQUEST_URI} !^/favicon.ico
RewriteCond %{REQUEST_URI} !^/closed.html
RewriteCond /usr/local/etc/site/closed -f
RewriteRule ^.*$ /closed.html [L]
share|improve this answer
    
No, requests for things other than style.css and favicon.ico work fine. It's just the exceptions that are the problem. You can see from the log entry that those are never rewritten to /closed.html .. they're continually rewritten as themselves. –  mpounsett May 29 at 18:38
    
I tried your first ruleset in a fresh Apache installation, in the default VirtualHost. Actually I don't have any error in my logs, everything is working fine. (Tested on Apache 2.2.22 - Ubuntu 12.04.4 LTS) –  nedstark May 29 at 19:24

Try to add

RewriteLog /tmp/rewrite.log
RewriteLogLevel 4

And look in the log file if it could be helpful.

share|improve this answer
    
Yeah, I've been looking at the log; that's how I know it thinks something's changing on every iteration. The log indicates the RewriteCond rules are matching the way I expect, and it's resulting in passthrough of the request, but then it loops back over the request anyway. –  mpounsett May 29 at 15:25
    
But are you trying to get style.css using a browser or something else? I've tested your "most recent attempt" on an apache server and it works. –  alciregi May 29 at 15:29
    
Are you sure there are no more rewrite rules after that one? –  alciregi May 29 at 15:37
    
It doesn't matter by what method the request arrives.. a request is a request. I've edited the question to show some example logging. Yes, I'm sure there are no other rewrite rules; they should show up in the logs anyway, if they exist, shouldn't they? –  mpounsett May 29 at 15:42

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.