if-statementmod-rewriteapache2.4

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


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.


Solution

  • 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...

    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.