File Coverage

blib/lib/Plack/Middleware/Inflater.pm
Criterion Covered Total %
statement 60 60 100.0
branch 8 14 57.1
condition n/a
subroutine 15 15 100.0
pod 2 3 66.6
total 85 92 92.3


line stmt bran cond sub pod time code
1             package Plack::Middleware::Inflater;
2             $Plack::Middleware::Inflater::VERSION = '0.001';
3             # ABSTRACT: Inflate gzipped PSGI requests
4              
5 1     1   95535 use strict;
  1         2  
  1         29  
6 1     1   3 use warnings;
  1         1  
  1         25  
7 1     1   20 use 5.012;
  1         6  
8 1     1   4 use Carp;
  1         1  
  1         74  
9 1     1   4 use autodie;
  1         1  
  1         12  
10 1     1   3432 use utf8;
  1         1  
  1         6  
11              
12 1     1   24 use base 'Plack::Middleware';
  1         1  
  1         558  
13 1     1   4639 use Plack::Util;
  1         2  
  1         20  
14 1     1   4 use Plack::Util::Accessor qw/content_encoding/;
  1         1  
  1         4  
15 1     1   605 use IO::Uncompress::Gunzip qw/gunzip/;
  1         28647  
  1         65  
16 1     1   529 use IO::Scalar;
  1         3235  
  1         259  
17              
18             sub prepare_app {
19 1     1 1 63 my $self = shift;
20 1 50       5 unless ($self->content_encoding) {
21 1         45 $self->content_encoding([qw/gzip/]);
22             }
23             }
24              
25             sub modify_request_maybe {
26 3     3 0 5 my ($self, $env) = @_;
27              
28 3 50       10 return if $env->{'plack.skip-inflater'};
29              
30 3 100       9 my $content_encoding = $env->{HTTP_CONTENT_ENCODING} or return;
31              
32             # this thing stolen from Plack::Middleware::Deflater
33 2         5 $content_encoding =~ s/(;.*)$//;
34 2 50       9 if (my $match_cts = $self->content_encoding) {
35 2         14 my $match=0;
36 2         2 for my $match_ct ( @{$match_cts} ) {
  2         5  
37 2 50       6 if ($content_encoding eq $match_ct) {
38 2         3 $match++;
39 2         3 last;
40             }
41             }
42 2 50       6 return unless $match;
43             }
44              
45             # if we're here it's one of the values of Content-Type that we
46             # want to inflate as gzip
47              
48 2 50       5 if ($env->{'psgi.input'}) {
49 2         2 my $inflated = '';
50 2         10 gunzip $env->{'psgi.input'}, \$inflated;
51 2         2925 $env->{'psgi.input'} = IO::Scalar->new(\$inflated);
52 2         116 my $content_length = do {
53 1     1   7 use bytes;
  1         1  
  1         6  
54 2         3 length $inflated };
55 2         4 $env->{CONTENT_LENGTH} = $content_length;
56             }
57             }
58              
59             sub call {
60 3     3 1 31901 my ($self, $env) = @_;
61 3         8 $self->modify_request_maybe($env);
62 3         14 return $self->app->($env);
63             }
64              
65             1;
66              
67              
68             =pod
69              
70             =head1 NAME
71              
72             Plack::Middleware::Inflater - Inflate gzipped PSGI requests
73              
74             =head1 VERSION
75              
76             version 0.001
77              
78             =head1 SYNOPSIS
79              
80             use Plack::Builder;
81             builder {
82             enable 'Inflater', content_encoding => [qw/gzip deflate/];
83             sub {
84             my $request = Plack::Request->new(shift);
85             my $response = $request->new_response(
86             200,
87             ['X-Request-Content-Length', $request->header('Content-Length'),
88             'X-Request-Content', $request->content],
89             'OK');
90             return $response->finalize;
91             };
92             };
93              
94             =head1 DESCRIPTION
95              
96             This PSGI middleware inflates incoming gzipped requests before they
97             hit your PSGI app. This only happens whenever the request's
98             C header is one of the values specified in the
99             C attribute, which defaults to C<['gzip']>.
100              
101             This lets you send compressed requests, like this:
102              
103             curl --header 'Content-Encoding: gzip' --data-binary @foobar.gz http://...
104              
105             =head1 SEE ALSO
106              
107             L
108              
109             =head1 AUTHOR
110              
111             Fabrice Gabolde
112              
113             =head1 COPYRIGHT AND LICENSE
114              
115             This software is copyright (c) 2016 by Weborama.
116              
117             This is free software; you can redistribute it and/or modify it under
118             the same terms as the Perl 5 programming language system itself.
119              
120             =cut
121              
122              
123             __END__