apachemod-rewrite

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.example [L,R=301]

If I change the RewriteCond to:

RewriteCond %{HTTP_HOST} ^(.*\.)?mydomain\.example/(?!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.example without a trailing slash will not be redirected.

What am I doing wrong?

Here are the rules:

<VirtualHost *:80>
    ServerAdmin me@mydomain.example
    DocumentRoot "/var/www/mydomain.example/htdocs"
    ServerName www.mydomain.example
    ServerAlias mydomain.example

    RewriteEngine on
    RewriteCond {REQUEST_URI} !^/audio
    RewriteRule ^(.*)$ http://www.newdomain.example [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.example/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.example/'
(2) explicitly forcing redirect with http://www.newdomain.example
(1) escaping http://www.newdomain.example for redirect
(1) redirect to http://www.newdomain.example [REDIRECT/301]

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


Solution

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

    Using REQUEST_URI should be all you need:

    RewriteCond %{REQUEST_URI} !^/audio
    

    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