Forum Moderators: phranque

Message Too Old, No Replies

Internal Redirect for site folders to come from another server

Complex httpd.conf question

         

craig1972

7:41 pm on Apr 23, 2009 (gmt 0)

10+ Year Member



Hope one of the gurus can help me here. I've tried a number of things but failed.

My domain structure is as follows:


abc.com
abc.com/folder1
abc.com/folder2
abc.com/folder3

I have three web servers for sharing load. Currently all folders come from my main web server of course, as usual. But because of heavy site traffic I now want my "folder2" and "folder3" to come from different web servers.

Not domains or subdomains, but just *folders* of a site!

That's why I'm stuck. I was trying something like this in the httpd.conf for the main web server's Apache, so that I could forward (internally) all traffic from "/folder3" to the third web server--


RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com\.?(:[0-9]+)?$
RewriteCond $1 folder3/
RewriteRule ^/(.*)$ http://10.10.x.3/folder3/$1 [L]

My couple questions:

1. In second line, how should I check for "folder3"? My code doesn't work.

2. In third line, how can I make sure an internal private IP redirect can be done without "R=301"? Including a [10.10.x.3...] requires an external redirect? If yes, then is there another way of leveraging a private LAN somehow to point *not* domains/subdomains but specific folders?

Many thanks!

craig1972

7:57 pm on Apr 23, 2009 (gmt 0)

10+ Year Member



Btw, I don't know if I could use some Unix type wizardry, like "linking" files in a folder on one server with files in a folder on another server? Through NFS etc. Would picking PHP files from an NFS-linked folder seriously affect Apache's performance? (No writing stuff, just website's reading as usual.)

Caterham

8:42 pm on Apr 23, 2009 (gmt 0)

10+ Year Member



You're looking for a reverse proxy.
Do you really need to check the host? If not, use the ProxyPass [httpd.apache.org] directive.

craig1972

4:24 am on Apr 24, 2009 (gmt 0)

10+ Year Member



Thanks Caterham.

Great RTFM there for me. But one concern: would ReverseProxy reduce performance? E.g., this somewhat dated mailing list post: [marc.info...]

Is there some kind of caching etc I could use?

craig1972

8:37 am on Apr 24, 2009 (gmt 0)

10+ Year Member



Or, what kinds of settings should I have to make the ReverseProxy as fast as if the files were coming from the same server? Performance tweaking of ReverseProxy I mean.

Caterham

9:00 am on Apr 24, 2009 (gmt 0)

10+ Year Member



would ReverseProxy reduce performance

You'll have a backend http request; that takes some time of course but you won't face the internet bandwidth speed issues.

Is there some kind of caching etc I could use?

Yes, mod_cache/mod_disk_cache for example. But I wouldn't proxy everything to a backend server, i.e., only dynamical generated content and serve static files as normal - may be with enablesendfile [httpd.apache.org] if OS permits - or use and reference a different server for resources such as images so that image requests won't hit your main server but e.g. img.example.com. That would require some HTML source code changes, of course.

craig1972

9:46 am on Apr 25, 2009 (gmt 0)

10+ Year Member



Thanks. This is working. But in the destination server (server 3) the values of PHP changes. For example:

I am forwarding the proxy from my main server something like this:


ProxyPass /folder http://server3.com/~domain/folder/

Now on the server3.com the value of PHP_SELF variable should be "/folder/x.php" but it is in fact "/~domain/folder/x.php".

I know it is the accurate value, but I want the paths to appear as they appear to the user in the browser.

Is there any Apache or PHP setting that will allow this?

g1smd

9:51 am on Apr 25, 2009 (gmt 0)

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



SELF refers to where it is in relation to the filesystem on the server.

You'll need to look at the value for the original URL REQUEST if you need the path part for that.

Caterham

11:43 am on Apr 25, 2009 (gmt 0)

10+ Year Member



If you slash the backend-server, you should have a trailing slash for the path as well.

ProxyPass /folder/ http://server3.com/~domain/folder/ 

Now on the server3.com the value of PHP_SELF variable should be "/folder/x.php" but it is in fact "/~domain/folder/x.php".

In order to communicate the frontend-requested uri to the backend server you'll have to set a request header via mod_headers

SetEnvIf Request_URI ^(/folder/.*) forw-uri=$1
RequestHeader set X-Forwarded-Uri %{forw-uri}e env=forw-uri

craig1972

3:17 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



Thanks so much caterham! The setenv stuff will go in the main web server or the server that i redirect traffic to with the proxypass stuff? (I can try and err, but this is a production server). Thanks@

Caterham

3:27 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



The setenv stuff will go in the main web server or the server that i redirect traffic to with the proxypass stuff?

Where your ProxyPass directive lives, i.e. main server. Only that server can pass a request header to a backend server (and has the knowledge about the requested uri).

craig1972

3:35 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



Thanks a bunch. I included the code as follows in the httpd.conf of the main web server:


SetEnvIf Request_URI ^(/folder/.*) forw-uri=$1
RequestHeader set X-Forwarded-Uri %{forw-uri}e env=forw-uri

Then in the target (redirected) web server, from where the "folder" is read, I created a test PHP page (/folder/test.php).


<?php
echo $_SERVER['PHP_SELF'];
?>

But this still shows the "/~domain/folder/test.php". This should actually read "/folder/test.php".

Any thoughts?

craig1972

3:40 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



Btw, did you mean I should replace the "forw-uri" with something of my own? I thought it's just a variable name.

Caterham

5:54 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



The PHP variable won't and can't change unless you modify php's source code and recompile. You'd have to use

$_SERVER['X-Forwarded-Uri']

if you use that header name in the RequestHeader directive (you can use any unless there is no conflict with existing ones).

did you mean I should replace the "forw-uri" with something of my own? I thought it's just a variable name.

It is just an env, correct.

craig1972

6:17 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



Great. Wow, I didn't know you could use environment variables like that!

Side question: Can I set my site specific variables in httpd.conf? Is it better performance than using DEFINE in php because apache's env vars are available at runtime?

Caterham

8:54 pm on Apr 25, 2009 (gmt 0)

10+ Year Member



Well, we're using a HTTP request header, the env is just used to a) invoke the directive only for certain requests (=env present, i.e. a request for /folder/...) and b) to pass the value.

That doesn't mean that you should set your application variables with headers or envs, but you could (SetEnv - not SetEnvIf - directive; avoid regular expressions). You'd have to use that directive at your backend server.

Is it better performance than using DEFINE in php because apache's env vars are available at runtime?

I doubt. Apache needs to set the env per request, the handler (mod_php) calls the envs and makes them available. I wouldn't expect that you can measure a difference; it's not a complex operation parsing your define code.