| 1 | package CGI::Fast; |
| 2 | |
| 3 | # See the bottom of this file for the POD documentation. Search for the |
| 4 | # string '=head'. |
| 5 | |
| 6 | # You can run this file through either pod2man or pod2html to produce pretty |
| 7 | # documentation in manual or html file format (these utilities are part of the |
| 8 | # Perl 5 distribution). |
| 9 | |
| 10 | # Copyright 1995,1996, Lincoln D. Stein. All rights reserved. |
| 11 | # It may be used and modified freely, but I do request that this copyright |
| 12 | # notice remain attached to the file. You may modify this module as you |
| 13 | # wish, but if you redistribute a modified version, please attach a note |
| 14 | # listing the modifications you have made. |
| 15 | |
| 16 | # The most recent version and complete docs are available at: |
| 17 | # http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html |
| 18 | # ftp://ftp-genome.wi.mit.edu/pub/software/WWW/ |
| 19 | $CGI::Fast::VERSION='1.05'; |
| 20 | |
| 21 | use CGI; |
| 22 | use FCGI; |
| 23 | @ISA = ('CGI'); |
| 24 | |
| 25 | # workaround for known bug in libfcgi |
| 26 | while (($ignore) = each %ENV) { } |
| 27 | |
| 28 | # override the initialization behavior so that |
| 29 | # state is NOT maintained between invocations |
| 30 | sub save_request { |
| 31 | # no-op |
| 32 | } |
| 33 | |
| 34 | # If ENV{FCGI_SOCKET_PATH} is specified, we maintain a FCGI Request handle |
| 35 | # in this package variable. |
| 36 | use vars qw($Ext_Request); |
| 37 | BEGIN { |
| 38 | # If ENV{FCGI_SOCKET_PATH} is given, explicitly open the socket, |
| 39 | # and keep the request handle around from which to call Accept(). |
| 40 | if ($ENV{FCGI_SOCKET_PATH}) { |
| 41 | my $path = $ENV{FCGI_SOCKET_PATH}; |
| 42 | my $backlog = $ENV{FCGI_LISTEN_QUEUE} || 100; |
| 43 | my $socket = FCGI::OpenSocket( $path, $backlog ); |
| 44 | $Ext_Request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, |
| 45 | \%ENV, $socket, 1 ); |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | # New is slightly different in that it calls FCGI's |
| 50 | # accept() method. |
| 51 | sub new { |
| 52 | my ($self, $initializer, @param) = @_; |
| 53 | unless (defined $initializer) { |
| 54 | if ($Ext_Request) { |
| 55 | return undef unless $Ext_Request->Accept() >= 0; |
| 56 | } else { |
| 57 | return undef unless FCGI::accept() >= 0; |
| 58 | } |
| 59 | } |
| 60 | return $CGI::Q = $self->SUPER::new($initializer, @param); |
| 61 | } |
| 62 | |
| 63 | 1; |
| 64 | |
| 65 | =head1 NAME |
| 66 | |
| 67 | CGI::Fast - CGI Interface for Fast CGI |
| 68 | |
| 69 | =head1 SYNOPSIS |
| 70 | |
| 71 | use CGI::Fast qw(:standard); |
| 72 | $COUNTER = 0; |
| 73 | while (new CGI::Fast) { |
| 74 | print header; |
| 75 | print start_html("Fast CGI Rocks"); |
| 76 | print |
| 77 | h1("Fast CGI Rocks"), |
| 78 | "Invocation number ",b($COUNTER++), |
| 79 | " PID ",b($$),".", |
| 80 | hr; |
| 81 | print end_html; |
| 82 | } |
| 83 | |
| 84 | =head1 DESCRIPTION |
| 85 | |
| 86 | CGI::Fast is a subclass of the CGI object created by |
| 87 | CGI.pm. It is specialized to work well with the Open Market |
| 88 | FastCGI standard, which greatly speeds up CGI scripts by |
| 89 | turning them into persistently running server processes. Scripts |
| 90 | that perform time-consuming initialization processes, such as |
| 91 | loading large modules or opening persistent database connections, |
| 92 | will see large performance improvements. |
| 93 | |
| 94 | =head1 OTHER PIECES OF THE PUZZLE |
| 95 | |
| 96 | In order to use CGI::Fast you'll need a FastCGI-enabled Web |
| 97 | server. Open Market's server is FastCGI-savvy. There are also |
| 98 | freely redistributable FastCGI modules for NCSA httpd 1.5 and Apache. |
| 99 | FastCGI-enabling modules for Microsoft Internet Information Server and |
| 100 | Netscape Communications Server have been announced. |
| 101 | |
| 102 | In addition, you'll need a version of the Perl interpreter that has |
| 103 | been linked with the FastCGI I/O library. Precompiled binaries are |
| 104 | available for several platforms, including DEC Alpha, HP-UX and |
| 105 | SPARC/Solaris, or you can rebuild Perl from source with patches |
| 106 | provided in the FastCGI developer's kit. The FastCGI Perl interpreter |
| 107 | can be used in place of your normal Perl without ill consequences. |
| 108 | |
| 109 | You can find FastCGI modules for Apache and NCSA httpd, precompiled |
| 110 | Perl interpreters, and the FastCGI developer's kit all at URL: |
| 111 | |
| 112 | http://www.fastcgi.com/ |
| 113 | |
| 114 | =head1 WRITING FASTCGI PERL SCRIPTS |
| 115 | |
| 116 | FastCGI scripts are persistent: one or more copies of the script |
| 117 | are started up when the server initializes, and stay around until |
| 118 | the server exits or they die a natural death. After performing |
| 119 | whatever one-time initialization it needs, the script enters a |
| 120 | loop waiting for incoming connections, processing the request, and |
| 121 | waiting some more. |
| 122 | |
| 123 | A typical FastCGI script will look like this: |
| 124 | |
| 125 | #!/usr/local/bin/perl # must be a FastCGI version of perl! |
| 126 | use CGI::Fast; |
| 127 | &do_some_initialization(); |
| 128 | while ($q = new CGI::Fast) { |
| 129 | &process_request($q); |
| 130 | } |
| 131 | |
| 132 | Each time there's a new request, CGI::Fast returns a |
| 133 | CGI object to your loop. The rest of the time your script |
| 134 | waits in the call to new(). When the server requests that |
| 135 | your script be terminated, new() will return undef. You can |
| 136 | of course exit earlier if you choose. A new version of the |
| 137 | script will be respawned to take its place (this may be |
| 138 | necessary in order to avoid Perl memory leaks in long-running |
| 139 | scripts). |
| 140 | |
| 141 | CGI.pm's default CGI object mode also works. Just modify the loop |
| 142 | this way: |
| 143 | |
| 144 | while (new CGI::Fast) { |
| 145 | &process_request; |
| 146 | } |
| 147 | |
| 148 | Calls to header(), start_form(), etc. will all operate on the |
| 149 | current request. |
| 150 | |
| 151 | =head1 INSTALLING FASTCGI SCRIPTS |
| 152 | |
| 153 | See the FastCGI developer's kit documentation for full details. On |
| 154 | the Apache server, the following line must be added to srm.conf: |
| 155 | |
| 156 | AddType application/x-httpd-fcgi .fcgi |
| 157 | |
| 158 | FastCGI scripts must end in the extension .fcgi. For each script you |
| 159 | install, you must add something like the following to srm.conf: |
| 160 | |
| 161 | FastCgiServer /usr/etc/httpd/fcgi-bin/file_upload.fcgi -processes 2 |
| 162 | |
| 163 | This instructs Apache to launch two copies of file_upload.fcgi at |
| 164 | startup time. |
| 165 | |
| 166 | =head1 USING FASTCGI SCRIPTS AS CGI SCRIPTS |
| 167 | |
| 168 | Any script that works correctly as a FastCGI script will also work |
| 169 | correctly when installed as a vanilla CGI script. However it will |
| 170 | not see any performance benefit. |
| 171 | |
| 172 | =head1 EXTERNAL FASTCGI SERVER INVOCATION |
| 173 | |
| 174 | FastCGI supports a TCP/IP transport mechanism which allows FastCGI scripts to run |
| 175 | external to the webserver, perhaps on a remote machine. To configure the |
| 176 | webserver to connect to an external FastCGI server, you would add the following |
| 177 | to your srm.conf: |
| 178 | |
| 179 | FastCgiExternalServer /usr/etc/httpd/fcgi-bin/file_upload.fcgi -host sputnik:8888 |
| 180 | |
| 181 | Two environment variables affect how the C<CGI::Fast> object is created, |
| 182 | allowing C<CGI::Fast> to be used as an external FastCGI server. (See C<FCGI> |
| 183 | documentation for C<FCGI::OpenSocket> for more information.) |
| 184 | |
| 185 | =over |
| 186 | |
| 187 | =item FCGI_SOCKET_PATH |
| 188 | |
| 189 | The address (TCP/IP) or path (UNIX Domain) of the socket the external FastCGI |
| 190 | script to which bind an listen for incoming connections from the web server. |
| 191 | |
| 192 | =item FCGI_LISTEN_QUEUE |
| 193 | |
| 194 | Maximum length of the queue of pending connections. |
| 195 | |
| 196 | =back |
| 197 | |
| 198 | For example: |
| 199 | |
| 200 | #!/usr/local/bin/perl # must be a FastCGI version of perl! |
| 201 | use CGI::Fast; |
| 202 | &do_some_initialization(); |
| 203 | $ENV{FCGI_SOCKET_PATH} = "sputnik:8888"; |
| 204 | $ENV{FCGI_LISTEN_QUEUE} = 100; |
| 205 | while ($q = new CGI::Fast) { |
| 206 | &process_request($q); |
| 207 | } |
| 208 | |
| 209 | =head1 CAVEATS |
| 210 | |
| 211 | I haven't tested this very much. |
| 212 | |
| 213 | =head1 AUTHOR INFORMATION |
| 214 | |
| 215 | Copyright 1996-1998, Lincoln D. Stein. All rights reserved. |
| 216 | |
| 217 | This library is free software; you can redistribute it and/or modify |
| 218 | it under the same terms as Perl itself. |
| 219 | |
| 220 | Address bug reports and comments to: lstein@cshl.org |
| 221 | |
| 222 | =head1 BUGS |
| 223 | |
| 224 | This section intentionally left blank. |
| 225 | |
| 226 | =head1 SEE ALSO |
| 227 | |
| 228 | L<CGI::Carp>, L<CGI> |
| 229 | |
| 230 | =cut |