From 7426502c697fc5f7f87390e881b8d4e216120171 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Tue, 4 Jun 2013 22:29:40 -0700 Subject: [PATCH] Add `remote_host()` and `address()` to Request. They prefer forwarded host and address information, when present. This should allow the proper remote host name to be included in the registration administration email when PGXN Manager is running behind a rerverse proxy. Closes #39. --- Changes | 4 ++++ README.md | 6 ++++-- lib/PGXN/Manager/Request.pm | 21 +++++++++++++++++++++ t/pod-spelling.t | 1 + t/request.t | 10 +++++++++- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Changes b/Changes index 208d71b..ac8edaa 100644 --- a/Changes +++ b/Changes @@ -20,6 +20,10 @@ Revision history for Perl extension PGXN::Manager properly. - Updated the HOWTO to properly order things in the `Makefile` and to include a `dist` target. + - Added `remote_host()` and `address()` to PGXN::API::Request to return + the forwarded host name and address, if present. This should allow + the proper host information to be included in the registration admin + email (issue #38). 0.14.1 2012-01-11T18:29:26Z - Greatly improved the `check_mirrors` utility, making it work with the diff --git a/README.md b/README.md index c404392..d8f19af 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,8 @@ way to separate these is to set up two reverse proxy servers: One to serve location / { proxy_pass http://127.0.0.1:7496/pub/; proxy_redirect off; - proxy_set_header Host $host; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-HTTPS ""; proxy_set_header X-Forwaded-Proto http; proxy_set_header X-Forwarded-Port 80; @@ -273,7 +274,8 @@ way to separate these is to set up two reverse proxy servers: One to serve location / { proxy_pass http://127.0.0.1:7496/auth/; proxy_redirect off; - proxy_set_header Host $host; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-HTTPS ON; proxy_set_header X-Forwaded-Proto https; proxy_set_header X-Forwarded-Port 443; diff --git a/lib/PGXN/Manager/Request.pm b/lib/PGXN/Manager/Request.pm index adb9639..2a06eb9 100644 --- a/lib/PGXN/Manager/Request.pm +++ b/lib/PGXN/Manager/Request.pm @@ -85,6 +85,16 @@ sub is_xhr { shift->env->{HTTP_X_REQUESTED_WITH} eq 'XMLHttpRequest'; } +sub address { + my $env = $_[0]->env; + return $env->{X_FORWARDED_FOR} || $env->{REMOTE_ADDR}; +} + +sub remote_host { + my $env = $_[0]->env; + return $env->{X_FORWARDED_HOST} || $env->{REMOTE_HOST}; +} + # Eliminates use of env->{'plack.request.query'}? sub query_parameters { my $self = shift; @@ -209,6 +219,17 @@ Returns true if the request is an C request and false if not. This is specific to L sending the C header. +=head3 C
+ +Returns the (possibly forwarded) IP address of the client (C +or C). + +=head3 C + +Returns the (possibly forwarded) remote host (C or +C) of the client. It may be empty, in which case you have to get +the IP address using C
method and resolve on your own. + =head3 C =head3 C diff --git a/t/pod-spelling.t b/t/pod-spelling.t index a2a792f..0de7817 100644 --- a/t/pod-spelling.t +++ b/t/pod-spelling.t @@ -36,3 +36,4 @@ reindex Reindexes reindexes JSON +IP diff --git a/t/request.t b/t/request.t index 2251efd..027f18b 100644 --- a/t/request.t +++ b/t/request.t @@ -2,7 +2,7 @@ use 5.10.0; use utf8; -use Test::More tests => 50; +use Test::More tests => 54; #use Test::More 'no_plan'; use HTTP::Request::Common; use HTTP::Message::PSGI; @@ -175,3 +175,11 @@ is $req->param('q'), "メインページ", 'q param should be decoded'; is_deeply [$req->parameters->get_all('q')], ['テスト', 'メインページ'], 'All q values should be decoded'; +############################################################################## +# Test remote_host() and address(). +is $req->remote_host, 'localhost', 'remote_host should be "localhost"'; +is $req->address, '127.0.0.1', 'remote_host should be "127.0.0.1"'; +$req->env->{X_FORWARDED_HOST} = 'foo'; +is $req->remote_host, 'foo', 'remote_host should prefer X-Forwarded-host'; +$req->env->{X_FORWARDED_FOR} = '192.168.0.1'; +is $req->address, '192.168.0.1', 'remote_host should prefer X-Forwarded-For';