Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mod_rewrite rule to redirect all requests except for one specific path

I'm trying to redirect all requests to my domain to another domain using mod_rewrite in an Apache 2.2 VirtualHost declaration. There is one exception to this -- I'd like all requests to the /audio path not to be redirected.

I've written a RewriteCond and RewriteRule to do this but it's not quite right and I can't figure out why. The regular expression contains a negative lookahead for the string "/audio", but for some reason this isn't matching. Here's the definition:

RewriteEngine on RewriteCond %{HTTP_HOST} ^(.*\.)?mydomain\.net(?!/audio) [NC] RewriteRule ^(.*)$ http://www.newdomain.net [L,R=301] 

If I change the RewriteCond to:

RewriteCond %{HTTP_HOST} ^(.*\.)?mydomain\.net/(?!audio) [NC] 

(i.e. put the forward slash outside of the negative lookahead part) then it works, but the downside of this is that requests to mydomain.net without a trailing slash will not be redirected.

Can anyone point out what I'm doing wrong?

(Note: the angle brackets around the domain in the RewriteRule bit above are being added by StackOverflow.com -- they are not there in the actual code!)


Here are the rules:

<VirtualHost *:80> ServerAdmin [email protected] DocumentRoot "/var/www/mydomain.net/htdocs" ServerName www.mydomain.net ServerAlias mydomain.net  RewriteEngine on RewriteCond {REQUEST_URI} !^/audio RewriteRule ^(.*)$ http://www.newdomain.net [L,R=301] RewriteLog logs/mod_rewrite_log RewriteLogLevel 3  ErrorLog logs/error_log CustomLog logs/access_log common </VirtualHost> 

Thanks @mercutio -- that makes perfect sense but it still doesn't seem to work.

Here's what the mod_rewrite log says when I make a request to http://mydomain.net/audio/something.mp3:

(2) init rewrite engine with requested uri /audio/something.mp3 (3) applying pattern '^(.*)$' to uri '/audio' (2) rewrite '/audio' -> 'http://www.newdomain.net/' (2) explicitly forcing redirect with http://www.newdomain.net (1) escaping http://www.newdomain.net for redirect (1) redirect to http://www.newdomain.net [REDIRECT/301] 

Since the REQUEST_URI does start with /audio I would expect the RewriteRule to be ignored.

like image 830
Olly Avatar asked Aug 21 '08 08:08

Olly


People also ask

What is the difference between rewrite and redirect?

Simply put, a redirect is a client-side request to have the web browser go to another URL. This means that the URL that you see in the browser will update to the new URL. A rewrite is a server-side rewrite of the URL before it's fully processed by IIS.

What is $1 in Apache rewrite rule?

$1 represents the match from the first set of parentheses in the RewriteRule regex, not in the RewriteCond regex.

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 Http_host in htaccess?

The condition ( RewriteCond directive) will never be successful (because the Host header never contains a slash), so the redirect will never occur. As mentioned above, the HTTP_HOST server variable contains the hostname only, eg. example.com or www.example.com .


1 Answers

The HTTP_HOST only contains the host name, not the path of the URL requested.

RewriteCond %{REQUEST_URI} !^/audio 

Should be all you need.

Further, you can get debug info from the rewrite engine with the following, which is really useful to see how your conditions and rules are being matched:

RewriteLog /path/to/log/file RewriteLogLevel 3 
like image 133
mercutio Avatar answered Sep 17 '22 12:09

mercutio