1

I'm trying to put my webpage into Maintenance Mode by using htaccess to redirect any page that begins with (domain name) to a maintenance.php file within a folder inside the root. I got this to work on localhost with no issues, but it just won't work when I put it on my web host server. It keeps saying there are too many redirects (there's an infinite loop going on).

# MAINTENANCE-PAGE REDIRECT
<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{REMOTE_ADDR} !^100\.184\.54\.96
 RewriteCond %{REQUEST_URI} !/maintenance/maintenance.php$ [NC]
 RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
 RewriteRule .* /maintenance/maintenance.php [R=302,L]
 </IfModule>

I tried plenty of the answers given to other questions such as

.htaccess error - ERR_TOO_MANY_REDIRECTS

htaccess maintenance page redirect results in "too many redirects" error ...among others. The same error keeps coming. I have another domain (domain-1) redirecting to the current webpage (domain-2), tried turning that off to see if it works, nope.

ArabianMaiden
  • 505
  • 7
  • 24
  • Hi @mslilafowler could you post your complete httpd.conf? The .htaccess seems fine, I cannot spot any error – Ass3mbler Jan 01 '19 at 00:17
  • Hi :) By httpf.conf you surely don't mean the entire apache config document ? http://www.mediafire.com/file/fy68s1lmoc7w70y/httpd.conf/file – ArabianMaiden Jan 01 '19 at 00:20
  • The redirect loop you are seeing would seem to be caused by "something else". The status code reported by your server is a 307, not a 302 as in the directives you posted? However, for "mainentance", consider sending a 503 response (no redirect) instead. See this question on the Webmasters stack: https://webmasters.stackexchange.com/questions/55635/website-is-under-maintenance-how-to-restrict-access – MrWhite Jan 01 '19 at 00:23
  • Yes, I mean exactly the full apache config. If the htaccess isn't working maybe there is some problem in the main config file, interfering with it. – Ass3mbler Jan 01 '19 at 00:24
  • The full Apache config is excessive (and mostly irrelevant). Only mod_alias and mod_rewrite directives are relevant here (from server and vHost contexts). Do you have other directives in your `.htaccess` file? Any other `.htaccess` files? – MrWhite Jan 01 '19 at 00:26
  • @MrWhite I thought about sending a 503 response but I heard that would interfere with SEO and Google's crawling bots. I need the maintenance mode to stay on for +-88 days, would that not considerably affect the SEO? --Nope, this above is the complete .htaccess file contents. I usually work with the rewrite rules without issues, so this is a first... – ArabianMaiden Jan 01 '19 at 00:27
  • A 302 is unlikely to be better (probably worse IMO). A 503 Service Unavailable is specifically for this type of task. However, 88 days is a long time for any kind of maintenance period / downtime. You will likely see a negative SEO impact - whatever method you use - over such a long time period. – MrWhite Jan 01 '19 at 00:31
  • the main httpd.conf seems fine too. Could you share conf/extra/httpd-vhosts.conf? – Ass3mbler Jan 01 '19 at 00:34
  • @MrWhite Ah I see... I just tried using the code in that link you posted with the 503 redirect...Error pages cannot handle php or scripts to run, am I right? My maintenance page is a fancy countdown page. You see, I'm only launching the website in March, more than maintenance it's actually a website construction. I'm already advertising it so when people visit (any directory) of the website, they should go to this fancy countdown page. – ArabianMaiden Jan 01 '19 at 00:35
  • @Ass3mbler Was a link to the `https.conf` file shared? – MrWhite Jan 01 '19 at 00:52
  • @MrWhite yes, here it is: http://www.mediafire.com/file/fy68s1lmoc7w70y/httpd.conf/file – Ass3mbler Jan 01 '19 at 01:00
  • "Error pages cannot handle php or scripts to run, am I right?" - No, error pages can be ordinary PHP pages and do anything a PHP page can do. However, if the site hasn't actually launched yet then this isn't really a 503 - although it could be. In this case I wouldn't "redirect" and just _internally rewrite_ the request to the maintenance page (200 OK response) - but this still may not resolve your "loop". However, a simple "under construction" page is not good for SEO... you should include some basic content about what it is. – MrWhite Jan 01 '19 at 01:01
  • Ironic thing is I haven't even put any content on the website yet, and I've used .htaccess files on other domains (with the same web host, same server/ip address) with no issues. First time trying an actual 'maintenance mode' tho. I'll keep trying the other solutions for now. Thanks for staying with me - Happy new year! – ArabianMaiden Jan 01 '19 at 01:07

2 Answers2

1

After following a ton of suggestions and styles from around the net, I finally came to a solution that worked for this issue.

To redirect all pages and sub-directories for your domain name to a maintenance page, create two files:

  1. maintenance.html (maintenance page)

  2. maintenance.enable (empty file)

Use the following code in your .htaccess file:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^105\.228\.123\.16
RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
RewriteCond %{DOCUMENT_ROOT}/maintenance.enable -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /maintenance.html [R=503,L]
ErrorDocument 503 /maintenance.html
Header Set Cache-Control "max-age=0, no-store"

Be sure to place the 2 files in the same directory as your index page.

That's the solution that worked in my case. I'm yet to try it out with external resources (css/js files and images) but I think it shouldn't take more than some tweaking the above code. Hope it helps someone else too.

EDIT For external resources and styling just add this line:

RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif|css|js|ico)

Be sure to add all of the relevant directories (containing the stylesheets and scripts) in the same directory as the maintenance.html page.

I could be wrong but it seems like a bad idea to use this in conjunction with Header Set Cache-Control "max-age=0, no-store" if you're going to keep the maintenance page up for a while. I leave that for the experts though :-)

ArabianMaiden
  • 505
  • 7
  • 24
  • Glad you got it resolved. Just to clarify, this doesn't "redirect" the request. By setting `R=503` Apache sends an _internal subrequest_ for the `ErrorDocument` (which is preferable). Consequently, the `RewriteRule` _substitution_ in `RewriteRule ^.*$ /maintenance.html [R=503,L]` is superfluous and can be replaced with a hyphen. In other words: `RewriteRule ^ - [R=503]` (the `L` flag is also superfluous because you are not using a 3xx code). – MrWhite Jan 04 '19 at 18:03
  • Incidentally, the _condition_ that checks against `SCRIPT_FILENAME` is also unncessary and can more efficiently be checked by the `RewriteRule` _pattern_ instead. For example: `RewriteRule !maintenance\.html - [R=503]`. (Note that that matches "maintenance.html" _anywhere_ in the URL.) – MrWhite Jan 04 '19 at 18:06
  • @MrWhite Excellent suggestions! :-) – ArabianMaiden Jan 04 '19 at 19:16
0

My maintenance page is a fancy countdown page.

This is actually part of the problem. Your "fancy" page contains links to numerous CSS and JS files (and the favicon.ico file) - 17 files in total - your .htaccess redirect will redirect these requests as well (all to your maintenance.php page - which will trigger further redirects etc.). You'll need to make additional exceptions for these URL/file extensions. For example:

RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^100\.184\.54\.96
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif|css|js|ico)$
RewriteRule !maintenance\.php$ /maintenance/maintenance.php [R=302,L]

The <IfModule mod_rewrite.c> wrapper is not required (you know your server).

The NC flag is not required unless you really do have mixed case extensions.

I realise this isn't a normal "site down for maintenance" type page, however, maintenance pages should ideally link to as few external resources as possible. To avoid issues like the above, but also you don't want to be in a situation where the maintenance page itself cannot be displayed because the site is down for maintenance!

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • Ah I see where you're going... So that in turn causes the infinite loop. --Edit: I just tested the page redirect without *any* scripts - the .htaccess points to a single document with html elements, no images/external links or resources. It gives the same error "redirected too many times". When I look at the bottom of the page, the status keeps saying "Connecting" then "Waiting for (www.domain.co.za)" about 10 times alternatively before the page fails... – ArabianMaiden Jan 01 '19 at 18:24
  • Have you included `ico` in an execption? Browser's will tend to request `favicon.ico`, regardless of whether you are linking to this file in the HTML source. Check the network traffic - what do you see? Otherwise, this shouldn't be triggering a redirect loop. As noted in my comment above, when I checked the network traffic, I could see a 307 response, not a 302 (as this directive states). If you are still seeing this; where is the 307 coming from? – MrWhite Jan 02 '19 at 00:02
  • Ok, I tried the same thing on another domain. I checked the network traffic, at first it says 22 requests (1 fail and the rest are 302), then it says 8 requests with 200 success responses... I just can't figure this out. Have a look if you can, while the network traffic is open: https://www.unidrones.co.za (P.S. I have included the iso, image formats, scripts and css in the exception rules) – ArabianMaiden Jan 02 '19 at 00:41
  • I notice you are using `/maintenance/test.php` in this new test - presumably you have updated these directives accordingly? The browser simply times out after a certain number of redirects. The "8 requests with 200 success" are the browsers default error response (not related to your site). Do you have any other directives in your `.htaccess` file? Any other `.htaccess` files? – MrWhite Jan 02 '19 at 00:58
  • Nothing at all, I changed the directives and created a new file test.php so that I know the file is not calling any external resources. I also tested it locally (working great, as expected on localhost). As soon as I put it up live the page fails... – ArabianMaiden Jan 02 '19 at 10:47
  • Something is a bit odd here... this _should_ work!? If you are linking to no other external resources then it's just a one-liner (to redirect everyone; including yourself): `RewriteRule !test\.php$ /maintenance/test.php [R,L]`. A redirect loop would imply the `RewriteRule` _pattern_ is failing to "match" (negated regex). Just try the following instead: `RewriteRule !. /maintenance/test.php [R,L]` and request `example.com/`. – MrWhite Jan 03 '19 at 23:07
  • Just going back to your original question... you said that it worked OK on your localhost, even with the code you posted - that shouldn't have worked given the complexity of your maintenance page at the time? The `httpd.conf` you shared appears to be that of the local Windows development (XAMPP) server, not a live production server? – MrWhite Jan 03 '19 at 23:08
  • Yes, it worked perfectly on Localhost. I know this sounds silly, but is there a possibility that browsers cannot read files 'higher' than the parent directory (in my case, the www.pedlar.co.za directory) and it's looking for the maintenance file _inside_ that directory therefore it's causing a kinda loop? -- OK you're asking for my webhost's config...I think this is it: https://www.pedlar.co.za/phpinfo.php ? (P.S. I'm still testing on https://unidrones.co.za for now, the www.pedlar.co.za website has the pages loaded directly as real pages, not maintenance redirects) – ArabianMaiden Jan 03 '19 at 23:40
  • "'higher' than the parent directory" - I'm not sure what you mean exactly? If you are at `/maintenance/test.php` then that would be "higher than the document root"? - which is not possible. `www.pedlar.co.za` isn't a directory, it's a hostname. (Although I see in your phpinfo you do have a `pedlar.co.za` filesystem directory.) That's just details about your PHP config - not actually the Apache server config (which is what Ass3mbler was asking about). Incidentally, your server is LiteSpeed, not Apache - although that shouldn't matter in this instance. – MrWhite Jan 04 '19 at 00:27
  • Did you try changing the `RewriteRule` _pattern_ to `!.`? Any change? Still a redirect loop? – MrWhite Jan 04 '19 at 00:30
  • In other words, can a browser get to your 'root' directory, one step higher than the 'public_html' directory where we're supposed to store sensitive stuff like .htpasswd files? My maintenance directory with the scripts are inside that 'utmost parent' directory, which makes me wonder if the path to the directory is causing the loop. ---Yes, I tried changing it, but that !. resulted in a 404 not found error (test.php was not found)? – ArabianMaiden Jan 04 '19 at 01:18
  • It sounds like you are trying to redirect to a file above the document root from the client's browser? - that is not possible. But how are you even referencing that file in the `RewriteRule` _substitution_? A "root-relative" URL-path is relative to the document-root (not your account root?). But even this shouldn't result a redirect-loop (although it would be interesting to see your actual directives) - you would expect to see a 404. This implies the `RewriteRule` _pattern_ you were using (before changing to `!.`) was incorrect. – MrWhite Jan 04 '19 at 12:02
  • Thanks for staying with me - I just solved this _frustrating_ problem. This is what I used: `RewriteEngine On #RewriteCond %{REMOTE_ADDR} !^105\.228\.123\.16 RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f RewriteCond %{DOCUMENT_ROOT}/maintenance.enable -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /maintenance.html [R=503,L] ErrorDocument 503 /maintenance.html Header Set Cache-Control "max-age=0, no-store"` , it now redirects any subdirectory or main page to the maintenance page! – ArabianMaiden Jan 04 '19 at 17:07
  • Whoops, that looks untidy. I moved it to an answer. See it working like a charm :) https://www.unidrones.co.za – ArabianMaiden Jan 04 '19 at 17:19