skip to Main Content

I have the following .htaccess file on my Apache Server, which does not work

<If "%{HTTP_HOST} == 'www.example.com'">
    RewriteCond %{REMOTE_ADDR} !^192.168.8.8$
    RewriteRule .* - [F]

    RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]

</If>

The code works fine without the if-Statement.
But with the if Statement

    RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]

does not work. It throws a "404 Not Found error"

2

Answers


  1. Chosen as BEST ANSWER

    I came myself to the following solutiuon. which i really like.

    ### Access control
    ###
    ###
    # Set the environment variable if the HTTP_HOST matches 'www.somehost.com'.
    SetEnvIf Host "www.somehost.com" IS_HOST=true
    
    # Use the set environment variable in a conditional
    RewriteCond %{ENV:IS_HOST} true
    RewriteCond %{REMOTE_ADDR} !^192.168.8.8$
    RewriteRule .* - [F]
    
    
    
    ### Rewrite Urls
    ###
    ###
    RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
    

  2. <If "%{HTTP_HOST} == 'www.example.com'">
        RewriteCond %{REMOTE_ADDR} !^192.168.8.8$
        RewriteRule .* - [F]
    
        RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
    
    </If>
    

    The "problem" is because the mod_rewrite directives are embedded inside an <If> expression. <If> blocks are merged very late, after the request has been mapped back to the file system. In this context, the RewriteRule pattern matches against the absolute filesystem path, not a relative URL-path, so the second rule above will not match as expected.

    So, the rule would need to be rewritten like this instead:

    RewriteRule ^/abs/file/path/to/docroot/([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
    

    Or, more simply, remove the start-of-string anchor – although this does make the match somewhat ambiguous:

    RewriteRule /([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
    

    Or, preferably, avoid the <If> construct altogether as you can get unexpected conflicts with other directives (outside of the <If> construct). For example:

    RewriteCond %{HTTP_HOST} =www.example.com
    RewriteCond %{REMOTE_ADDR} !^192.168.8.8$
    RewriteRule ^ - [F]
    
    RewriteCond %{HTTP_HOST} =www.example.com
    RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
    

    (The NC flag is not necessary in the 2nd rule, since you are already matching A-Z and a-z in the regex. ALso, use ^ instead of .* in the first rule, since you don’t need to actually match anything here.)

    If you have many such rules that apply to just this one host then you can reverse the logic and skip the N rules that follow when the requested host is not what is expected. For example:

    # Skip the next 2 rules if the requested host is not "www.example.com"
    RewriteCond %{HTTP_HOST} !=www.example.com
    RewriteRule ^ - [S=2]
    
    RewriteCond %{REMOTE_ADDR} !^192.168.8.8$
    RewriteRule ^ - [F]
    
    RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search