.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "CGI::Compress::Gzip 3pm" .TH CGI::Compress::Gzip 3pm "2021-01-07" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" CGI::Compress::Gzip \- CGI with automatically compressed output .SH "LICENSE" .IX Header "LICENSE" Copyright 2006\-2007 Clotho Advanced Media, Inc., .PP Copyright 2007\-2008 Chris Dolan .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use CGI::Compress::Gzip; \& \& my $cgi = new CGI::Compress::Gzip; \& print $cgi\->header(); \& print " ..."; .Ve .PP See the \s-1CAVEATS\s0 section below! .SH "DESCRIPTION" .IX Header "DESCRIPTION" CGI::Compress::Gzip extends the \s-1CGI\s0 module to auto-detect whether the client browser wants compressed output and, if so and if the script chooses \s-1HTML\s0 output, apply gzip compression on any content header for \&\s-1STDOUT.\s0 This module is intended to be a drop-in replacement for \&\s-1CGI\s0.pm. .PP Apache mod_perl users may wish to consider the Apache::Compress or Apache::GzipChain modules, which allow more transparent output compression than this module can provide. However, as of this writing those modules are more aggressive about compressing, regardless of Content-Type. .SS "Headers" .IX Subsection "Headers" At the time that a header is requested, CGI::Compress::Gzip checks the \&\s-1HTTP_ACCEPT_ENCODING\s0 environment variable (passed by Apache). If this variable includes the flag \*(L"gzip\*(R" and the outgoing mime-type is \&\*(L"text/*\*(R", then gzipped output is preferred. [the default mime-type selection of text/* can be changed by subclassing \*(-- see below] The header is altered to add the \*(L"Content-Encoding: gzip\*(R" flag which indicates that compression is turned on. .PP Naturally, it is crucial that the \s-1CGI\s0 application output nothing before the header is printed. If this is violated, things will go badly. .SS "Compression" .IX Subsection "Compression" When the header is created, this module sets up a new filehandle to accept data. \s-1STDOUT\s0 is redirected through that filehandle. The new filehandle passes data verbatim until it detects the end of the \s-1CGI\s0 header. At that time, it switches over to Gzip output for the remainder of the \s-1CGI\s0 run. .PP Note that the Zlib library on which this code is ultimately based requires a fileno for the output filehandle. Where the output filehandle is faked (i.e. in mod_perl), we instead use in-memory compression. This is more wasteful of \s-1RAM,\s0 but it is the only solution I've found (and it is one shared by the Apache::* compression modules). .PP Debugging note: if you set \fB\f(CB$CGI::Compress::Gzip::global_give_reason\fB\fR to a true value, then this module will add an \s-1HTTP\s0 header entry called \&\fBX\-non-gzip-reason\fR with an explanation of why it chose not to gzip the output stream. .SS "Buffering" .IX Subsection "Buffering" The Zlib library introduces latencies. In some cases, this module may delay output until the \s-1CGI\s0 object is garbage collected, presumably at the end of the program. This buffering can be detrimental to long-lived programs which are supposed to have incremental output, causing browser timeouts. To compensate, compression is automatically disabled when autoflush (i.e. the $| variable) is set to true. Future versions may try to enable autoflushing on the Zlib filehandles, if possible [Help wanted]. .SH "CLASS METHODS" .IX Header "CLASS METHODS" .ie n .IP "$pkg\->new([\s-1CGI ARGS\s0])" 4 .el .IP "\f(CW$pkg\fR\->new([\s-1CGI ARGS\s0])" 4 .IX Item "$pkg->new([CGI ARGS])" Create a new object. This resets the environment before creating a \&\s-1CGI\s0.pm object. This should not be called more than once per script run! All arguments are passed to the parent class. .ie n .IP "$pkg\->useCompression($boolean)" 4 .el .IP "\f(CW$pkg\fR\->useCompression($boolean)" 4 .IX Item "$pkg->useCompression($boolean)" .PD 0 .ie n .IP "$self\->useCompression($boolean)" 4 .el .IP "\f(CW$self\fR\->useCompression($boolean)" 4 .IX Item "$self->useCompression($boolean)" .PD This can be used as a class method or an instance method. The former is included for backward compatibility, and is \s-1NOT\s0 recommended. As a class method, this changes the default value. As an instance method it affects only the specified instance. .Sp Turn compression on/off for the target. If turned on, compression will be used only if the prerequisite compression libraries are available and if the client browser requests compression. .Sp Defaults to on. .SH "INSTANCE METHODS" .IX Header "INSTANCE METHODS" .ie n .IP "$self\->useFileHandle($filehandle)" 4 .el .IP "\f(CW$self\fR\->useFileHandle($filehandle)" 4 .IX Item "$self->useFileHandle($filehandle)" Manually set the output filehandle. Because of limitations of Zlib, this \s-1MUST\s0 be a real filehandle (with valid results from \fBfileno()\fR) and not a pseudo filehandle like IO::String. .Sp If this is not set, \s-1STDOUT\s0 is used. .ie n .IP "$self\->isCompressibleType($content_type)" 4 .el .IP "\f(CW$self\fR\->isCompressibleType($content_type)" 4 .IX Item "$self->isCompressibleType($content_type)" Given a \s-1MIME\s0 type (with possible charset attached), return a boolean indicating if this media type is a good candidate for compression. This implementation is simply: .Sp .Vb 1 \& return $type =~ /^text\e//; .Ve .Sp Subclasses may wish to override this method to apply different criteria. .ie n .IP "$self\->header([\s-1HEADER ARGS\s0])" 4 .el .IP "\f(CW$self\fR\->header([\s-1HEADER ARGS\s0])" 4 .IX Item "$self->header([HEADER ARGS])" Overrides the \f(CW\*(C`header()\*(C'\fR method in \s-1CGI\s0. .Sp Return a \s-1CGI\s0 header with the compression flags set properly. Returns an empty string is a header has already been printed. .Sp This method engages the Gzip output by fiddling with the default output filehandle. All subsequent output via usual Perl \fBprint()\fR will be automatically gzipped except for this header (which must go out as plain text). .Sp Any arguments will be passed on to CGI::header. This method should \&\s-1NOT\s0 be called if you don't want your header or \s-1STDOUT\s0 to be fiddled with. .ie n .IP "$self\->\s-1\fBDESTROY\s0()\fR" 4 .el .IP "\f(CW$self\fR\->\s-1\fBDESTROY\s0()\fR" 4 .IX Item "$self->DESTROY()" Override the \s-1CGI\s0 destructor so we can close the Gzip output stream, if there is one open. .SH "CAVEATS" .IX Header "CAVEATS" .SS "Apache::Registry" .IX Subsection "Apache::Registry" Under Apache::Registry, global variables may not go out of scope in time. This may causes timing bugs, since this module makes use of the \s-1\fBDESTROY\s0()\fR method. To avoid this issue, make sure your \s-1CGI\s0 object is stored in a scoped variable. .PP .Vb 5 \& # BROKEN CODE \& use CGI::Compress::Gzip; \& $q = CGI::Compress::Gzip\->new; \& print $q\->header; \& print "Hello, world\en"; \& \& # WORKAROUND CODE \& use CGI::Compress::Gzip; \& do { \& my $q = CGI::Compress::Gzip\->new; \& print $q\->header; \& print "Hello, world\en"; \& } .Ve .SS "Filehandles" .IX Subsection "Filehandles" This module works by changing the default filehandle. It does not change \s-1STDOUT\s0 at all. As a consequence, your programs should call \&\f(CW\*(C`print\*(C'\fR without a filehandle argument. .PP .Vb 5 \& # BROKEN CODE \& use CGI::Compress::Gzip; \& my $q = CGI::Compress::Gzip\->new; \& print STDOUT $q\->header; \& print STDOUT "Hello, world\en"; \& \& # WORKAROUND CODE \& use CGI::Compress::Gzip; \& my $q = CGI::Compress::Gzip\->new; \& print $q\->header; \& print "Hello, world\en"; .Ve .PP Future versions may steal away \s-1STDOUT\s0 and replace it with the compression filehandle, but that seemed too risky for this version. .SS "Header Munging" .IX Subsection "Header Munging" When sending compressed output, the \s-1HTTP\s0 headers must remain uncompressed. So, this module goes to great effort to keep the headers and body separate. That has led to \fBCGI::header()\fR emulation code that is a little brittle. Most potential problems arise because \&\s-1STDOUT\s0 gets tweaked as soon as \fBheader()\fR is called. .PP If you use the \s-1CGI\s0.pm \fBheader()\fR \s-1API\s0 as specified in \s-1CGI\s0.pm, then all should go well. But if you do anything unusual, this module may break. For example: .PP .Vb 5 \& # BROKEN CODE \& use CGI::Compress::Gzip; \& my $q = CGI::Compress::Gzip\->new; \& print "Set\-Cookie: foo=bar\en" . $q\->header; \& print "Hello, world\en"; \& \& # WORKAROUND 1 (preferred) \& use CGI::Compress::Gzip; \& my $q = CGI::Compress::Gzip\->new; \& print $q\->header("\-Set_Cookie" => "foo=bar"); \& print "Hello, world\en"; \& \& # WORKAROUND 2 \& use CGI::Compress::Gzip; \& my $q = CGI::Compress::Gzip\->new; \& print "Set\-Cookie: foo=bar\en"; \& print $q\->header; \& print "Hello, world\en"; .Ve .PP Future versions could try to parse the header to look for its end rather than insisting that the printed version match the version returned by \&\fBheader()\fR. Patches would be very welcome. .SH "SEE ALSO" .IX Header "SEE ALSO" CGI::Compress::Gzip depends on \s-1CGI\s0 and IO::Zlib. Similar functionality is available from mod_gzip, Apache::Compress or Apache::GzipChain, however all of those require changes to the webserver configuration. .SH "AUTHOR" .IX Header "AUTHOR" Chris Dolan .PP This module was originally developed by me at Clotho Advanced Media Inc. Now I maintain it in my spare time. .SH "ACKNOWLEDGMENTS" .IX Header "ACKNOWLEDGMENTS" Clotho greatly appreciates the assistance and feedback the community has extended to help refine this module. .PP Thanks to Rhesa Rozendaal who noticed the \-Type omission in v0.17. .PP Thanks to Laga Mahesa who did some Windows testing and experimentation. .PP Thanks to Slaven Rezic who 1) found several header handling bugs, 2) discovered the Apache::Registry and Filehandle caveats, 3) provided a patch incorporated into v0.17, and 4) persisted with smoke tests that reproduced the envvar problem fixed in v0.23. .PP Thanks to Jan Willamowius who found a header handling bug. .PP Thanks to Andreas J. Koenig and brian d foy for module naming advice. .SH "HELP WANTED" .IX Header "HELP WANTED" If you like this module, please help by testing on Windows or in a \&\f(CW\*(C`FastCGI\*(C'\fR environment, since I have neither available for easy testing. .PP Personally, I don't use this module much anymore as all of my work is on Catalyst and mod_perl now.