2 use ExtUtils::MakeMaker;
4 do 'FCGI.cfg' or die "no FCGI.cfg";
8 print "Generating FCGI.pm\n";
10 # $Id: FCGI.PL,v 1.37 2002/12/15 20:02:48 skimo Exp $
17 @ISA = qw(Exporter DynaLoader);
18 # Items to export into callers namespace by default. Note: do not export
19 # names by default without a very good reason. Use EXPORT_OK instead.
20 # Do not simply export all your public functions/methods/constants.
27 print OUT '$VERSION = q{'.MM->parse_version('version.pm')."};\n\n";
29 print OUT "bootstrap FCGI;\n" unless ($pure);
31 print OUT '$VERSION = eval $VERSION;';
33 print OUT <<'EOP' if ($pure);
37 use constant VERSION_1 => 1;
39 use constant BEGIN_REQUEST => 1;
40 use constant PARAMS => 4;
41 use constant FCGI_STDIN => 5;
42 use constant FCGI_STDOUT => 6;
43 use constant FCGI_STDERR => 7;
45 use constant RESPONDER => 1;
46 use constant AUTHORIZER => 2;
47 use constant FILTER => 3;
49 %FCGI::rolenames = (RESPONDER, "RESPONDER",
50 AUTHORIZER, "AUTHORIZER",
54 # This only works on Unix; anyone familiar with Windows is welcome
59 (!defined getpeername shift->{listen_sock}) && $! == ENOTCONN
60 unless exists $req->{isfastcgi};
61 return $req->{isfastcgi};
65 return shift->{'env'};
71 return undef unless read $stream, $buf, 1, 0;
72 my ($len) = unpack("C", $buf);
74 $buf = pack("C", $len & 0x7F);
75 return undef unless read $stream, $buf, 3, 1;
76 $len = unpack("N", $buf);
91 open $self->{listen_sock}, "<&=0";
100 unless ($req->IsFastCGI()) {
101 return -1 if $run_once;
107 $req->{socket} = gensym();
108 if ($req->{last} || !accept($req->{socket}, $req->{listen_sock})) {
109 $req->{error} = "accept";
112 my ($type, $id, $body) = $req->read_record();
113 if ($type != BEGIN_REQUEST) {
114 $req->{error} = "begin request";
117 my ($role, $flags) = unpack("nC", $body);
118 $req->{role} = $role;
119 $req->{flags} = $flags;
123 $req->{env}{FCGI_ROLE} = $FCGI::rolenames{$req->{role}};
124 my $param = FCGI::Stream->new($req, PARAMS);
126 while (defined($nlen = read_nv_len($param)) &&
127 defined($vlen = read_nv_len($param)))
130 read $param, $name, $nlen;
131 read $param, $val, $vlen;
132 $req->{env}{$name} = $val;
135 $req->{accepted} = 1;
143 untie ${$req->{out}};
144 untie ${$req->{err}};
150 tie ${$req->{in}}, 'FCGI::Stream', $req, FCGI_STDIN;
151 tie ${$req->{out}}, 'FCGI::Stream', $req, FCGI_STDOUT;
152 tie ${$req->{err}}, 'FCGI::Stream', $req, FCGI_STDERR;
158 $req->Bind() if ($req->{accepted} && !$req->{bound});
163 $req->UndoBindings() if ($req->{accepted} && $req->{bound});
168 return unless $req->{accepted};
170 $req->UndoBindings();
171 # apparently these are harmful
172 # close ${$req->{out}};
173 # close ${$req->{err}};
175 $req->{accepted} = 0;
190 read($self->{socket}, $header, 8);
191 my ($version, $type, $id, $clen, $plen) = unpack("CCnnC", $header);
192 read($self->{socket}, $body, $clen+$plen);
193 $body = undef if $clen == 0;
198 my ($self, $rtype, $len) = @_;
199 while (length $self->{buf} < $len) {
200 my ($type, $id, $buf) = $self->read_record();
201 return undef unless defined $buf;
202 if ($type != $rtype) {
203 $self->{error} = "unexpected stream type";
206 $self->{buf} .= $buf;
208 my ($newbuf, $result) = (substr($self->{buf}, $len),
209 substr($self->{buf}, 0, $len));
210 $self->{buf} = $newbuf;
219 my ($self, $type, $content, $len) = @_;
220 return unless $len > 0;
221 $self->write_record($type, $content, $len);
225 my ($self, $type, $content, $length) = @_;
227 while ($length > 0) {
228 my $len = $length > 32*1024 ? 32*1024 : $length;
229 my $padlen = (8 - ($len % 8)) % 8;
230 my $templ = "CCnnCxa${len}x$padlen";
231 my $data = pack($templ,
232 VERSION_1, $type, $self->{id}, $len, $padlen,
233 substr($content, $offset, $len));
234 syswrite $self->{socket}, $data;
240 { package FCGI::Stream;
243 my ($class, $src, $type) = @_;
244 my $handle = do { \local *FH };
245 tie($$handle, $class, $src, $type);
250 my ($class, $src, $type) = @_;
251 bless { src => $src, type => $type }, $class;
255 my ($stream, undef, $len, $offset) = @_;
257 my $buf = $stream->{src}->read($stream->{type}, $len);
258 return undef unless defined $buf;
259 substr($$ref, $offset, 0, $buf);
264 my ($stream) = shift;
266 $stream->{src}->write($stream->{type}, $_, length($_));
273 $stream->{src}->write_record($stream->{type}, undef, 0);
279 print OUT while <DATA>;
283 # Preloaded methods go here.
285 # Autoload methods go after __END__, and are processed by the autosplit program.
287 *FAIL_ACCEPT_ON_INTR = sub() { 1 };
289 sub Request(;***$*$) {
290 my @defaults = (\*STDIN, \*STDOUT, \*STDERR, \%ENV, 0, FAIL_ACCEPT_ON_INTR());
291 $_[4] = fileno($_[4]) if defined($_[4]) && defined(fileno($_[4]));
292 splice @defaults,0,@_,@_;
296 package FCGI::Stream;
299 shift->PRINT(sprintf(shift, @_));
308 my $rs = $/ eq '' ? "\n\n" : $/;
309 my $l = substr $rs, -1;
310 my $len = length $rs;
312 $c = $stream->GETC();
315 $c = $stream->GETC();
320 last if $c eq $l and substr($s, -$len) eq $rs;
321 $c = $stream->GETC();
329 return open($_[0], $_[1]);
332 eval("$rc = open($_[0], $_[1], $_[2])");
338 # Some things (e.g. IPC::Run) use fileno to determine if a filehandle is open,
339 # so we return a defined, but meaningless value. (-1 being the error return
340 # value from the syscall in c, meaning it can never be a valid fd no)
341 # Probably a better alternative would be to return the fcgi stream fd.
350 FCGI - Fast CGI module
357 my $request = FCGI::Request();
359 while($request->Accept() >= 0) {
360 print("Content-type: text/html\r\n\r\n", ++$count);
371 Creates a request handle. It has the following optional parameters:
375 =item input perl file handle (default: \*STDIN)
377 =item output perl file handle (default: \*STDOUT)
379 =item error perl file handle (default: \*STDERR)
381 These filehandles will be setup to act as input/output/error
382 on successful Accept.
384 =item environment hash reference (default: \%ENV)
386 The hash will be populated with the environment.
388 =item socket (default: 0)
390 Socket to communicate with the server.
391 Can be the result of the OpenSocket function.
392 For the moment, it's the file descriptor of the socket
393 that should be passed. This may change in the future.
395 You should only use your own socket if your program
396 is not started by a process manager such as mod_fastcgi
397 (except for the FastCgiExternalServer case) or cgi-fcgi.
398 If you use the option, you have to let your FastCGI
399 server know which port (and possibly server) your program
401 See remote.pl for an example.
403 =item flags (default: 0)
409 =item FCGI::FAIL_ACCEPT_ON_INTR
411 If set, Accept will fail if interrupted.
412 It not set, it will just keep on waiting.
419 my $req = FCGI::Request;
423 my $in = new IO::Handle;
424 my $out = new IO::Handle;
425 my $err = new IO::Handle;
426 my $req = FCGI::Request($in, $out, $err, \%env);
428 =item FCGI::OpenSocket(path, backlog)
430 Creates a socket suitable to use as an argument to Request.
436 Pathname of socket or colon followed by local tcp port.
437 Note that some systems take file permissions into account
438 on Unix domain sockets, so you'll have to make sure that
439 the server can write to the created file, by changing
440 the umask before the call and/or changing permissions and/or
441 group of the file afterwards.
445 Maximum length of the queue of pending connections.
447 request arrives with the queue full the client may receive
448 an error with an indication of ECONNREFUSED.
452 =item FCGI::CloseSocket(socket)
454 Close a socket opened with OpenSocket.
458 Accepts a connection on $req, attaching the filehandles and
459 populating the environment hash.
460 Returns 0 on success.
461 If a connection has been accepted before, the old
462 one will be finished first.
464 Note that unlike with the old interface, no die and warn
465 handlers are installed by default. This means that if
466 you are not running an sfio enabled perl, any warn or
467 die message will not end up in the server's log by default.
468 It is advised you set up die and warn handlers yourself.
469 FCGI.pm contains an example of die and warn handlers.
473 Finishes accepted connection.
474 Also detaches filehandles.
478 Flushes accepted connection.
482 Temporarily detaches filehandles on an accepted connection.
486 Re-attaches filehandles on an accepted connection.
488 =item $req->LastCall()
490 Tells the library not to accept any more requests on this handle.
491 It should be safe to call this method from signal handlers.
493 Note that this method is still experimental and everything
494 about it, including its name, is subject to change.
496 =item $env = $req->GetEnvironment()
498 Returns the environment parameter passed to FCGI::Request.
500 =item ($in, $out, $err) = $req->GetHandles()
502 Returns the file handle parameters passed to FCGI::Request.
504 =item $isfcgi = $req->IsFastCGI()
506 Returns whether or not the program was run as a FastCGI.
512 FCGI.pm isn't Unicode aware, only characters within the range 0x00-0xFF are
513 supported. Attempts to output strings containing characters above 0xFF results
514 in a exception: (F) C<Wide character in %s>.
516 Users who wants the previous (FCGI.pm <= 0.68) incorrect behavior can disable the
517 exception by using the C<bytes> pragma.
527 Sven Verdoolaege <skimo@kotnet.org>