File Coverage

blib/lib/Plack/Middleware/XForwardedFor.pm
Criterion Covered Total %
statement 38 38 100.0
branch 11 12 91.6
condition 1 2 50.0
subroutine 9 9 100.0
pod 2 2 100.0
total 61 63 96.8


line stmt bran cond sub pod time code
1             package Plack::Middleware::XForwardedFor;
2             BEGIN {
3 1     1   1019 $Plack::Middleware::XForwardedFor::VERSION = '0.103060';
4             }
5             # ABSTRACT: Plack middleware to handle X-Forwarded-For headers
6              
7 1     1   8 use strict;
  1         2  
  1         33  
8 1     1   4 use warnings;
  1         2  
  1         44  
9 1     1   4 use parent qw(Plack::Middleware);
  1         2  
  1         7  
10 1     1   67 use Plack::Util::Accessor qw( trust );
  1         2  
  1         9  
11 1     1   7486 use Regexp::Common qw /net/;
  1         4557  
  1         7  
12 1     1   5970 use Net::Netmask;
  1         19230  
  1         393  
13              
14             sub prepare_app {
15 6     6 1 2313 my $self = shift;
16              
17 6 100       20 if (my $trust = $self->trust) {
18 4 100       29 my @trust = map { Net::Netmask->new($_) } ref($trust) ? @$trust : ($trust);
  5         59  
19 4         181 $self->trust(\@trust);
20             }
21             }
22              
23             sub call {
24 6     6 1 263 my ($self, $env) = @_;
25              
26 6   50     40 my @forward = ($env->{HTTP_X_FORWARDED_FOR} || '') =~ /\b($RE{net}{IPv4})\b/g;
27              
28 6 50       778 if (@forward) {
29 6         14 my $addr = $env->{REMOTE_ADDR};
30 6 100       15 if (my $trust = $self->trust) {
31             ADDR: {
32 4 100       21 if (my $next = pop @forward) {
  8         17  
33 6         10 foreach my $netmask (@$trust) {
34 7 100       42 if ($netmask->match($addr)) {
35 4         91 $addr = $next;
36 4         10 redo ADDR;
37             }
38             }
39             }
40             }
41             }
42             else { # trust everything, so use first in list
43 2         14 $addr = shift @forward;
44             }
45 6         112 $env->{REMOTE_ADDR} = $addr;
46             }
47              
48 6         18 $self->app->($env);
49             }
50              
51             1;
52              
53             =head1 NAME
54              
55             Plack::Middleware::XForwardedFor - Plack middleware to handle X-Forwarded-For headers
56              
57             =head1 VERSION
58              
59             version 0.103060
60              
61             =head1 SYNOPSIS
62              
63             builder {
64             enable "Plack::Middleware::XForwardedFor",
65             trust => [qw(127.0.0.1/8)];
66             };
67              
68             =head1 DESCRIPTION
69              
70             C will look for C
71             header in the incomming request and change C to the
72             real client IP
73              
74             =head1 PARAMETERS
75              
76             =over
77              
78             =item trust
79              
80             If not spcified then all addressed are trusted and C will be set to the
81             first IP in the C header.
82              
83             If given, it should be a list of IPs or Netmasks that can be trusted. Starting with the IP
84             of the client in C then the IPs in the C header from right to left.
85             The first untrusted IP found is set to be C
86              
87             =back
88              
89             =head1 SEE ALSO
90              
91             L, L
92              
93             =head1 AUTHOR
94              
95             Graham Barr
96              
97             =head1 COPYRIGHT AND LICENSE
98              
99             This software is copyright (c) 2010 by Graham Barr.
100              
101             This is free software; you can redistribute it and/or modify it under
102             the same terms as the Perl 5 programming language system itself.
103              
104             =cut