Rewrite Rule not working within <If>-block in .htaccess on Apache 2.4

47 Views Asked by At

I'm lost. My Rewrite Rule does work fine till the moment that I place it within an <If>-block.

When I search here for answers, via google, and via ChatGPT, I do get a mixed image of whether this is possible at all, or not.

Anyone a suggestion what I might have to change to get this working on the Apache 2.4 server of my webhoster?

SetEnv MAINTENANCE_MODE 1

RewriteEngine On

# REWRITE REQUESTS TO /MAINTENANCE(/) TO /MAINTENANCE.HTML
RewriteRule ^maintenance/?$ /maintenance.html [L,END]

<If "%{ENV:MAINTENANCE_MODE} == '1'">
    
    # EXCLUDE IPS FROM THIS REWRITE
    RewriteCond %{REMOTE_ADDR} !=1.2.3.41
    RewriteCond %{REMOTE_ADDR} !=1.2.3.42

    # EXCLUDE MAINTENANCE.HTML AND THE MAINTENANCE URL ITSELF FROM BEING REDIRECTED
    RewriteCond %{REQUEST_URI} !^/maintenance\.html$
    RewriteCond %{REQUEST_URI} !^/maintenance/?$
    
    # REDIRECT ALL OTHER IPS TO THE MAINTENANCE PAGE
    RewriteRule ^(.*)$ /maintenance/ [R=302,L]

</If>

Btw - I've checked with AddType application/x-lsphp83 .php inside the <If>-block that the If-condition is working.

1

There are 1 best solutions below

1
MrWhite On BEST ANSWER

This is most probably due to the order of processing. SetEnv is processed very late. <If> expressions are evaluated early, but merged late. mod_rewrite is processed very early and behaves "differently" when enclosed in an <If> block.

Try the following instead...

  • Use SetEnvIf to set the env var, which is processed early.
  • No need for the <If> expression since the env var can be evaluated in a mod_rewrite condition.

For example:

SetEnvIf ^ ^ MAINTENANCE_MODE=1

RewriteEngine On

# REWRITE REQUESTS TO /MAINTENANCE(/) TO /MAINTENANCE.HTML
RewriteRule ^maintenance/?$ /maintenance.html [END]

# Only when MAINTENANCE_MODE is set
RewriteCond %{ENV:MAINTENANCE_MODE} =1

# EXCLUDE IPS FROM THIS REWRITE
RewriteCond %{REMOTE_ADDR} !=1.2.3.41
RewriteCond %{REMOTE_ADDR} !=1.2.3.42

# EXCLUDE MAINTENANCE.HTML AND THE MAINTENANCE URL ITSELF FROM BEING REDIRECTED
RewriteCond %{REQUEST_URI} !^/maintenance(\.html|/)?$

# REDIRECT ALL OTHER IPS TO THE MAINTENANCE PAGE
RewriteRule ^ /maintenance/ [R=302,L]

Although, consider sending a 503 instead to serve a custom maintenance page.