File Coverage

blib/lib/MojoX/Encode/Gzip.pm
Criterion Covered Total %
statement 37 39 94.8
branch 3 6 50.0
condition 10 19 52.6
subroutine 7 7 100.0
pod 1 1 100.0
total 58 72 80.5


line stmt bran cond sub pod time code
1             package MojoX::Encode::Gzip;
2              
3             # ABSTRACT: Gzip a Mojo::Message::Response
4              
5 2     2   131043 use strict;
  2         12  
  2         57  
6 2     2   11 use warnings;
  2         4  
  2         50  
7              
8 2     2   10 use base 'Mojo::Base';
  2         16  
  2         1022  
9              
10 2     2   370268 use Data::Dumper;
  2         4  
  2         123  
11 2     2   947 use Mojo::Content::Single;
  2         89239  
  2         21  
12 2     2   87 use Mojo::Util qw(gzip);
  2         5  
  2         694  
13              
14             our $VERSION = '1.13';
15              
16             __PACKAGE__->attr( min_bytes => 500 );
17             __PACKAGE__->attr( max_bytes => 500000 );
18              
19             sub maybe_gzip {
20 2     2 1 5493 my $self = shift;
21 2         4 my $tx = shift;
22             #my $debug = shift;
23              
24 2         6 my $req = $tx->req;
25 2         13 my $res = $tx->res;
26              
27 2   100     13 my $accept = $req->headers->header('Accept-Encoding') || '';
28 2         80 my $body = $res->body;
29 2   50     38 my $length = $res->body_size || 0;
30              
31             # Don't both unless:
32             # - we have a success code
33             # - we have a content type that makes sense to gzip
34             # - a client is asking for giving
35             # - the content is not already encoded.
36             # - The body is not too small or too large to gzip
37             # XXX content-types should be configurable.
38 2 50 66     41 unless ( ( index( $accept, 'gzip' ) >= 0 )
      66        
      33        
      33        
      33        
39             and ( $length > $self->min_bytes )
40             and ( $length < $self->max_bytes )
41             and ( $res->code == 200 )
42             and ( not $res->headers->header('Content-Encoding'))
43             and ( $res->headers->content_type =~ qr{^text|xml$|javascript$|^application/json$} )
44             ) {
45 1         3 return undef;
46             }
47              
48 1 50       73 eval { local $/; $body = <$body> } if ref $body;
  0         0  
  0         0  
49 1 50       4 die "Response body is an unsupported kind of reference" if ref $body;
50              
51 1         5 my $zipped = gzip $body;
52              
53 1         2457 $res->content( Mojo::Content::Single->new );
54 1         45 $res->body( $zipped );
55 1         41 $res->fix_headers;
56 1         243 $res->headers->header( 'Content-Length' => length $zipped );
57 1         37 $res->headers->header( 'Content-Encoding' => 'gzip' );
58 1         29 $res->headers->add( 'Vary' => 'Accept-Encoding' );
59              
60 1         18 return 1;
61             }
62              
63             1;
64              
65             =pod
66              
67             =encoding UTF-8
68              
69             =head1 NAME
70              
71             MojoX::Encode::Gzip - Gzip a Mojo::Message::Response
72              
73             =head1 VERSION
74              
75             version 1.13
76              
77             =head1 SYNOPSIS
78              
79             use MojoX:Encode::Gzip;
80              
81             # Simple
82             MojoX::Encode::Gzip->new->maybe_gzip($tx);
83              
84             # With options
85             my $gzip = MojoX::Encode::Gzip->new(
86             min_bytes => 600,
87             max_bytes => 600000,
88             );
89             $success = $gzip->maybe_gzip($tx);
90              
91             =head1 DESCRIPTION
92              
93             Gzip compress a Mojo::Message::Response if client supports it.
94              
95             =head2 ATTRIBUTES
96              
97             =head2 C
98              
99             The minumum number of bytes in the body before we would try to gzip it. Trying to gzip really
100             small messages can take extra CPU power on the server and client without saving any times. Defaults
101             to 500.
102              
103             =head2 C
104              
105             The maximum number of bytes in the body before we give up on trying gzip it. Gzipping very large messages
106             can delay the response and possibly exhaust system resources. Defaults to 500000.
107              
108             =head1 METHODS
109              
110             =head2 C
111              
112             my $success = $gzip->maybe_gzip($tx);
113              
114             Given a L object, possibly gzips transforms the response by
115             gzipping it. Returns true if we gzip it, and undef otherwise. The behavior is
116             modified by the C<< min_bytes >> and C<< max_bytes >> attributes.
117              
118             Currently we only only try to gzip Content-types that start with "text/", or end in "xml" or "javascript",
119             along with "application/json". This may be configurable in the future.
120              
121             =head1 SUPPORT
122              
123             You can find documentation for this module with the perldoc command.
124              
125             perldoc MojoX::Encode::Gzip
126              
127             =head1 CODE REPOSITORY AND BUGTRACKER
128              
129             The code repository and a bugtracker are available at L.
130              
131             =head1 ACKNOWLEDGEMENTS
132              
133             Inspired by Catalyst::Plugin::Compress::Gzip
134              
135             =head1 PREVIOUS MAINTAINERS
136              
137             =over 4
138              
139             =item * 2008-2015 Mark Stosberg
140              
141             =back
142              
143             =head1 AUTHOR
144              
145             Renee Baecker
146              
147             =head1 COPYRIGHT AND LICENSE
148              
149             This software is copyright (c) 2018 by Renee Baecker.
150              
151             This is free software; you can redistribute it and/or modify it under
152             the same terms as the Perl 5 programming language system itself.
153              
154             =cut
155              
156             __END__