File Coverage

blib/lib/CGI/Fast.pm
Criterion Covered Total %
statement 48 48 100.0
branch 18 20 90.0
condition 33 41 80.4
subroutine 11 11 100.0
pod 1 3 33.3
total 111 123 90.2


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