Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use a mod_rewrite server variable inside a RewriteCond's CondPattern?

Using mod_rewrite, I'd like to use a Server Variable as part of the CondPattern of a RewriteCond, something like:

RewriteCond %{HTTP_HOST} !^%{SERVER_NAME} [NC]
                           ^^^^^^^^^^^^^^

This would be really useful. I know that the CondPattern is a Perl-compatible Regular Expression, and that that means for example the {} chars in my example would need to be escaped somehow. I've left it as-is simply to demonstrate the idea.

The aforementioned docs don't mention anything about it as far as I can find, and googling around I wasn't able to find anything definitive. My hunch is the answer is no, but I'd like to know for sure.

like image 774
Madbreaks Avatar asked Feb 28 '13 19:02

Madbreaks


People also ask

What is mod_rewrite in Apache?

The mod_rewrite module uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. By default, mod_rewrite maps a URL to a filesystem path. However, it can also be used to redirect one URL to another URL, or to invoke an internal proxy fetch.

How do you check mod_rewrite is enabled or not?

In PHP, there is an inbuilt function called 'phpinfo'. By using this function, we can output all the Loaded Modules and see the 'mod_rewrite' is enabled or not. Syntax: phpinfo();

What is RewriteCond and RewriteRule?

There are two main directive of this module: RewriteCond & RewriteRule . RewriteRule is used to rewrite the url as the name signifies if all the conditions defined in RewriteCond are matching. One or more RewriteCond can precede a RewriteRule directive.

What is Apache rewrite rules?

RewriteRule specifies the directive. pattern is a regular expression that matches the desired string from the URL, which is what the viewer types in the browser. substitution is the path to the actual URL, i.e. the path of the file Apache servers. flags are optional parameters that can modify how the rule works.


1 Answers

CondPattern does not expand %{VAR} variables or %N backreferences to the previous RewriteCond, so David's suggestion

RewriteCond %{SERVER_NAME} ^(.*)$
RewriteCond %{HTTP_HOST} !%1

will succeed whenever %{HTTP_HOST} does not contain the literal string %1, which is not what you want.

What you want, according to your example

RewriteCond %{HTTP_HOST} !^%{SERVER_NAME} [NC]

is to match if HTTP_HOST does not start with SERVER_NAME (case-insensitive). You can implement this with a single RewriteCond if you include SERVER_NAME in the TestString, capture it in the regex, and use \N to reference it again:

RewriteCond "%{SERVER_NAME} %{HTTP_HOST}" "!(^[^ ]*) \1" [NC]

The regex uses a space to separate SERVER_NAME and HTTP_HOST because neither variable can have spaces.

Apache expressions (version 2.4 and later)

If you actually just want to test if SERVER_NAME equals HTTP_HOST, it would be simpler to use Apache expressions:

# Case-sensitive comparison.
RewriteCond expr "%{HTTP_HOST} == %{SERVER_NAME}"

or

# Case-insensitive comparison.
RewriteCond expr "tolower(%{HTTP_HOST}) == tolower(%{SERVER_NAME})"
like image 52
mxxk Avatar answered Oct 26 '22 11:10

mxxk