File Coverage

blib/lib/AnyEvent/SCGI.pm
Criterion Covered Total %
statement 33 44 75.0
branch 2 2 100.0
condition n/a
subroutine 8 12 66.6
pod 1 2 50.0
total 44 60 73.3


line stmt bran cond sub pod time code
1             package AnyEvent::SCGI;
2 2     2   159643 use strict;
  2         4  
  2         103  
3 2     2   9 use warnings;
  2         4  
  2         61  
4              
5 2     2   9 use AnyEvent;
  2         11  
  2         86  
6 2     2   1911 use AnyEvent::Socket;
  2         30736  
  2         260  
7 2     2   29 use AnyEvent::Handle;
  2         3  
  2         42  
8              
9 2     2   8 use base 'Exporter';
  2         4  
  2         828  
10             our @EXPORT = qw(scgi_server);
11              
12             =head1 NAME
13              
14             AnyEvent::SCGI - Event based SCGI server
15              
16             =cut
17              
18             our $VERSION = '1.1';
19              
20             =head1 SYNOPSIS
21              
22             A simple Hello World SCGI server running on port 22222:
23              
24             use AnyEvent::SCGI;
25             use HTTP::Headers;
26              
27             my $s = scgi_server '127.0.0.1', 22222, sub {
28             my $handle = shift;
29             my $env = shift;
30             my $content_ref = shift; # undef if none
31             my $fatal_error = shift;
32             my $error_string = shift;
33              
34             my $headers = HTTP::Headers->new(
35             'Status' => '200 OK',
36             'Content-Type' => 'text/plain',
37             'Connection' => 'close',
38             );
39              
40             $handle->push_write($headers->as_string . "\r\nHello World!\r\n");
41             $handle->push_shutdown;
42             }
43             AnyEvent->condvar->recv;
44              
45             =head1 DESCRIPTION
46              
47             Sets up a SCGI server on the specified port. Can be used with or without
48             C. You are responsible for any daemonization and startup code.
49              
50             The usual C callback caveats apply; make sure you don't block or
51             re-enter the event loop in a way that's not supported. This module has been
52             tested for use with C, but if you don't want to use that, it's
53             recommended that you return from the callback as quickly as possible.
54              
55             =head2 Using Coro
56              
57             If you're using Coro, here's the supported calling pattern:
58              
59             use Coro;
60             use Coro::AnyEvent;
61             use AnyEvent;
62             use AnyEvent::SCGI;
63              
64             my $s = scgi_server $server_name, $port, sub {
65             my $handle = shift;
66             my $env = shift;
67             my $content = shift;
68              
69             # handle errors if any
70              
71             async {
72             my $stuff = expensive($content);
73             $handle->push_write(
74             $headers->as_string .
75             "\r\nHello World!\r\n$stuff"
76             );
77             $handle->push_shutdown;
78             };
79             # return before running async block
80             };
81             AE::cv->recv;
82              
83             =head1 FUNCTIONS
84              
85             =head2 scgi_server $host, $port, $handler_cb
86              
87             This function creates a TCP socket on the given host and port by calling
88             C from C.
89              
90             Calls C<$handler_cb> when a valid SCGI request has been received. The
91             callback will block other clients until it returns.
92              
93             =head3 $handler_cb->($handle,\%env,\$content,$fatal,$error)
94              
95             The first parameter is the C If the request has a payload, a
96             reference to it is passed in as the C<$content> parameter.
97              
98             On error, C<\%env> and C<\$content> are undef and the usual C<$fatal> and
99             C<$error> parameters are passed in as subsequent arguments. On "EOF" from the
100             client, fatal is "0" and error is 'EOF'.
101              
102             =cut
103              
104             sub scgi_server($$$) {
105 0     0 1 0 my $host = shift;
106 0         0 my $port = shift;
107 0         0 my $cb = shift;
108 0     0   0 return tcp_server $host, $port, sub { handle_scgi(@_,$cb) };
  0         0  
109             }
110              
111             sub handle_scgi {
112 4     4 0 94755 my $fh = shift;
113 4         11 my $host = shift;
114 4         7 my $port = shift;
115 4         8 my $cb = shift;
116              
117 4         8 my $handle; $handle = AnyEvent::Handle->new(
118             fh => $fh,
119             on_error => sub {
120 0     0   0 shift;
121 0         0 my $fatal = shift;
122 0         0 my $error = shift;
123 0         0 $cb->($handle, undef, undef, $fatal, $error);
124             },
125             on_eof => sub {
126 0     0   0 shift;
127 0         0 $cb->($handle, undef, undef, 0, 'EOF');
128             },
129 4         43 );
130              
131             $handle->push_read (netstring => sub {
132 4     4   1746 shift;
133 4         9 my $env = shift;
134 4         48 my %env = split /\0/, $env;
135              
136 4 100       23 if ($env{CONTENT_LENGTH} == 0) {
137 2         9 $cb->($handle, \%env);
138             }
139             else {
140             $handle->push_read(chunk => $env{CONTENT_LENGTH}, sub {
141 2         75 $cb->($handle, \%env, \$_[1]);
142 2         16 });
143             }
144 4         439 });
145              
146 4         578 return;
147             }
148              
149             =head1 AUTHORS
150              
151             Jeremy Stashewsky
152              
153             Kevin Jones
154              
155              
156             =head1 BUGS
157              
158             Please report any bugs or feature requests to C, or through
159             the web interface at L. I will be notified, and then you'll
160             automatically be notified of progress on your bug as I make changes.
161              
162              
163             =head1 SUPPORT
164              
165             You can find documentation for this module with the perldoc command.
166              
167             perldoc AnyEvent::SCGI
168              
169              
170             You can also look for information at:
171              
172             =over 4
173              
174             =item * RT: CPAN's request tracker
175              
176             L
177              
178             =item * AnnoCPAN: Annotated CPAN documentation
179              
180             L
181              
182             =item * CPAN Ratings
183              
184             L
185              
186             =item * Search CPAN
187              
188             L
189              
190             =back
191              
192              
193             =head1 ACKNOWLEDGEMENTS
194              
195              
196             =head1 COPYRIGHT & LICENSE
197              
198             Copyright 2009 Jeremy Stashewsky
199             Copyright 2009 Kevin Jones
200              
201             Copyright 2009 Socialtext Inc., all rights reserved.
202              
203             This program is free software; you can redistribute it and/or modify it
204             under the same terms as Perl itself.
205              
206              
207             =cut
208              
209             1; # End of AnyEvent::SCGI