0

Possible this question has already been answered but I didn't find any answer after hours of searching.

I need to put the site under "maintenance mode" and redirect/rewrite all requests to site_down.html, but at the same time I need the site to be available if I enter the address like files are in a subfolder.

ex:

if I type http://example.com/login.php I need site_down.html to be displayed. but if I specify http://example.com/test/login.php I need real login.php do be displayed.

I need this to be done with rewrite, so copying everything to another directory isn't a solution.

I tried a couple dozens of combinations, but I'm still unable to achieve what I need

This is one version of my .htaccess file ():

DirectoryIndex site_down.html
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^test\/(.*)$ $1 [S=1]
    RewriteRule ^(.*\.php)$ site_down.html
    RewriteRule .* - [L]
</IfModule>

This code should rewrite all requests with "test/*" to "parent folder" and skip next rewrite rule and then terminate rewriting at RewriteRule .* - [L]. If there is no "test/" in url - all request should be rewritten to site_down.html

What am I doing wrong?

Could you suggest any valid solutions, please?

Thank you.

Alfa3eta
  • 405
  • 2
  • 8

1 Answers1

1

Essentially, you are searching for 2 rules. One rule will translate a virtual subdirectory to the working files. The other rule will translate the url to the working files to a splash page. We just have to make sure that if the first rule matches, the second rule doesn't match. We can do this by making sure " /test/" (including that leading space) was not in THE_REQUEST (or the string that the client sent to the server to request a page; something in the form of GET /test/mypage.php?apes=bananas HTTP/1.1). THE_REQUEST doesn't change on a rewrite, which makes it perfect for that. Skipping a rule like you did usually doesn't have the effect you expect, because mod_rewrite makes multiple passes through .htaccess until the resulting url doesn't change anymore, or it hits a limit and throws an error. The first time it will skip the rule, but the second time it will not do that.

RewriteCond %{THE_REQUEST} !\ /test/
RewriteRule \.php site_down.html [L]

RewriteRule ^test/(.*)$ $1 [L]
Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • "The first time it will skip the rule, but the second time it will not do that" - that's right, but isn't this supposed to terminate rewriting? RewriteRule .* - [L] – Alfa3eta Jun 12 '14 at 14:34
  • The `L` flag in `.htaccess` will only terminate this round through .htaccess (where the `L` flag in httpd.conf will terminate rewriting completely). If the url hasn't been changed at all, it should not go through .htaccess again, but the first rule did change the url. It will therefore go through .htaccess a second time. In a sufficient recent version of Apache you can use the `END` flag if you really need to. Most of the time it is easier and more convenient to rethink the situation and just make it logically correct (so it always works) instead of stopping early and hope for the best – Sumurai8 Jun 12 '14 at 14:38
  • I didn't mean just [L] flag. As mentioned in this answer http://stackoverflow.com/a/6800150/1105947 , this rule RewriteRule .* - [L] should exit rewriting completely – Alfa3eta Jun 12 '14 at 14:41
  • No :-) There is a difference between "this rule does not rewrite anything" and "this rewrite round nothing is rewritten". You have 3 rules, where the 3rd rule is the one that does not do anything. Apache will only not start the next rewrite round if "nothing is rewritten this round". However, your rule 1 is matched before rule 3. Something *is* rewritten that round. In fact, your .htaccess file will behave exactly the same if you would remove the third rule. – Sumurai8 Jun 12 '14 at 15:00