server port number in requests

server port number in requests

am 23.04.2008 11:47:31 von John ORourke

Hi folks,

I can't seem to find a way to retrieve the inbound port number during
requests.

I have a server listening on multiple ports, and need to know which one
the request came in on. Here's the setup:

apache config:
Listen 127.0.0.1:81
Listen 127.0.0.1:82
NameVirtualHost *:*

......


The underlying reason for this is that I have a reverse proxy in front
of it, which proxies HTTP and HTTPS requests. The back-end needs to
create self-referencing URLs but cannot tell if it's HTTP or HTTPS, so I
decided to direct HTTP to port 81 and HTTPS to port 82. I'd prefer to
do it by adding a request header so if someone knows a way to do that
please let me know!

cheers
John

Re: server port number in requests

am 23.04.2008 12:28:11 von Rhesa Rozendaal

John ORourke wrote:
> Hi folks,
>
> The underlying reason for this is that I have a reverse proxy in front
> of it, which proxies HTTP and HTTPS requests. The back-end needs to
> create self-referencing URLs but cannot tell if it's HTTP or HTTPS, so I
> decided to direct HTTP to port 81 and HTTPS to port 82. I'd prefer to
> do it by adding a request header so if someone knows a way to do that
> please let me know!

I stole this strategy from the Rails folks: on the frontend https, add this line:

RequestHeader set X_FORWARDED_PROTO 'https'

On the backend, you can then test for $ENV{X_FORWARDED_PROTO}.


Rhesa

Re: server port number in requests

am 23.04.2008 12:32:21 von aw

John ORourke wrote:
> Hi folks,
>
> I can't seem to find a way to retrieve the inbound port number during
> requests.
>
> I have a server listening on multiple ports, and need to know which one
> the request came in on. Here's the setup:
>
> apache config:
> Listen 127.0.0.1:81
> Listen 127.0.0.1:82
> NameVirtualHost *:*
>
> ......
>

>
I believe you could resolve this as follows (although it is really a
"brute force" method) :
Instead of one , you could define 2 sections, entirely
copy of eachother except for :


PerlSetVar ConnType "HTTP"
....



PerlSetVar ConnType "HTTPS"
....


and then in your script/handler get the ConnType config value to tell
the difference.

AW

Re: server port number in requests

am 23.04.2008 12:45:39 von aw

André Warnier wrote:
>
>
> John ORourke wrote:
>> Hi folks,
>>
>> I can't seem to find a way to retrieve the inbound port number during
>> requests.
>>
>> I have a server listening on multiple ports, and need to know which
>> one the request came in on. Here's the setup:
>>
>> apache config:
>> Listen 127.0.0.1:81
>> Listen 127.0.0.1:82
>> NameVirtualHost *:*
>>
>> ......
>>

>>
> I believe you could resolve this as follows (although it is really a
> "brute force" method) :
> Instead of one , you could define 2 sections, entirely
> copy of eachother except for :
>
>
> PerlSetVar ConnType "HTTP"
> ....
>

>
>
> PerlSetVar ConnType "HTTPS"
> ....
>

>
> and then in your script/handler get the ConnType config value to tell
> the difference.
>

Addendum :
Apart from he brute force method above, I believe there must be numerous
other ways to achieve best what you really need.
For instance, I would have a look at the Apache SetEnvIf configuration
directive, which may be used to set an environment variable later
retrieved by your script/module.
I would also imagine that a HTTPS request already includes some specific
HTTP headers which a HTTP request does not have, and you could test for
that (either in the script/module or with SetEnvIf).
Which method really works best in your case, and which is the most
efficient, is left as an exercise to the reader.

Re: server port number in requests

am 23.04.2008 13:15:48 von Clinton Gormley

Hi John

> The underlying reason for this is that I have a reverse proxy in
> front
> of it, which proxies HTTP and HTTPS requests. The back-end needs to
> create self-referencing URLs but cannot tell if it's HTTP or HTTPS, so I
> decided to direct HTTP to port 81 and HTTPS to port 82. I'd prefer to
> do it by adding a request header so if someone knows a way to do that
> please let me know!

You can do this with $request->get_server_port

However, what I'm doing is running a single server on my backend
machines, and then on my proxy (I'm using Pound), I have this config:

ListenHTTP
Address x.x.x.x
Port 80
HeadRemove "X-Forwarded-For"
HeadRemove "X-HTTPS"
RewriteLocation 0
End

ListenHTTPS
Address x.x.x.x
Port 443
Cert "/path/to/cert.pem"
HeadRemove "X-Forwarded-For"
AddHeader "X-HTTPS: 1"
RewriteLocation 0
End

Clint

Re: server port number in requests

am 23.04.2008 13:25:52 von aw

André Warnier wrote:
>
> André Warnier wrote:
>>
>>
>> John ORourke wrote:
>>> Hi folks,
>>>
>>> I can't seem to find a way to retrieve the inbound port number during
>>> requests.
>>>
>>> I have a server listening on multiple ports, and need to know which
>>> one the request came in on. Here's the setup:
>>>
>>> apache config:
>>> Listen 127.0.0.1:81
>>> Listen 127.0.0.1:82
>>> NameVirtualHost *:*
>>>
>>> ......
>>>

>>>
>> I believe you could resolve this as follows (although it is really a
>> "brute force" method) :
>> Instead of one , you could define 2 sections,
>> entirely copy of eachother except for :
>>
>>
>> PerlSetVar ConnType "HTTP"
>> ....
>>

>>
>>
>> PerlSetVar ConnType "HTTPS"
>> ....
>>

>>
>> and then in your script/handler get the ConnType config value to tell
>> the difference.
>>
>
> Addendum :
> Apart from he brute force method above, I believe there must be numerous
> other ways to achieve best what you really need.
> For instance, I would have a look at the Apache SetEnvIf configuration
> directive, which may be used to set an environment variable later
> retrieved by your script/module.
> I would also imagine that a HTTPS request already includes some specific
> HTTP headers which a HTTP request does not have, and you could test for
> that (either in the script/module or with SetEnvIf).
> Which method really works best in your case, and which is the most
> efficient, is left as an exercise to the reader.
>

Addendum # 2 :

Here is a more mod_perl-ish solution :

use Apache2::RequestRec ();
use Apache2::Connection ();
use APR::SockAddr ();

sub handler {

my $r = shift;
my $c = $r->connection;
my $serverport = $c->local_addr->port;

# ... and now you know

}

Refs :
http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html# C_connection_
http://perl.apache.org/docs/2.0/api/Apache2/Connection.html# C_local_addr_
http://perl.apache.org/docs/2.0/api/APR/SockAddr.html

Note : I am deriving this purely from the documentation, and haven't
tried it myself yet.

Re: server port number in requests

am 23.04.2008 13:28:34 von torsten.foertsch

On Wed 23 Apr 2008, John ORourke wrote:
> The underlying reason for this is that I have a reverse proxy in front
> of it, which proxies HTTP and HTTPS requests. =A0The back-end needs to
> create self-referencing URLs but cannot tell if it's HTTP or HTTPS, so I
> decided to direct HTTP to port 81 and HTTPS to port 82. =A0I'd prefer to
> do it by adding a request header so if someone knows a way to do that
> please let me know!

If mod_perl is enabled on the proxy you can simply add something to=20
$r->headers_in prior to the response phase. It will be transmitted to the=20
backend.

Otherwise if you have mod_headers you can use the RequestHeader directive. =
The=20
SSL enabled vhost sets a custom header to one value the other vhost to=20
another. You must set it in both cases or someone can send that header to t=
he=20
proxy and it will be forwarded to the backend.

Torsten=20

=2D-
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: server port number in requests

am 23.04.2008 15:16:22 von John ORourke

Many, many thanks for the input everyone - naturally it turned out to be
a case of RTFM but here's a summary of the simplest ways to do it. I've
no idea how I missed these in the docs, though I am at the
bang-head-on-wall stage of development.

(I'm going on the assumption that the proxy may not be running mod_perl
to keep memory footprint down)

1 - RequestHeader directive in the HTTPS proxy - avoids listening on 2
ports but runs late in the request (fixup) - fine for proxying.

2 - $r->connection()->local_addr()->port(); (I missed that in the docs
by assuming local_addr returned an IP address string, not an
APR::Socket). It's a clean way but differing by port number is not a
flexible way to set up the application, makes it less portable.

I've just spent half an hour creating this (Apache) config snippet which
can be included in both the HTTP and HTTPS proxies:

SetEnv SCHEME http
SetEnv HOST localhost
RewriteEngine on
RewriteCond %{HTTPS} on
RewriteRule ^(.*) $1 [E=SCHEME:https]
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteRule ^(.*) $1 [PT,E=HOST:%1] <--------- note the
PT flag, allows mod_proxy to work!
RequestHeader set X-Absolute-URI %{SCHEME}e://%{HOST}e

and make the app allow the absolute URI to be overridden by that header.

This leaves one small security hole - any server this app is installed
on must prevent browsers from setting that header, otherwise Bad
Things(tm) may happen.

cheers
John