Re: getting $r and env to reflect external ports

2009-08-14 Thread André Warnier

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 ?


Re: getting $r and env to reflect external ports

2009-08-14 Thread Jonathan Swartz

> 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



Re: getting $r and env to reflect external ports

2009-08-15 Thread Torsten Foertsch
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.foert...@gmx.net