File Coverage

blib/lib/CGI/Fast.pm
Criterion Covered Total %
statement 53 53 100.0
branch 18 20 90.0
condition 21 29 72.4
subroutine 13 13 100.0
pod 1 3 33.3
total 106 118 89.8


line stmt bran cond sub pod time code
1             package CGI::Fast;
2 6     6   340886 use strict;
  6         53  
  6         182  
3 6     6   30 use warnings;
  6         10  
  6         311  
4 6     6   4232 use if $] >= 5.019, 'deprecate';
  6         80  
  6         33  
5              
6             $CGI::Fast::VERSION='2.14';
7              
8 6     6   11417 use CGI;
  6         182666  
  6         36  
9 6     6   4124 use CGI::Carp;
  6         16165  
  6         39  
10 6     6   2751 use FCGI;
  6         4943  
  6         228  
11             # use vars works like "our", but is compatible with older Perls.
12 6         766 use vars qw(
13             @ISA
14             $ignore
15 6     6   41 );
  6         15  
16             @ISA = ('CGI');
17              
18             # workaround for known bug in libfcgi
19             while (($ignore) = each %ENV) { }
20              
21             # override the initialization behavior so that
22             # state is NOT maintained between invocations
23       11 0   sub save_request {
24             # no-op
25             }
26              
27             # If ENV{FCGI_SOCKET_PATH} is specified, we maintain a FCGI Request handle
28             # in this package variable.
29 6     6   39 use vars qw($Ext_Request $socket $socket_perm $queue);
  6         12  
  6         3768  
30              
31             sub import {
32 10     10   8475 my ($package,@import) = @_;
33             # check imports for this class then pass on
34             # imports to SUPER class
35 10         48 for (my $i = 0; $i < scalar( @import ); $i++) {
36 14 100       68 if ( $import[$i] eq 'socket_path' ) {
    100          
    100          
37 3         13 $socket = $import[$i+1];
38             } elsif ( $import[$i] eq 'socket_perm' ) {
39 2         5 $socket_perm = $import[$i+1];
40             } elsif ( $import[$i] eq 'listen_queue' ) {
41 1         3 $queue = $import[$i+1];
42             }
43             }
44 10         67 $package->SUPER::import(@import);
45             }
46              
47             sub _create_fcgi_request {
48 7     7   21 my ( $in_fh,$out_fh,$err_fh ) = @_;
49             # If we have a socket set, explicitly open it
50 7 100 66     63 if ($ENV{FCGI_SOCKET_PATH} or $socket) {
51 4   33     18 my $path = $ENV{FCGI_SOCKET_PATH} || $socket;
52 4   100     17 my $perm = $ENV{FCGI_SOCKET_PERM} || $socket_perm;
53 4   50     23 my $backlog = $ENV{FCGI_LISTEN_QUEUE} || $queue || 100;
54 4         220 my $socket = FCGI::OpenSocket( $path, $backlog );
55 4 100 100     34 if ($path !~ /^:/ && defined $perm) {
56 2 50       38 chmod $perm, $path or croak( "Couldn't chmod($path): $!" );
57             }
58 4   50     63 return FCGI::Request(
      50        
      50        
59             ( $in_fh || \*STDIN ),
60             ( $out_fh || \*STDOUT ),
61             ( $err_fh || \*STDERR ),
62             \%ENV,
63             $socket,
64             1
65             );
66             }
67             else {
68 3   100     38 return FCGI::Request(
      100        
      100        
69             ( $in_fh || \*STDIN ),
70             ( $out_fh || \*STDOUT ),
71             ( $err_fh || \*STDERR ),
72             );
73             }
74             }
75              
76             {
77             my ( $in_fh,$out_fh,$err_fh );
78              
79             sub file_handles {
80 1     1 0 164 my ($self, $handles) = @_;
81              
82 1 50       5 if ( ref( $handles ) eq 'HASH' ) {
83 1         3 $in_fh = delete( $handles->{fcgi_input_file_handle} );
84 1         3 $out_fh = delete( $handles->{fcgi_output_file_handle} );
85 1         17 $err_fh = delete( $handles->{fcgi_error_file_handle} );
86             }
87             }
88              
89             sub new {
90 14     14 1 15226 my ($self, $initializer, @param) = @_;
91              
92 14 100       51 if ( ! defined $initializer ) {
93 12   66     80 $Ext_Request ||= _create_fcgi_request( $in_fh,$out_fh,$err_fh );
94 12 100       3279 return undef unless $Ext_Request->Accept >= 0;
95             }
96 13         612 CGI->_reset_globals;
97 13 100       460 $self->_setup_symbols(@CGI::SAVED_SYMBOLS) if @CGI::SAVED_SYMBOLS;
98 13         604 return $CGI::Q = $self->SUPER::new($initializer, @param);
99             }
100             }
101              
102             1;
103              
104             =head1 NAME
105              
106             CGI::Fast - CGI Interface for Fast CGI
107              
108             =for html
109             Build Status
110             Coverage Status
111              
112             =head1 SYNOPSIS
113              
114             use CGI::Fast
115             socket_path => '9000',
116             socket_perm => 0777,
117             listen_queue => 50;
118              
119             use CGI qw/ :standard /;
120              
121             $COUNTER = 0;
122              
123             # optional, will default to STDOUT, STDERR
124             CGI::Fast->file_handles({
125             fcgi_output_file_handle => IO::Handle->new,
126             fcgi_error_file_handle => IO::Handle->new,
127             });
128              
129             while ($q = CGI::Fast->new) {
130             process_request($q);
131             }
132              
133             =head1 DESCRIPTION
134              
135             CGI::Fast is a subclass of the CGI object created by CGI.pm. It is
136             specialized to work with the FCGI module, which greatly speeds up CGI
137             scripts by turning them into persistently running server processes.
138             Scripts that perform time-consuming initialization processes, such as
139             loading large modules or opening persistent database connections, will
140             see large performance improvements.
141              
142             Note that as CGI::Fast is based on CGI.pm it is no longer advised as
143             a way to write Perl web apps. See L
144             for more information about this
145              
146             =head1 OTHER PIECES OF THE PUZZLE
147              
148             In order to use CGI::Fast you'll need the FCGI module. See
149             http://www.cpan.org/ for details.
150              
151             =head1 WRITING FASTCGI PERL SCRIPTS
152              
153             FastCGI scripts are persistent: one or more copies of the script
154             are started up when the server initializes, and stay around until
155             the server exits or they die a natural death. After performing
156             whatever one-time initialization it needs, the script enters a
157             loop waiting for incoming connections, processing the request, and
158             waiting some more.
159              
160             A typical FastCGI script will look like this:
161              
162             #!perl
163             use CGI::Fast;
164             do_some_initialization();
165             while ($q = CGI::Fast->new) {
166             process_request($q);
167             }
168              
169             Each time there's a new request, CGI::Fast returns a
170             CGI object to your loop. The rest of the time your script
171             waits in the call to new(). When the server requests that
172             your script be terminated, new() will return undef. You can
173             of course exit earlier if you choose. A new version of the
174             script will be respawned to take its place (this may be
175             necessary in order to avoid Perl memory leaks in long-running
176             scripts).
177              
178             CGI.pm's default CGI object mode also works. Just modify the loop
179             this way:
180              
181             while (CGI::Fast->new) {
182             process_request();
183             }
184              
185             Calls to header(), start_form(), etc. will all operate on the
186             current request.
187              
188             =head1 INSTALLING FASTCGI SCRIPTS
189              
190             See the FastCGI developer's kit documentation for full details. On
191             the Apache server, the following line must be added to srm.conf:
192              
193             AddType application/x-httpd-fcgi .fcgi
194              
195             FastCGI scripts must end in the extension .fcgi. For each script you
196             install, you must add something like the following to srm.conf:
197              
198             FastCgiServer /usr/etc/httpd/fcgi-bin/file_upload.fcgi -processes 2
199              
200             This instructs Apache to launch two copies of file_upload.fcgi at
201             startup time.
202              
203             =head1 USING FASTCGI SCRIPTS AS CGI SCRIPTS
204              
205             Any script that works correctly as a FastCGI script will also work
206             correctly when installed as a vanilla CGI script. However it will
207             not see any performance benefit.
208              
209             =head1 EXTERNAL FASTCGI SERVER INVOCATION
210              
211             FastCGI supports a TCP/IP transport mechanism which allows FastCGI scripts to run
212             external to the webserver, perhaps on a remote machine. To configure the
213             webserver to connect to an external FastCGI server, you would add the following
214             to your srm.conf:
215              
216             FastCgiExternalServer /usr/etc/httpd/fcgi-bin/file_upload.fcgi -host sputnik:8888
217              
218             Two environment variables affect how the C object is created,
219             allowing C to be used as an external FastCGI server. (See C
220             documentation for C for more information.)
221              
222             You can set these as ENV variables or imports in the use CGI::Fast statement.
223             If the ENV variables are set then these will be favoured so you can override
224             the import statements on the command line, etc.
225              
226             =over
227              
228             =item FCGI_SOCKET_PATH / socket_path
229              
230             The address (TCP/IP) or path (UNIX Domain) of the socket the external FastCGI
231             script to which bind an listen for incoming connections from the web server.
232              
233             =item FCGI_SOCKET_PERM / socket_perm
234              
235             Permissions for UNIX Domain socket.
236              
237             =item FCGI_LISTEN_QUEUE / listen_queue
238              
239             Maximum length of the queue of pending connections, defaults to 100.
240              
241             =back
242              
243             For example:
244              
245             use CGI::Fast
246             socket_path => "sputnik:8888",
247             listen_queue => "50"
248             ;
249              
250             use CGI qw/ :standard /;
251              
252             do_some_initialization();
253              
254             while ($q = CGI::Fast->new) {
255             process_request($q);
256             }
257              
258              
259             Or:
260              
261             use CGI::Fast;
262             use CGI qw/ :standard /;
263              
264             do_some_initialization();
265              
266             $ENV{FCGI_SOCKET_PATH} = "sputnik:8888";
267             $ENV{FCGI_LISTEN_QUEUE} = 50;
268              
269             while ($q = CGI::Fast->new) {
270             process_request($q);
271             }
272              
273             Note the importance of having use CGI after use CGI::Fast as this will
274             prevent any CGI import pragmas being overwritten by CGI::Fast. You can
275             use CGI::Fast as a drop in replacement like so:
276              
277             use CGI::Fast qw/ :standard /
278              
279             =head1 FILE HANDLES
280              
281             FCGI defaults to using STDOUT and STDERR as its output filehandles - this
282             may lead to unexpected redirect of output if you migrate scripts from CGI.pm
283             to CGI::Fast. To get around this you can use the file_handles method, which
284             you must do B the first call to CGI::Fast->new. For example using
285             IO::Handle:
286              
287             CGI::Fast->file_handles({
288             fcgi_output_file_handle => IO::Handle->new,
289             fcgi_error_file_handle => IO::Handle->new,
290             });
291              
292             while (CGI::Fast->new) {
293             ..
294             }
295              
296             Overriding STDIN using the C key is also possible,
297             however doing so is likely to break at least POST requests.
298              
299             =head1 CAVEATS
300              
301             I haven't tested this very much.
302              
303             =head1 LICENSE
304              
305             Copyright 1996-1998, Lincoln D. Stein. All rights reserved. Currently
306             maintained by Lee Johnson
307              
308             This library is free software; you can redistribute it and/or modify
309             it under the same terms as Perl itself.
310              
311             Address bug reports and comments to:
312              
313             https://github.com/leejo/cgi-fast
314              
315             =head1 BUGS
316              
317             This section intentionally left blank.
318              
319             =head1 SEE ALSO
320              
321             L, L
322              
323             =cut