Forum Moderators: phranque

Message Too Old, No Replies

Problem with Browser changing URL

.htaccess rewrite help

         

HungDry

6:23 am on Jan 4, 2009 (gmt 0)

10+ Year Member



All I want to do is make it so that when users type in blah.example.com, it stays at blah.example.com, and it should link to http://example.com/subdomain/blah. Although, currently when users type in blah.example.com, it changes the URL in the browsers window to http://example.com/subdomains/blah, this can't happen, needs to stay at blah.example.com. There's gotta be a way to do this within the .htaccess file?

I currently have my .htaccess looking like this:


RewriteEngine on

RewriteCond %{HTTP_HOST} ^blah.example.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.blah.example.com$
RewriteRule ^(.*)$ "http\:\/\/example\.com\/subdomains\/blah\/" [R=301,L]

Can someone please help me to get this right? It's linking to http://example.com/subdomains/blah correctly, however, it's not changing, and/or keeping the URL in the browser to blah.example.com... I'm very new to .htaccess editing, and all of the darn tutorials I see online for this are not very helpful, they talk about numbers being added to it, and so on and on. Do I need a REQUEST_URI in here somewhere? If so, where and how.

Thanks!

[edited by: tedster at 8:46 am (utc) on Jan. 4, 2009]
[edit reason] switch to example.com - it can never be owned [/edit]

phranque

8:12 am on Jan 4, 2009 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



it looks like it's doing exactly what it's written for.
you must add a ! in front of the patterns if you want the rewrite for the negative condition.

i would question why you want to serve the same content to multiple domains.
the way you intend to set it up, you will get the same content for example.com, blah.example.com and www.blah.example.com which a fundamental problem.

Caterham

3:05 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



it changes the URL in the browsers window to

You specified that with the R flag.

If you're looking for reverse proxying, use the P flag.
Note: without setting ProxyPassReverse in your httpd.conf, redirects issued by the backend server are broken. Also, you'll need to specify the path in the substitution. I assume there's no way to setup bla.example.com to point to example.com (i.e. you can avoid a reverse proxy)?


RewriteCond %{HTTP_HOST} ^(www\.)?blah\.example\.com
RewriteRule ^(.*)$ "http://example.com/subdomains/blah/$1" [R=301,L]

jdMorgan

4:11 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



1) Fix non-canonical hostname requests to prevent duplicate content
2) Fix inherent .htaccess recursion problem

# Externally redirect to canonical non-www hostnames
RewriteCond %{HTTP_HOST} ^www\.(([^.]+\.)*)example\.com
RewriteRule (.*) http://%1example.com/$1 [R=301,L]
#
# Internally rewrite "blah" hostname requests to
# /subdomains subdirectory if not already done
RewriteCond %{HTTP_HOST} ^blah\.example\.com
RewriteCond $1 !^subdomains/
RewriteRule (.*) /subdomains/blah/$1 [L]

Jim

g1smd

4:57 pm on Jan 4, 2009 (gmt 0)

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



The problem was that the OP original code was externally redirecting one URL to a new URL.

The solution (directly above) is to rewrite requests for the wanted URL to the real internal server location.

That's the difference between a redirect and a rewrite.

HungDry

5:07 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



I have tried jdMorgan's code but it's not working, getting Error Page..., so then I tried Caterham's, and his seems to be working if I use the P Flag like this:

RewriteCond %{HTTP_HOST} ^(www\.)?blah\.example\.com
RewriteRule ^(.*)$ "http://example.com/subdomains/blah/$1" [R=301,P,L]

But I'm not sure that this is the best approach, although all seems to be working fine.

Can't understand why jdMorgan's code was giving me an error...perhaps if I just put the real names of the subdomain, etc. I can understand better...

Here's what I have as of now...


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

Ok, so if you go to acs.graphicsmayhem.com it will stay at acs.graphicsmayhem.com and not change to graphicsmayhem.com/subdomains/acs, how can I use jdMorgan's example above to accomplish this?

[edited by: HungDry at 5:10 pm (utc) on Jan. 4, 2009]

[edited by: jdMorgan at 5:14 pm (utc) on Jan. 4, 2009]
[edit reason] example.com [/edit]

g1smd

5:10 pm on Jan 4, 2009 (gmt 0)

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



I can't see an error in jdMorgan's code. It should work fine.

Did you flush your cache first?

You absolutely do not want a 301 redirect here. You need a rewrite.

jdMorgan

5:16 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rather than trying to "guess" at this, please test with the code exactly as I posted it, changing only the subdirectory and domain names, leaving all of the other characters as shown, and flushing your browser cache after uploading the new code.

Then post the relevant contents of your server error log if you get a 500 error.

Jim

HungDry

5:33 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



Here is the error I am getting:

Not Found
The requested URL /subdomains/acs/ was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

--------------------------------------------------------------------------------

Apache/1.3.41 Server at acs.example.com Port 80

here is the exact code I am using:

RewriteEngine on

# Externally redirect to canonical non-www hostnames
RewriteCond %{HTTP_HOST} ^www\.(([^.]+\.)*)example\.com
RewriteRule (.*) http://%1example.com/$1 [R=301,L]
#
# Internally rewrite "blah" hostname requests to
# /subdomains subdirectory if not already done
RewriteCond %{HTTP_HOST} ^acs\.example\.com
RewriteCond $1 !^subdomains/
RewriteRule (.*) /subdomains/acs/$1 [L]

[edited by: jdMorgan at 5:50 pm (utc) on Jan. 4, 2009]
[edit reason] Please do not post your domain. See Terms of Service. [/edit]

HungDry

5:43 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



perhaps you are not understanding what I am trying to do. http://example.com/subdomains/acs is what I have as it is. I want [acs.example.com...] to link directly to http://example.com/subdomains/acs directory and keep the url in the browser to [acs.example.com....]

[edited by: jdMorgan at 5:52 pm (utc) on Jan. 4, 2009]
[edit reason] Do not post your domain. See Terms of Service. [/edit]

jdMorgan

5:49 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I understand perfectly-well, as this question comes up 100 times a year or so...

What you want is to link to the URL http://acs.example.com/ on your pages, and have the content served from the server filepath /subdomains/acs directory when that link is clicked and that URL is requested by the HTTP client.

A URL is not a filepath, or vice-versa; The URL is defined on your Web pages, while the filepath is defined by your server directory structure. The main function of a server is to transparently map HTTP-requested URLs to server filepaths, and mod_rewrite simply allows doing so in an indirect, non-default way (in addition to the several other functions that it supports).

Your requirements call for an internal rewrite, not an external redirect (which by definition sends a new URL to the browser which effectively causes the browser to update its address bar).

In addition, the hostname canonicalization redirect I posted is needed to prevent duplicate-content problems and to simplify the internal rewrite code.

The code I posted works on thousands of servers, so the problem is no longer in code design, but in implementation or in server configuration.

Please post the relevant contents of your server error log, as requested above. Progress will be limited without the information it contains.

Please do not post your domain name, as I will have to edit it out every time (as above) to comport with our Terms of Service. You may also find this thread out-ranking your own site for searches on the domain name if I do not do so.

Jim

[edited by: jdMorgan at 6:08 pm (utc) on Jan. 4, 2009]

HungDry

6:44 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



Ok, thanks, will not post the domain name, sorry. My error log only contains errors dated back to Dec. 22, 2008. No errors in there after that.

HungDry

6:48 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



for some reason, it is trying to get the info from:

acs.example.com/subdomains/acs/

when it should be trying to get it from:

example.com/subdomains/acs/

so i am getting an error saying:
The requested URL /subdomains/acs/ was not found on this server. And I believe it's looking for it in acs.example.com

so I think I just need to fix the path where it's loading from,
which probably just needs to be changed somewhere in the .htaccess file from acs.example.com to example.com. Does that sound about right to you?

[edited by: HungDry at 6:57 pm (utc) on Jan. 4, 2009]

jdMorgan

7:20 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Understand that "domain names" do not exist once the request is translated into the filespace of your server.

If the acs subdomain is hosted in the same filespace as the main domain, then you can rewrite to that filespace.

If the acs subdomain is hosted in a separate filespace with its own DocumentRoot declared, then what you want won't be possible to do, or to do efficiently, because in order to reach a different virtual server, a redirect or a proxy through-put will be needed. If you redirect, then the browser will update its address bar. If you do a proxy, then all traffic for "acs" will pass through the main server -going and coming- and will be logged. In addition, the 'acs' server will see all requests as coming from the main server and not the originating client, unless you configure the main server to send the x-forwarded-for header, and configure the acs server to log that header instead of the remote_host header.

How did you create and/or define the 'acs' subdomain -- WHat tool or method did you use?

Jim

HungDry

8:33 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



Was created using the CPanel provided by the ISP.

jdMorgan

9:41 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In that case, the acs subdomain will have it's own filespace, and requests for that filespace will be sent directly there, bypassing the .htaccess file in the main domain's filespace. Because of this, there should be no need to use .htaccess to accomplish this mapping.

If you don't like the way the control panel does this, then you'll need to change from a name-based virtual hosting account to an IP-based virtual hosting account, so that you can map IP addresses (and therefore domains) to any filespace you choose.

Alternatively, if you host allows directly-editing the httpd.conf file (not likely with a shared host), you could set the DocuemntRoot of the cvs subdomain to be the same as that for the main domain, and thereby guarantee that your main domain's .htaccess code would be run for cvs subdomain requests.

Jim

HungDry

10:50 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



ok, but what's wrong with Catterhams approach, seems to work for me, just added the P Flag:

RewriteCond %{HTTP_HOST} ^(www\.)?blah\.example\.com
RewriteRule ^(.*)$ "http://example.com/subdomains/blah/$1" [R=301,P,L]

g1smd

11:18 pm on Jan 4, 2009 (gmt 0)

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



By using a proxy you increase the load on the server and you cannot trace where your visitors have come from.

If you do a proxy, then all traffic for "acs" will pass through the main server -going and coming- and will be logged. This will massively clutter the stats for that domain. In addition, the 'acs' server will see all requests as coming from the main server and not the originating client, unless you configure the main server to send the x-forwarded-for header, and configure the acs server to log that header instead of the remote_host header.

This is a lot of extra work, and can be completely avoided by doing things the other way. That other way is much more clean, more efficient, and a whole lot better.

jdMorgan

12:56 am on Jan 5, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So in other words, there's nothing "wrong" with Caterham's proxy approach. You just need to appreciate what it means to your server load, your log files, and your 'stats' and traffic analysis results. Only you (or your organization) can decide if any of this is important or not, once the issues are well-understood.

Jim

amacieli

7:27 am on Jan 17, 2009 (gmt 0)

10+ Year Member



Sorry to be number 101 asking the same question...
rewrite X.domain.com to be file path domain.com/X
tried settling for X.domain.com --> domain.com/cms/X by trying the following code:

RewriteEngine On
# Externally redirect to canonical non-www hostnames
RewriteCond %{HTTP_HOST} ^www\.(([^.]+\.)*)domain\.net
RewriteRule (.*) [%1domain.net...] [R=301,L]
#
# Internally rewrite "blah" hostname requests to
# /subdomains subdirectory if not already done
RewriteCond %{HTTP_HOST} ^adam\.domain\.net
RewriteCond $1 !^cms/
RewriteRule (.*) /cms/adam/$1 [L]

I was expecting that to rewrite adam.domain.net into domain.net/cms/adam, thus executing the software installed in that folder.

Made sure I did a "hard refresh" in the browser - control+reload.

Get 500 error, here it is:

[Sat Jan 17 00:08:23 2009] [error] [client 68.38.xx.xx] Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

Using Bluehost, originally used cpanel to set up subdomain - with redirection, then without redirection.

Deleting the subdomain in cpanel altogether leaves X.domain.net in the address bar of the browser, but the software in domain.net/cms/X is not run (the page that appears if you go to domain.net appears instead). No server errors in this scenario.

Any ideas?

Also, is it possible to wildcard the subdomains, so that literally whatever subdomain I enter is rewritten to the appropriate subfolder? Would prefer not to hard code the mappings.

Really sorry to ask, but have been googling for hours and doing tons of experimentation. Just get to a point where no hair is left... :(

[edited by: eelixduppy at 5:14 pm (utc) on Jan. 18, 2009]
[edit reason] obfuscated IP [/edit]

g1smd

10:27 am on Jan 17, 2009 (gmt 0)

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



You appear have a problem where the rewritten filepath is then matched again by the rule and rewritten again, and that new filepath matches the rule and is rewritten again.... forever in an infinite loop.

Careful inspection of the input URL, the wanted filepath, and the rules might point to a modification you can do to the rule to prevent that happening. Often a negative match

RewriteCond
looking at
%{THE_REQUEST}
can be used.

System

12:18 pm on Jan 17, 2009 (gmt 0)

redhat



The following message was cut out to new thread by jdmorgan. New thread at: apache/3828487.htm [webmasterworld.com]
11:25 am on Jan. 17, 2009 (CT -6)