9

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

RewriteCond %{HTTP_HOST} ^example\.com [nc]
RewriteRule (.*) http://www.example.com/$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://example.com --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://example.com/
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.example.com/">here</a>.</p>
<hr>
<address>Apache/2.2.16 (Debian) Server at example.com 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] [example.com/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] [example.com/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] [example.com/sid#b797f948][rid#b7d2c1c8/initial] (2) [perdir /var/www/oup/81/] rewrite '' -> 'http://www.example.com/'
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [example.com/sid#b797f948][rid#b7d2c1c8/initial] (2) [perdir /var/www/oup/81/] explicitly forcing redirect with http://www.example.com/
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [example.com/sid#b797f948][rid#b7d2c1c8/initial] (1) [perdir /var/www/oup/81/] escaping http://www.example.com/ for redirect
192.168.1.221 - - [06/Jun/2011:17:49:32 +0200] [example.com/sid#b797f948][rid#b7d2c1c8/initial] (1) [perdir /var/www/oup/81/] redirect to http://www.example.com/ [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 example.com
        ServerAlias example.com www.example.com
        DocumentRoot /var/www/example/
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/example/>
                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 example.com and not www.example.com
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://www.example.com' . $_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?

15
  • 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, 2011 at 1:22
  • I didn't compile apache myself and thete's no other server in between.
    – cypher
    Jun 15, 2011 at 11:22
  • probably your NS server is not configured properly
    – venimus
    Jun 16, 2011 at 10:52
  • 4
    It isn't necessary to repeat the server name in the ServerAlias entry.
    – chris
    Jul 28, 2011 at 1:48
  • can you put all content of file here
    – undone
    Aug 20, 2011 at 0:52

11 Answers 11

2

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 (...)
4
  • I haven't found anything like this.
    – cypher
    Aug 26, 2011 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, 2011 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, 2011 at 18:32
  • @Jakob Egger - I haven't found ProxyPassReverse directive anywhere.
    – cypher
    Aug 29, 2011 at 13:46
1

Can you try this alternative mod_rewrite code:

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
14
  • This failed exactly the same way.
    – cypher
    Jun 6, 2011 at 15:28
  • can you enable RewriteLog and see what it spits out.
    – anubhava
    Jun 6, 2011 at 15:31
  • And how exactly can I do that? :-)
    – cypher
    Jun 6, 2011 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, 2011 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, 2011 at 16:20
1

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.

6
  • 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, 2011 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, 2011 at 16:23
  • No, it is NOT in production.
    – cypher
    Jun 6, 2011 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, 2011 at 16:33
  • Oh, damned, what I meant to write was that tis IS in production, dunno how this happenned :-)
    – cypher
    Jun 6, 2011 at 16:40
0

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

1
  • And yet it isn't :-) (tried already, didn't work)
    – cypher
    Jun 10, 2011 at 14:15
0

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.

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

Try:

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

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>
3
  • I've updated the question with definition of the VirtualHost.
    – cypher
    Jun 16, 2011 at 12:39
  • Did you give the above multiple VirtualHost solution a try, or are you set on using mod_rewrite?
    – chris
    Jul 28, 2011 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, 2011 at 7:48
0

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.

1
  • Nope, nothing in hosts about that domain.
    – cypher
    Aug 24, 2011 at 21:34
0

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!

1
  • 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, 2011 at 23:01
0

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

hexdump -C .htaccess
0

I believe you are missing a $ sign after your rewrite condition. Please try:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .