Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: ModPerl: ModPerl

getting $r and env to reflect external ports

 

 

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded


swartz at pobox

Aug 14, 2009, 3:15 PM

Post #1 of 4 (722 views)
Permalink
getting $r and env to reflect external ports

We've got a bunch of legacy code that uses $ENV{SCRIPT_URI},
$ENV{SERVER_PORT}, $r->server->port and the like to generate external
redirects.

This has worked fine til now, but now we are moving to a system where
our external port != our internal port - the load balancer is going to
forward ports 80 and ports 443 to non-secure ports 8080 and 8443 (so
that we can run httpd as a non-root user.) Unfortunately, the code
mentioned above will then use the wrong (internal) ports in the
redirects. If I were using Apache reverse proxy, ProxyPassReverse
would take care of this, but I'm not.

The legacy code is scattered in many files and will be difficult to
change. Thus I'm wondering if there's an easy way to get %ENV and $r
to reflect the external ports, without going through and changing each
port-related $ENV and $r value by hand.

e.g. In the Apache code I see that the ENV vars are populated via
ap_get_server_port - is there a way for me to hook in early enough
that I can change this?

Thanks
Jon


aw at ice-sa

Aug 14, 2009, 3:32 PM

Post #2 of 4 (687 views)
Permalink
Re: getting $r and env to reflect external ports [In reply to]

Jonathan Swartz wrote:
> We've got a bunch of legacy code that uses $ENV{SCRIPT_URI},
> $ENV{SERVER_PORT}, $r->server->port and the like to generate external
> redirects.
>
If these are really external redirects, they must happen through a
"Location:" response header, no ?
In that case, what about leaving your code alone and use an output
filter modifying these Location headers ?


swartz at pobox

Aug 14, 2009, 4:12 PM

Post #3 of 4 (678 views)
Permalink
Re: getting $r and env to reflect external ports [In reply to]

> > We've got a bunch of legacy code that uses $ENV{SCRIPT_URI},
> > $ENV{SERVER_PORT}, $r->server->port and the like to generate
> external
> > redirects.
> >
> If these are really external redirects, they must happen through a
> "Location:" response header, no ?
> In that case, what about leaving your code alone and use an output
> filter modifying these Location headers ?

Good question. That could work for redirects. But some of the code
also examines the values of these ports in conditionals, e.g.

if ($ENV{SERVER_PORT} == 80) { ... }

It isn't pretty, but it's old code and I don't want to be the one to
break it. :) Ideally I want the code to see the environment as it was
before the port switch. Maybe this is asking too much though...

Jon


torsten.foertsch at gmx

Aug 15, 2009, 10:04 AM

Post #4 of 4 (681 views)
Permalink
Re: getting $r and env to reflect external ports [In reply to]

On Sat 15 Aug 2009, Jonathan Swartz wrote:
> We've got a bunch of legacy code that uses $ENV{SCRIPT_URI},  
> $ENV{SERVER_PORT}, $r->server->port and the like to generate external
>   redirects.
>
> This has worked fine til now, but now we are moving to a system where
>   our external port != our internal port - the load balancer is going
> to forward ports 80 and ports 443 to non-secure ports 8080 and 8443
> (so that we can run httpd as a non-root user.) Unfortunately, the
> code mentioned above will then use the wrong (internal) ports in the
> redirects. If I were using Apache reverse proxy, ProxyPassReverse
> would take care of this, but I'm not.
>
> The legacy code is scattered in many files and will be difficult to  
> change. Thus I'm wondering if there's an easy way to get %ENV and $r
>   to reflect the external ports, without going through and changing
> each port-related $ENV and $r value by hand.
>
> e.g. In the Apache code I see that the ENV vars are populated via  
> ap_get_server_port - is there a way for me to hook in early enough  
> that I can change this?

According to the docs the server port can also be set. But I think this is not a good idea.

The $r->server->port part can possibly be circumvented by reassigning a new function to the Apache2::ServerRec::port symbol at startup time. Try this in your startup.pl:

use Apache2::ServerRec ();
BEGIN {
my $old=\&Apache2::ServerRec::port;
*Apache2::ServerRec::port=sub {
if( @_==1 ) { # read access
my $port=$old->(@_);
if( $port==8080 ) {
return 80;
} elsif(...) {
...
} else {
return $port;
}
} else {
return $old->(@_);
}
};
}

As for the %ENV part this approach may work. Call $r->subprocess_env in void context without parameters somewhere before the response phase, e.g. fixup. This initializes the CGI variables in %ENV or rather $r->subprocess_env. Then use $r->subprocess_env to change what you need. The subsequent perl-script handler will know that the CGI variables are already set up and won't do it again. So your script should see the overridden values. That's the theory.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch [at] gmx

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.