Forum Moderators: phranque

Message Too Old, No Replies

redirect to subdomain from folder(urlpath) - can't find answer

mod rewrite apache

         

tropicallea1

3:18 am on Feb 28, 2009 (gmt 0)

10+ Year Member



I have a urlpath that I want to redirect to a subdomain using mod_rewrite.

The mod rewrite should do the work:
www.example.com/xyz -> xyz.example.com

I don't want to send a redirect to the browser(so it doesn't know the page is different).

Another example, just to clarify.

If http://www.example.com/xyz/urlpath is entered into the browser, Apache returns the contents of http://xyz.example.com/urlpath

I'm not familiar with mod rewrite.
Hope someone can help.

[edited by: Robert_Charlton at 4:03 am (utc) on Feb. 28, 2009]
[edit reason] changed to example.com - it can never be owned [/edit]

tropicallea1

4:39 am on Feb 28, 2009 (gmt 0)

10+ Year Member



The question sounds maybe simple, but I search the forum and can't find the answer. All people are inquiring(regarding subdomains) about redirecting FROM subdomain to folder/urlpath

g1smd

7:56 pm on Feb 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



*** I want to redirect to a subdomain using mod_rewrite. ***

*** I don't want to send a redirect to the browser. ***

You'll need a

rewrite
using a
RewriteRule
then. It uses very similar syntax to a redirect; but for a rewrite the target should not contain a domain name.

Use [L] at the end of the rule. Post your best effort code here with details of what problems you are having.

tropicallea1

6:49 am on Mar 1, 2009 (gmt 0)

10+ Year Member



I wrote the following rewriting rule in root .htaccess which is working "almost" fine.

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^bookings/(.*) http://bookings.example.com/$1

The problem is that after entering in the address bar:
http://www.example.com/bookings/phpquery
I get in the browser the content of:
http://booking.example.com/phpquery, so it's ok,
BUT (!)
the address bar changed at the same moment and is also displaying: http://booking.example.com/phpquery

should I use [P] flag?

I should have mentioned that bookings is a CNAME which points to another domain which i'm affiliated with. So i'm pulling the content from provider website, which is prepared for me with my logo etc.

I could stay with the solution bookings.example.com, but I will have also other CNAMEs, so solution www.example.com/<various CNAMEs>/ is better for SEO and customers

[edited by: jdMorgan at 4:22 pm (utc) on Mar. 3, 2009]
[edit reason] de-linked [/edit]

g1smd

6:26 pm on Mar 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I already gave the answer immediately above. :-)

*** ...for a rewrite the target should not contain a domain name. ***

*** Use [L] at the end of the rule ***

By ignoring that, you have created a 302 redirect instead of an internal rewrite.

tropicallea1

2:22 am on Mar 2, 2009 (gmt 0)

10+ Year Member



Hi g1smd,
thanks for replying as it's only you,

I thought the following should work:

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^www\.(.*)/bookings/(.*)$ bookings\.$1/$2 [L]

but unfortunately it doesn't.

Any your help would me much appreciated

g1smd

10:30 am on Mar 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



RewriteRule
cannot 'see' the domain name (nor parameters).

You need to test

HTTP_HOST
with a
RewriteCond
for that.

jdMorgan

2:56 pm on Mar 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is the whole "package" needed to implement subdomain to subdirectory rewrites. All three steps are required for this to work properly.

The first rule externally redirects to canonicalize all hostnames to either www.example.com, or to xyz.example.com, no matter what variations of the hostname are requested. This simplifies the following rules, as well as others which you may wish to add, and prevents duplicate-content problems.

Examples of non-canonical hostnames redirected by this rule are

example.com --301--> www.example.com
www.example.com. --301--> www.example.com
www.example.com:80 --301--> www.example.com
www.example.com.:80 --301--> www.example.com
www.xyz.example.com --301--> xyz.example.com
xyz.www.example.com --301--> xyz.example.com
www.xyz.www.example.com --301--> xyz.example.com
etc.

The second rule externally redirects all direct client requests for the subdomain-subdirectories back to the subdomain, so that clients requesting www.example.com/xyz/<something> will be redirected to xyz.example.com/<something>. Again, this is to avoid duplicate content, and also to prevent "fishing" in your directory structure by possibly-unfriendly prying eyes. This redirect can only be done based on direct client requests, otherwise, it would interact with the third rule creating an 'infinite' redirect/rewrite loop.

The third rule internally rewrites all subdomain requests except for "www" to a subdirectory whose name is "sd_" plus the subdomain name. The "sd_" is an arbitrary "tag" needed to identify subdomain subdirectories to prevent recursion and also so that you can still have "real" subdirectories not associated with a subdomain. So you can change "sd_" to any unique string you like, as long as it does not match *any* other subdirectory name.

You will need to rename all of your subdomain-subdirectories so that they start with "sd_" in order for any of this to work. There are other ways to do it, but all are far more painful. I suggest that you test and get this working as-is, then make changes if you feel you need to.


# Canonicalize all requested hostnames
RewriteCond www>%{HTTP_HOST} ^(www)>example\.com [OR]
RewriteCond %{HTTP_HOST} ^(www)\.example\.com\. [OR]
RewriteCond %{HTTP_HOST} ^(www)\.example\.com:[0-9] [OR]
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.(www\.)?example\.com [OR]
RewriteCond %{HTTP_HOST} ^([^.]+)\.www\.example\.com
RewriteRule (.*) http://%1.example.com/$1 [R=301,L]
#
# Externally redirect direct client requests for www.example.com/sd_xyz to xyz.example.com
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /sd_[^/]+/
RewriteRule ^sd_([^/]+)/(.*)$ http://$1.example.com/$2 [R=301,L]
#
# Internally rewrite xyz.example.com to filepath example.com/sd_xyz, except for "www.example.com"
RewriteCond $1 !^sd_
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteRule (.*) /sd_%1/$1 [L]

I just banged this out -- Hopefully there are no typos... :)

Jim

[edit] Correction to last RewriteCond in first rule as noted below. [/edit]

[edited by: jdMorgan at 4:33 pm (utc) on Mar. 3, 2009]

tropicallea1

3:50 pm on Mar 2, 2009 (gmt 0)

10+ Year Member



Hi Jim,

Thanks a lot for reply and the effort you put into it.
I tried it and unfortunately it returns error 404.
I tried also only the third part and the effect is the same.
You wrote in a comment to 3rd rule that
# Internally rewrite xyz.example.com to filepath example.com/sd_xyz, except for "www.example.com"

I'm not sure if this is right.
I want the opposite.
When customer browser requests for:
www.example.com/bookings/phpquery
(or www.example.com/sd_bookings/phpquery)
the apache should give him the content of:
bookings.example.com/phpquery

In fact my folder bookings doesn't really exist, because it's just for search engines robots, to avoid multiple subdomains.

Best Regards,
Nick

littlespy

7:05 pm on Mar 2, 2009 (gmt 0)

10+ Year Member



Hey Jim I have a question for you. I'm trying to use your script you just posted as i need test.example.com to point to example.com/sd_test. I've tried to use script but it doesnt seem to be working for me. I have an 2 A records pointing to *.example.com and example.com and a static ip address of course. Are there any other options I need to do as well? I don't get any 500 or 404 error just every subdomain #*$!.example.co.uk just points to the main one and not example.co.uk/sd_#*$! This is what is in my sites-available script for the site.

ServerAlias www.example.co.uk *.example.co.uk

DocumentRoot /var/www/example.co.uk/public
DirectoryIndex index.html index.php

<Directory /var/www/example.co.uk/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>

And this is the script I was trying to use:

# Canonicalize all requested hostnames
RewriteCond www>%{HTTP_HOST} ^(www)>example\.co\.uk [OR]
RewriteCond %{HTTP_HOST} ^(www)\.example\.co\.uk\. [OR]
RewriteCond %{HTTP_HOST} ^(www)\.example\.co\.uk:[0-9] [OR]
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.(www\.)?example\.co\.uk [OR]
RewriteCond %{HTTP_HOST} ^([^.]+)\.(www\.)?example\.co\.uk
RewriteRule (.*) [%1.example.co.uk...] [R=301,L]
#
# Externally redirect direct client requests for www.example.com/sd_xyz to xyz.example.com
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /sd_[^/]+/
RewriteRule ^sd_([^/]+)/(.*)$ [$1.example.co.uk...] [R=301,L]
#
# Internally rewrite xyz.example.com to filepath example.com/sd_xyz, except for "www.example.com"
RewriteCond $1 !^sd_
RewriteCond %{HTTP_HOST} !^www\.example\.co\.uk
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.co\.uk
RewriteRule (.*) /sd_%1/$1 [L]

I'm pretty stumped here, any suggestions would be MORE than welcome. Thanks guys.

littlespy

2:51 am on Mar 3, 2009 (gmt 0)

10+ Year Member



hmm I've realized I needed to add RewriteEngine On to the top of my .htaccess file, but now this script is giving me an infinite redirect loop. Anyone know what's up?

tropicallea1

3:32 am on Mar 3, 2009 (gmt 0)

10+ Year Member



Hi littlespy

Well... after reading your post i realized that i forgot to add
Options +FollowSymLinks
RewriteEngine On
too... :-)

So now it gives me the same message
"This webpage has a redirect loop."

littlespy

4:01 am on Mar 3, 2009 (gmt 0)

10+ Year Member



i commented out the first rewrite rule and it works decently now only problem is obviously that

www.test.example.com goes to www.example.com

so there has to be something in the first rule that causing an infinite loop

i also found something interesting has anyone ever read about this before?

www.merhar.si/hosting/mapping-subdomains-to-subdirectories-with-apache-the-easy-way

[edited by: jdMorgan at 4:25 pm (utc) on Mar. 3, 2009]
[edit reason] De-linked. [/edit]

jdMorgan

4:31 pm on Mar 3, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The last RewriteCond in the first rule I posted has a typo (I did warn you!)

RewriteCond %{HTTP_HOST} ^([^.]+)\.(www\.)?example\.com

- should be:
 RewriteCond %{HTTP_HOST} ^([^.]+)\.www\.example\.com

I will also correct this in my post above, so that future readers don't encounter the same looping problem.

Jim

jdMorgan

7:53 pm on Mar 3, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



tropicallea1,

Sorry, I got distracted by the other subject in this thread.

For what you want to do, only the second rule I posted is needed. Modify the "sd_" string and patterns to suit.

Jim