Proper Implementation of Apache’s <If> Directive in .htaccess: Examples and Common Pitfalls


2 views

The <If> directive in Apache allows for conditional execution of configuration directives based on server variables. The correct syntax requires careful attention to expression formatting:

<If "%{VARIABLE_NAME} =~ /pattern/">
    # Configuration here
</If>

Here are several practical implementations that work in .htaccess files:

1. Checking Request Method

<If "%{REQUEST_METHOD} in ['GET','HEAD','OPTIONS']">
    Header set X-Method-Valid "true"
</If>

2. Port-Based Configuration

The original question had an incorrect port check example. Here's the proper way:

<If "%{SERVER_PORT} == '80'">
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</If>

The error in the original question occurred because:

  • SERVER_PORT was checked against HTTP methods (invalid comparison)
  • Missing quotes around the comparison value
  • Possible missing expression delimiters

For more complex scenarios:

<If "(%{HTTP_HOST} =~ /example\.com/) && (%{HTTPS} != 'on')">
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</If>
  • Always wrap expressions in double quotes
  • Use proper comparison operators: ==, !=, <, >, =~ (regex match)
  • For string lists, use square brackets: ['value1','value2']
  • Combine conditions with && (AND) or || (OR)
  1. Verify AllowOverride includes FileInfo (required for <If> directives)
  2. Check Apache error logs for specific syntax errors
  3. Test with simpler conditions first
  4. Ensure you're using Apache 2.4+ (earlier versions don't support this syntax)

The <If> directive in Apache's .htaccess allows for conditional execution of configuration directives based on various server variables. Unlike IfDefine or IfModule, it evaluates expressions at request time.

Your example contains a logical error - comparing SERVER_PORT (which is numeric) with HTTP methods. Here's the correct way to check request methods:

<If "%{REQUEST_METHOD} in ['GET','HEAD','OPTIONS']">
    # Configuration for safe methods
    Header set X-Safe-Method "true"
</If>

For port checking (which appears to be what you intended):

<If "%{SERVER_PORT} == 80">
    RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
</If>

The 500 error you encountered typically occurs when:

  • Using incorrect expression syntax (missing quotes, wrong operators)
  • Comparing incompatible variable types
  • Having unclosed <If> blocks

Combine multiple conditions:

<If "%{REQUEST_URI} =~ /\.php$/ && %{QUERY_STRING} =~ /debug=1/">
    php_flag display_errors on
</If>

Check request headers:

<If "%{HTTP_USER_AGENT} =~ /Mobile/">
    RewriteRule ^(.*)$ /mobile/$1 [L]
</If>

While powerful, overusing <If> can impact performance. For static conditions, consider:

  • IfModule for module availability checks
  • IfDefine for build-time conditions
  • Environment variables for complex logic

Always test .htaccess changes gradually. Use:

apachectl configtest

Or check error logs for specific syntax errors when encountering 500 errors.