File Coverage

blib/lib/Plack/Request/WithEncoding.pm
Criterion Covered Total %
statement 73 74 98.6
branch 14 16 87.5
condition 8 12 66.6
subroutine 19 19 100.0
pod 8 8 100.0
total 122 129 94.5


line stmt bran cond sub pod time code
1             package Plack::Request::WithEncoding;
2 2     2   46534 use 5.008_001;
  2         16  
3 2     2   11 use strict;
  2         4  
  2         39  
4 2     2   9 use warnings;
  2         4  
  2         68  
5 2     2   584 use parent qw/Plack::Request/;
  2         339  
  2         16  
6 2     2   135620 use Encode ();
  2         5  
  2         33  
7 2     2   12 use Carp ();
  2         5  
  2         33  
8 2     2   11 use Hash::MultiValue;
  2         4  
  2         74  
9              
10             our $VERSION = "0.14";
11              
12 2     2   12 use constant KEY_BASE_NAME => 'plack.request.withencoding';
  2         4  
  2         133  
13 2     2   13 use constant DEFAULT_ENCODING => 'utf-8';
  2         6  
  2         1570  
14              
15             sub encoding {
16 26     26 1 25624 my $env = $_[0]->env;
17 26         95 my $k = KEY_BASE_NAME . '.encoding';
18              
19             # In order to be able to specify the `undef` into $req->env->{plack.request.withencoding.encoding}
20 26 100       144 exists $env->{$k} ? $env->{$k} : ($env->{$k} = DEFAULT_ENCODING);
21             }
22              
23             sub body_parameters {
24 10     10 1 40285 my $self = shift;
25 10   66     32 $self->env->{KEY_BASE_NAME . '.body'} ||= $self->_decode_parameters($self->SUPER::body_parameters);
26             }
27              
28             sub query_parameters {
29 8     8 1 1556 my $self = shift;
30 8   66     23 $self->env->{KEY_BASE_NAME . '.query'} ||= $self->_decode_parameters($self->SUPER::query_parameters);
31             }
32              
33             sub parameters {
34 19     19 1 27316 my $self = shift;
35 19   66     60 $self->env->{KEY_BASE_NAME . '.merged'} ||= do {
36 5         41 my $query = $self->query_parameters;
37 4         148 my $body = $self->body_parameters;
38 4         114 Hash::MultiValue->new($query->flatten, $body->flatten);
39             }
40             }
41              
42             sub raw_body_parameters {
43 2     2 1 4139 shift->SUPER::body_parameters;
44             }
45              
46             sub raw_query_parameters {
47 1     1 1 5 shift->SUPER::query_parameters;
48             }
49              
50             sub raw_parameters {
51 4     4 1 5 my $self = shift;
52              
53 4   66     17 $self->env->{'plack.request.merged'} ||= do {
54 1         9 my $query = $self->SUPER::query_parameters();
55 1         161 my $body = $self->SUPER::body_parameters();
56 1         95 Hash::MultiValue->new( $query->flatten, $body->flatten );
57             };
58             }
59              
60             sub raw_param {
61 4     4 1 6429 my $self = shift;
62              
63 4         11 my $raw_parameters = $self->raw_parameters;
64 4 50       83 return keys %{ $raw_parameters } if @_ == 0;
  0         0  
65              
66 4         8 my $key = shift;
67 4 100       30 return $raw_parameters->{$key} unless wantarray;
68 1         6 return $raw_parameters->get_all($key);
69             }
70              
71             sub _decode_parameters {
72 12     12   2526 my ($self, $stuff) = @_;
73 12 100       29 return $stuff unless $self->encoding; # return raw value if encoding method is `undef`
74              
75 9         20 my $encoding = Encode::find_encoding($self->encoding);
76 9 100       11455 unless ($encoding) {
77 1         4 my $invalid_encoding = $self->encoding;
78 1         270 Carp::croak("Unknown encoding '$invalid_encoding'.");
79             }
80              
81 8         33 my @flatten = $stuff->flatten;
82 8         121 my @decoded;
83 8         34 while ( my ($k, $v) = splice @flatten, 0, 2 ) {
84 11         42 push @decoded, $self->_decode($encoding, $k), $self->_decode($encoding, $v);
85             }
86 8         44 return Hash::MultiValue->new(@decoded);
87             }
88              
89             sub _decode {
90 29     29   108 my ($self, $encoding, $data) = @_;
91              
92 29 100       75 if (ref $data eq "ARRAY") {
    100          
93 1         2 my @result;
94 1         4 for my $d (@$data) {
95 3         14 push @result, $self->_decode($encoding, $d);
96             }
97 1         8 return \@result;
98             }
99             elsif (ref $data eq "HASH") {
100 1         3 my %result;
101 1         8 while (my ($k, $v) = each %$data) {
102 2         16 $result{$self->_decode($encoding, $k)} = $self->_decode($encoding, $v);
103             }
104 1         11 return \%result;
105             }
106              
107 27 50       144 return defined $data ? $encoding->decode($data) : undef;
108             }
109              
110             1;
111             __END__