Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to redirect an url without www. to www.version (domain.cz to www.domain.cz). I use the usual

RewriteCond %{HTTP_HOST} ^domain\.cz [nc]
RewriteRule (.*) http://www.domain.cz/$1 [R=301,L]

This works on all my other projects. However on this particular site, it ends with a redirect loop. Here's the weird part: I tried to curl the non-www version to see what headers it sends using curl --get http://domain.cz --dump-header domain.header > domain.html. The header file looked like this:

HTTP/1.1 301 Moved Permanently
Date: Mon, 06 Jun 2011 14:45:16 GMT
Server: Apache/2.2.16 (Debian)
Location: http://domain.cz/
Vary: Accept-Encoding
Content-Length: 310
Content-Type: text/html; charset=iso-8859-1

However, the resulting HTML file was this:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.domain.cz/">here</a>.</p>
<hr>
<address>Apache/2.2.16 (Debian) Server at domain.cz Port 80</address>
</body></html>

(note the address difference between the files) Does anybody know how to fix this (and what the hell is causing it)? Any other url rewriting directives work fine.

EDIT: rewrite log contained this: (the site is accessed by a lot of people so the rewrite log got quite long, I'm not 100% sure if this is the right part)

192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (3) [perdir /var/www/oup/81/] strip per-dir prefix: /var/www/oup/81/ ->
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (3) [perdir /var/www/oup/81/] applying pattern '(.*)' to uri ''
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (2) [perdir /var/www/oup/81/] rewrite '' -> 'http://www.domain.cz/'
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (2) [perdir /var/www/oup/81/] explicitly forcing redirect with http://www.domain.cz/
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (1) [perdir /var/www/oup/81/] escaping http://www.domain.cz/ for redirect
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [domain.cz/sid#b797f948][rid#b7d2c1c8/initial] (1) [perdir /var/www/oup/81/] redirect to http://www.domain.cz/ [REDIRECT/301]

The access log line (probably the right one):

192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] "GET / HTTP/1.1" 301 555 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Safari/534.24"

The definition of the virtualhost:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName domain.cz
        ServerAlias domain.cz www.domain.cz
        DocumentRoot /var/www/domain/
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/domain/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride All
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

EDIT2: okay, I just figured out that if I do this (resigned and attempted to redirect this without .htaccess):

//if clause determining that we're running on domain.cz and not www.domain.cz
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://www.domain.cz' . $_SERVER['REQUEST_URI']);
header('Connection: close');

It causes EXACTLY THE SAME redirect loop. Seriously, what the hell? Does anyone have an idea what might possibly be causing this?

share|improve this question
    
Did you compile Apache yourself, or? It should be impossible for the Location header to differ from what's in the page since they're taken from the same variable in this case, so that's pretty odd. I assume that the requests are passed directly to Apache, right, there's no other server sitting inbetween? –  Tim Stone Jun 15 '11 at 1:22
    
I didn't compile apache myself and thete's no other server in between. –  cypher Jun 15 '11 at 11:22
    
probably your NS server is not configured properly –  venimus Jun 16 '11 at 10:52
4  
It isn't necessary to repeat the server name in the ServerAlias entry. –  chris Jul 28 '11 at 1:48
    
can you put all content of file here –  undone Aug 20 '11 at 0:52
show 8 more comments

migrated from stackoverflow.com Aug 28 '11 at 20:28

This question came from our site for professional and enthusiast programmers.

10 Answers

What strikes me as odd is the Location: http://domain.cz/ header line reported by CURL. You never redirect to that domain. The redirect log also doesn't contain any mention of it.

Somehow the Location header seems to be altered after modrewrite does its stuff, and since you tried changing the header with PHP as well, the Location header is apparently changed after the request is processed. The only explanation I can think of is that you are modifying the location header with mod_header somewhere.

Did you check all configuration files (httpd.conf, the included .conf files, and the .htaccess file) if you somewhere find a line similar to this:

Header set Location (...)

or

Header edit Location (...)
share|improve this answer
    
I haven't found anything like this. –  cypher Aug 26 '11 at 11:51
2  
Are you directly connecting to Apache, or is there some caching or proxy server inbetween that might change headers? The ProxyPassReverse directive might also change the location header (httpd.apache.org/docs/2.0/mod/mod_proxy.html#ProxyPassReverse). –  Jakob Egger Aug 28 '11 at 8:01
    
there might be some proxy inbetween, I'll have a look into it as soon as I get to work tomorrow. –  cypher Aug 28 '11 at 18:32
    
@Jakob Egger - I haven't found ProxyPassReverse directive anywhere. –  cypher Aug 29 '11 at 13:46
add comment

In addition to enabling rewritelog (if you have access to change the httpd.conf) you should remove the application that lives on this site from the equation. Remove/rename temporarily the default index.php (or whatever index page is serving your app) to be sure it's not causing this.

There are many reports of applications (e.g. wordpress) causing these apache default redirect page to appear if they are misconfigured.

Also, check the rest of the apache config to see if there are any other 'redirect' instructions that might be conflicting.

share|improve this answer
    
The application is alright, I tried it on a different server and different domain (copied the whole app) and it worked alright. I guess it's something in apache configuration, but I can't figure out what. –  cypher Jun 6 '11 at 16:15
    
The app may be ok, but may be also conflicting with the setup on this server. It sounds like your app is currently in production so I can see how 'disabling it' isn't ideal. For fun, you might add a query string to the end of the redirection as a flag to aid discovery - so /$1?nowww=1 or something similar. –  Gavin C Jun 6 '11 at 16:23
    
No, it is NOT in production. –  cypher Jun 6 '11 at 16:30
    
Oh cool, then can't hurt to move the index file out of the way to 100% exclude it as part of the problem :) –  Gavin C Jun 6 '11 at 16:33
    
Oh, damned, what I meant to write was that tis IS in production, dunno how this happenned :-) –  cypher Jun 6 '11 at 16:40
show 1 more comment

Can you try this alternative mod_rewrite code:

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
share|improve this answer
    
This failed exactly the same way. –  cypher Jun 6 '11 at 15:28
    
can you enable RewriteLog and see what it spits out. –  anubhava Jun 6 '11 at 15:31
    
And how exactly can I do that? :-) –  cypher Jun 6 '11 at 15:35
    
Please see here: httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritelog Only thing is that this directive goes into apache config NOT in .htaccess. –  anubhava Jun 6 '11 at 15:38
1  
I copied same rule (as my answer above) to my Apache installation and ran the same curl command you have in your question and got Location: http://www.domain.com/ as part of my headers so in my case headers and html both are showing same domain i.e. www.domain.com. Can you also paste you relevant access.log lines in your question above? –  anubhava Jun 6 '11 at 16:20
show 9 more comments

could you try to use [NC] instead of [nc], might be so simple

share|improve this answer
    
And yet it isn't :-) (tried already, didn't work) –  cypher Jun 10 '11 at 14:15
add comment

I hope you have server access, Added the redirect line after site document folder specified followed

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.cz [NC]
RewriteRule ^/(.*) http://www.domain.cz/$1 [L,R=301]

If you dont have access for server, add those line on httaccess starting / change the portion.

May be you havent add "RewriteEngine on" before the redirection.

share|improve this answer
    
I have added RewriteEngine on, as I said, it works on another server properly, just not on this one. –  cypher Jun 15 '11 at 11:23
    
AllowOverride All allow from all add those lines in your server config file –  Thilak Jun 15 '11 at 12:51
add comment

Try:

RewriteCond %{HTTP_HOST} ^domain.cz [NC]
RewriteRule (.*) http://www.domain.cz/$1 [R=301,L]
share|improve this answer
add comment

Be sure to have Options +FollowSymLinks if you are working within a directory context.

Otherwise if you are using name based virtual hosts, try:

<VirtualHost *:80>
  ServerName domain.cz
  Redirect / http://www.domain.cz/
</VirtualHost>

<VirtualHost *:80>
  ServerName www.domain.cz
  # whatever else
</VirtualHost>
share|improve this answer
    
I've updated the question with definition of the VirtualHost. –  cypher Jun 16 '11 at 12:39
    
Did you give the above multiple VirtualHost solution a try, or are you set on using mod_rewrite? –  chris Jul 28 '11 at 1:49
    
At firts, I didn't want to use multiple VirtualHosts, but given the circumstances I tried it anyway and it didn't help. –  cypher Aug 22 '11 at 7:48
add comment

After reading all the answers you could check de /etc/hosts file... maybe all your checks are from your computer. Try to access from a different location.

share|improve this answer
    
Nope, nothing in hosts about that domain. –  cypher Aug 24 '11 at 21:34
add comment

I have a second idea. The server log you posted shows an adress of "192.168.1.221", which is an adress from the local network. Do all log entries show the same IP adress? If this is the case, there is a proxy between you and the server. This proxy probably uses ProxyPassReverse or Header edit to change the Location header.

This is a usual setup to circumvent the problem when the backend server puts its own hostname into the Location header, rather than the hostname of the external proxy server.

If there really is a proxy server, you will have to change the configuration of the proxy server rather than the configuration of the backend server, as the proxy will always overwrite the information.

This means that all the time we have been looking at the wrong server: The problem is with the proxy server!

share|improve this answer
    
Tomorrow I'm calling tech support of the company that runs this server. I think that must be it, I'll let you know. –  cypher Aug 30 '11 at 23:01
add comment

Could be unprintable chars like null in the .htaccess file.

hexdump -C .htaccess
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.