Search code examples
mod-rewriteapache2browser-refresh

Apache2 - It seems that rewrite condition is not always applied


I would like to redirect to /lost/index.php only when the image file does not exists. When I try it - it seems that it does not work on browser refresh If I invoke it with a file which exists on the server

/images/image1.jpg
  • it shows me a file (GOOD - the file exists ) but if I refresh the browser it redirects me to /lost/index.php (WHICH IS BAD)

Below my rules

RewriteEngine On
RewriteLog      /var/log/apache2/rewrite.log
RewriteLogLevel 3

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/images/(.*)$    /lost/index.php?image=$1 [L,R]

Any ideas ?


Solution

  • So I solved it.

    If you define your rewrite rules inside element they should look like

    <Directory /var/www/local.example.com>
    
            ...
            RewriteEngine On
    
            RewriteCond %{REQUEST_FILENAME} !-l
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^images/(.*)$    /lost/index.html?image=$1 [R]
    </Directory> 
    

    If you define them "globally" outside the (per-server context) they should look like

    RewriteEngine On
    RewriteCond %{LA-U:REQUEST_FILENAME} !-l
    RewriteCond %{LA-U:REQUEST_FILENAME} !-d
    RewriteCond %{LA-U:REQUEST_FILENAME} !-f
    RewriteRule ^/images/(.*)$    /lost/index.html?image=$1 [R] 
    

    This is due the fact that if used in per-server context (i.e., before the request is mapped to the filesystem) SCRIPT_FILENAME and REQUEST_FILENAME cannot contain the full local filesystem path since the path is unknown at this stage of processing. Both variables will initially contain the value of REQUEST_URI in that case. In order to obtain the full local filesystem path of the request in per-server context, use an URL-based look-ahead %{LA-U:REQUEST_FILENAME} to determine the final value of REQUEST_FILENAME.

    What is also important - the pattern has to be different in both cases. In second case it has to starts with '/' while in the first one not. This is due the fact that REQUEST_FILENAME contains the '/' at the beginning for the second case but it does NOT for the first one