Forum Moderators: phranque

Message Too Old, No Replies

mod_rewrite stumper

         

neomaven

11:02 pm on Sep 8, 2005 (gmt 0)

10+ Year Member



I have a hosting account on my server that doesn not a have a specific domain associated with it, just an IP address. I am then aliasing domains to this IP in my zone files.

I need to redirect all requests for that domain to simply http://www.example.com

including requests like:

http://anything.example.com
http://www.example.com/blahblah.html
http://example.com/blahblah.htm
http://anything.example.com/blahblah.php

basically, everything.

I tried the following in the .htaccess file for the base directory for the IP, but could not get all variations to work properly:


RewriteEngine On
RewriteCond %{HTTP_HOST} http://^(.*)?(.*$)
RewriteRule ^(.*)$ http://www.$2/ [R=301,L]

In various attempts, I was able to get http://example.com/blahblah.html to work, but nothing with a subdomain (including www), which shows that I am on the right track, but something is wrong with my reg exp.

Any suggestions or examples I could try would be appreciated.

Thanks in advance!

neomaven

[edited by: jdMorgan at 1:16 am (utc) on Sep. 9, 2005]
[edit reason] Example.com [/edit]

jdMorgan

1:06 am on Sep 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



neomaven,

Welcome to WebmasterWorld!

This will redirect requests for any domain variants of example.com, *except* for www.example.com to www.example.com, while preserving the requested resource (file, image, etc) name:


RewriteEngine on
Rewritecond %{HTTP_HOST} example\.com
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

This may or may not be what you need, but it's the closest I can guess from your description. (It's not clear if there are other domains you don't want to redirect. It's also not clear if "example" is a fixed or variable domain name.)

It is necessary to check that the request is *not* for www.example.com, because you don't want to redirect it to itself and create an 'infinite' loop.

Jim

neomaven

1:19 am on Sep 9, 2005 (gmt 0)

10+ Year Member



Jd,

Thanks for your reply!

Actually, I want to strip everything from the request (resource, extended path, folders etc.) for variable domains.

the .htaccess file will have no idea which domains will be pointing at this IP.

So I want any and every possible request for domain.com, for example:

http://example.com/anyfile.html
http://www.example.com/anyfile.html
http://www.example.com/somedir/anyfile.html
http://anysubdomain.example.com
http://anysubdomain.example.com/anypage.html
http://anysubdomain.example.com/somedir/anypage.php
etc. etc.

to redirect simply to http://www.example.com

Hopefully this makes things clearer for you?

I appreciate your help, me and my host have been wrangling with this for hours.

[edited by: jdMorgan at 1:41 am (utc) on Sep. 9, 2005]
[edit reason] example.com. Please. [/edit]

neomaven

1:24 am on Sep 9, 2005 (gmt 0)

10+ Year Member



I should clarify:

The RewriteRule should not contain reference to any specific domain name, but rather extract this info from the HTTP_HOST information.

This is because the home directory /www/domain-park/ and this .htaccess where i will put the rewrite rule, have no idea which domains are aliased to the IP.

The ip where this page is hosted has no idea which domains are pointing at it, yet is able to catch all incoming request.

Thanks,

neomaven

[edited by: jdMorgan at 1:34 am (utc) on Sep. 9, 2005]
[edit reason] No URLs, please. See TOS. [/edit]

jdMorgan

1:40 am on Sep 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Please use example.com, and only example.com in example code. Thanks.

This may work better for your requirements:


RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.[^.]+\.com
Rewritecond %{HTTP_HOST} ([^.]+)\.[^.]+$
RewriteRule .* http://www.%1.com/? [R=301,L]

Jim

[edited by: jdMorgan at 1:55 am (utc) on Sep. 9, 2005]

neomaven

1:45 am on Sep 9, 2005 (gmt 0)

10+ Year Member



JD

I apologize for the external links. I wasn't aware of the rule about that.

I put the following in my .htaccess

RewriteEngine on
RewriteCond %{HTTP_HOST}!^www\.[^.]+\.com
RewriteCond %{HTTP_HOST} ([^.]+)\.[^.]+$
RewriteRule .* [%1.com...] [R=301,L]

and now I simply get internal server errors.

Any ideas?

Thanks

jdMorgan

1:56 am on Sep 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Posting on this forum deletes some spaces required by mod_rewrite syntax. See corrected code above.

See your server error log for confirmation.

Jim

neomaven

2:19 am on Sep 9, 2005 (gmt 0)

10+ Year Member



JD,

Here is what I have now:


RewriteEngine On
RewriteCond %{HTTP_HOST}!^www\.[^.]+\.com
RewriteCond %{HTTP_HOST} ([^.]+)\.[^.]+$
RewriteRule (.*) http://www.%1.com/? [R=301,L]

Most of the requests are being redirected properly.

Two problems:

http://www.example.com/somefile.html gives a 404

Also, this only works for .com domains. Is there a way to extract the tld from the HTTP_HOST info and append that in the RewriteRule so this will work for all extensions?

Thanks very much, you are very helpful.

jdMorgan

3:44 am on Sep 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> Is there a way to extract the tld from the HTTP_HOST info and append that in the RewriteRule so this will work for all extensions?

Well, yes and no. The problem is that mod_rewrite doesn't know a domain name from a doormat. If you've got example.net, example.co.uk, www.example.net, www.example.co.uk, subdomain.example.com, and subdomain.example.co.uk (just for examples), then how is mod_rewrite to know which 'piece' is the proper domain? It could be the whole string "example.com" or it might be just the second and third part of "www.example.com" or it could be the second, third, and fourth part of "subdomain.example.co.uk".

There has to be some 'base' for mod_rewrite to use as a 'key' to find the domain. In the code above, I used ".com" at the end to locate the domain part of the hostname. You might use a text pattern like ".com" or positional elements such as "first, second, and third piece", or both, but you've got to nail it down somehow.

Exacerbating the problem is the fact that you also need to check for 'NOT the correct canonical domain' in order to prevent redirection loops as mentioned above.

And add to that the fact that mod_rewrite can't compare one variable against another, so you can't do that to prevent the redirection loop. (There is a very tricky work-around that allows the use of POSIX 1003.2 atomic back-references to 'compare' two variables, but it only works on *some* servers running certain operating systems, and of course, an OS change or upgrade could cause the code to stop working with catastrophic results.)

Therefore, it *may* be possible to make this work for a well-defined subset of al possible domains and variants, but it won't be possible to make it work for *any* domain and all of its possible variants unless those domains are separately hosted so that the redirection loop is not a concern.

Jim

neomaven

4:03 am on Sep 9, 2005 (gmt 0)

10+ Year Member



Jim,

I only need it to work for the following extensions:
.com
.net
.org
.biz
.us
.info

Would this work for the "anchoring" that you describe?


RewriteEngine on
RewriteCond %{HTTP_HOST}!^www\.[^.]+\.(com好et她rg在iz守s夷nfo)
RewriteCond %{HTTP_HOST} ([^.]+)\.[^.]+$
RewriteRule (.*) http://www.%1.com/ [R=301,L]

Also, any idea why

http://www.example.com/blahblah.htm is not being redirected properly?

I have tinkered with the code with all kinds of small change, but I end up fixing one thing and breaking another.

jdMorgan

5:12 am on Sep 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, running out of guesses here...

RewriteEngine on
# If request is NOT for "www.<domain>.com"
RewriteCond %{HTTP_HOST} !^www\.[^.]+\.com
# Extract domain from dot-delimited field preceding "com", "net", "org", etc.)
RewriteCond %{HTTP_HOST} ([^.]+)\.(com好et她rg在iz守s夷nfo)
# Redirect to home page of "www.<domain>.com", deleting any appended query strings
RewriteRule (.*) http://www.%1.com/? [R=301,L]

> Also, any idea why
> http://www.example.com/blahblah.htm is not being redirected properly?

Because we don't want to redirect requests for "www.example.com/" because that is the domain you are redirecting *to*. If you really do want to redirect all pages, images, etc. on www.example.com to www.example.com/, then you'll need to add a second (simpler) rule. But that will mean that these "sites" can have only one page or script, and no additional URL-accessible pages, images, stylesheets, scripts, etc.

Add:


RewriteRule . http://%{HTTP_HOST}/? [R=301,L]

after the ruleset above. The first ruleset 'standardizes' the domain and drops any URL-paths, while the second rule catches cases where the domain name is correct, but the URL-path is non-blank.

Again, it is necessary to very precisely define what you want to do. A single character in mod_rewrite can change the result drastically; The requirements must be defined precisely, and the code must be written precisely, in order to do precisely what you want.

Note also that this code is for use in .htaccess only, and will need tweaking if you move it to httpd.conf.

Jim

neomaven

9:22 am on Sep 9, 2005 (gmt 0)

10+ Year Member



Jim,

Thanks for your help in trying to crack this one.
I decided to look for other solutions, after wrestling with mod_rewrite for over 6 hours.

Here is what I came up with:

Change the httpd.conf entry for the directory to this:


<VirtualHost 1.2.3.4>
ServerName domainpark
ServerAlias *
ScriptAlias /cgi-bin/ /www/domainpark/cgi-bin/
DocumentRoot /www/domainpark/
#CustomLog logs/domainpark-access_log common
</VirtualHost>

Put the following in .htaccess in the root directory:


ErrorDocument 404 /404.php

And let php strip out the pure domain name with no subdomains or extended path info:

404.php


<?php
$host = $_SERVER['HTTP_HOST'];

$h = explode('.',$host);
$domain = implode('.',array_splice($h, -2, 2));

header("Location: http://$domain");

?>

This solution has any and all request being properly redirected.

Thanks again for trying to help me on this.