Search code examples
phpapache.htaccessmod-rewrite

How to perform If statement in .htaccess if the pages are specific


I am getting this as response,when I try an if statement to run a RewriteRule when the pages are specific. My apache server is 2.4 it is also in my screen shot. What i want to do in my code is

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f


RewriteRule ^index$ ./index.php
RewriteRule ^zindex$ ./zindex.php
RewriteRule ^logout$ ./logout.php
RewriteRule ^login$ ./login.php
RewriteRule ^zlogin$ ./zlogin.php
RewriteRule ^404$ ./404.php





#write if statement to check pages that is being loaded else fire for new username

    <If "%{HTTP_HOST} == 'index.php' || %{HTTP_HOST} == 'ajaxsignlog.php' || %{HTTP_HOST} == 'ajaxsignlog1.php' || %{HTTP_HOST} == 'ajaxupload.php' || %{HTTP_HOST} == 'connect.php' || %{HTTP_HOST} == 'logout.php' || %{HTTP_HOST} == 'password.php' || %{HTTP_HOST} == 'top.php' || %{HTTP_HOST} == 'zindex.php' || %{HTTP_HOST} == 'ztop.php'">
                     // do not rewrite rule
    </If>
    <Else> //do some rewrite rules here
    RewriteRule ^ profile.php [NC,L]
    RewriteRule ^profile/([0-9a-zA-Z]+) profile.php?id=$1 [NC,L]

    RewriteRule ^ zprofile.php [NC,L]
    RewriteRule ^zprofile/([0-9a-zA-Z]+) zprofile.php?id=$1 [NC,L]
    </Else>

Solution

  • RewriteRule ^ profile.php [NC,L]
    RewriteRule ^profile/([0-9a-zA-Z]+) profile.php?id=$1 [NC,L]
    

    The 400 Bad Request is caused by the relative path substitution inside an <If>/<Else> construct. For some reason, the directory-prefix that is added back in this context is always *If/ (regardless of the whether the directive is in the <If> or <Else> block) - which will likely result in a 400 Bad Request when performing an internal rewrite (or a 403 Forbidden if performing an external redirect).

    But also, in an <If>/<Else> construct, the RewriteRule pattern matches against an absolute filesystem path, not a root-relative URL-path. So, the second directive above will never match.

    So, if these restrictions/differences affect you then don't use mod_rewrite and Apache <If> expressions together. There are also other issues with how directives outside the <If> expression are also affected. (Personally, I would avoid mixing the two if at all possible.)

    See also my answer to the following question on ServerFault that goes into more detail: https://serverfault.com/questions/1054363/bad-request-from-rewriterule-after-putting-if-directive

    You don't need an <If>/<Else> expression to do what you are wanting. mod_rewrite itself offers the mechanism to do this, without additional tools. However, exactly how you implement this can depend on exactly what you are trying to do.

    In the example in the question where you want to skip a series of rewrites if the request matches one of a series of URLs then you could do something like this:

    RewriteCond %{REQUEST_URI} =/index.php [OR]
    RewriteCond %{REQUEST_URI} =/ajaxsignlog.php [OR]
    RewriteCond %{REQUEST_URI} =/ajaxsignlog1.php [OR]
    RewriteCond %{REQUEST_URI} =/ajaxupload.php [OR]
    RewriteCond %{REQUEST_URI} =/connect.php [OR]
    RewriteCond %{REQUEST_URI} =/logout.php [OR]
    RewriteCond %{REQUEST_URI} =/password.php [OR]
    RewriteCond %{REQUEST_URI} =/top.php [OR]
    RewriteCond %{REQUEST_URI} =/zindex.php [OR]
    RewriteCond %{REQUEST_URI} =/ztop.php
    RewriteRule ^ - [S=10]
    
    # 10 Rules follow that are skipped when any of the above URLs are requested
    # :
    # :
    
    

    The S=10 flag on the RewriteRule directive indicates the number of complete rules that are skipped when any of the preceding URLs are matched exactly.

    See also my answer to the following question for some more ideas about ways to implement conditional branching in .htaccess: Grouping RewriteRule by RewriteCond with .htaccess