1POE::Component::Server:U:sHeTrTPC(o3n)tributed Perl DocuPmOeEn:t:aCtoimopnonent::Server::HTTP(3)
2
3
4
6 POE::Component::Server::HTTP - Foundation of a POE HTTP Daemon
7
9 use POE::Component::Server::HTTP;
10 use HTTP::Status;
11 my $aliases = POE::Component::Server::HTTP->new(
12 Port => 8000,
13 ContentHandler => {
14 '/' => \&handler1,
15 '/dir/' => sub { ... },
16 '/file' => sub { ... }
17 },
18 Headers => { Server => 'My Server' },
19 );
20
21 sub handler {
22 my ($request, $response) = @_;
23 $response->code(RC_OK);
24 $response->content("Hi, you fetched ". $request->uri);
25 return RC_OK;
26 }
27
28 POE::Kernel->call($aliases->{httpd}, "shutdown");
29 # next line isn't really needed
30 POE::Kernel->call($aliases->{tcp}, "shutdown");
31
33 POE::Component::Server::HTTP (PoCo::HTTPD) is a framework for building
34 custom HTTP servers based on POE. It is loosely modeled on the ideas of
35 apache and the mod_perl/Apache module.
36
37 It is built alot on work done by Gisle Aas on HTTP::* modules and the
38 URI module which are subclassed.
39
40 PoCo::HTTPD lets you register different handler, stacked by directory
41 that will be run during the cause of the request.
42
43 Handlers
44
45 Handlers are put on a stack in fifo order. The path
46 /foo/bar/baz/honk.txt will first push the handlers of / then of /foo/
47 then of /foo/bar/, then of /foo/bar/baz/, and lastly
48 /foo/bar/baz/honk.txt. Pay attention to directories! A request for
49 /honk will not match /honk/ as you are used to with apache. If you
50 want /honk to act like a directory, you should have a handler for /honk
51 which redirects to /honk/.
52
53 However, there can be only one ContentHandler and if any handler
54 installs a ContentHandler that will override the old ContentHandler.
55
56 If no handler installs a ContentHandler it will find the closest one
57 directory wise and use it.
58
59 There is also a special StreamHandler which is a coderef that gets
60 invoked if you have turned on streaming by doing $response->stream‐
61 ing(1);
62
63 Handlers take the $request and $response objects as arguments.
64
65 RC_OK
66 Everything is ok, please continue processing.
67
68 RC_DENY
69 If it is a TransHandler, stop translation handling and carry on
70 with a PreHandler, if it is a PostHandler do nothing, else return
71 denied to the client.
72
73 RC_WAIT
74 This is a special handler that suspends the execution of the han‐
75 dlers. They will be suspended until $response->continue() is
76 called, this is usefull if you want to do a long request and not
77 blocck.
78
79 The following handlers are available.
80
81 TransHandler
82 TransHandlers are run before the URI has been resolved, giving them
83 a chance to change the URI. They can therefore not be registred per
84 directory.
85
86 new(TransHandler => [ sub {return RC_OK} ]);
87
88 A TransHandler can stop the dispatching of TransHandlers and jump
89 to the next handler type by specifing RC_DENY;
90
91 PreHandler
92 PreHandlers are stacked by directory and run after TransHandler but
93 before the ContentHandler. They can change ContentHandler (but
94 beware, other PreHandlers might also change it) and push on
95 PostHandlers.
96
97 new(PreHandler => { '/' => [sub {}], '/foo/' => [\&foo]});
98
99 ContentHandler
100 The handler that is supposed to give the content. When this handler
101 returns it will send the response object to the client. It will
102 automaticly add Content-Length and Date if these are not set. If
103 the response is streaming it will make sure the correct headers are
104 set. It will also expand any cookies which have been pushed onto
105 the response object.
106
107 new(ContentHandler => { '/' => sub {}, '/foo/' => \&foo});
108
109 ErrorHandler
110 This handler is called when there is a read or write error on the
111 socket. This is most likely caused by the remote side closing the
112 connection. $resquest->is_error and $response->is_error will
113 return true. Note that "PostHanlder" will still called, but "Tran‐
114 sHandler" and "PreHandler" won't be. It is a map to coderefs just
115 like ContentHandler is.
116
117 PostHandler
118 These handlers are run after the socket has been flushed.
119
120 new(PostHandler => { '/' => [sub {}], '/foo/' => [\&foo]});
121
122 StreamHandler
123 If you turn on streaming in any other handler, the request is
124 placed in streaming mode. This handler is called, with the usual
125 parameters, when streaming mode is first entered, and subsequently
126 when each block of data is flushed to the client.
127
128 Streaming mode is turned on via the $response object:
129
130 $response->streaming(1);
131
132 You deactivate streaming mode with the same object:
133
134 $response->close;
135
136 Content is also sent to the client via the $response object:
137
138 $response->send($somedata);
139
140 The output filter is set to POE::Filter::Stream, which passes the
141 data through unchanged. If you are doing a multipart/mixed
142 response, you will have to set up your own headers.
143
144 Example:
145
146 sub new {
147 .....
148 POE::Component::Filter::HTTP->new(
149 ContentHandler => { '/someurl' => sub { $self->someurl(@_) },
150 StreamHandler => sub { $self->stream(@_),
151 );
152 }
153
154 sub someurl {
155 my($self, $resquest, $response)=@_;
156 $self->{todo} = [ .... ];
157 $response->streaming(1);
158 $response->code(RC_OK); # you must set up your response header
159 $response->content_type(...);
160
161 return RC_OK;
162 }
163
164 sub stream {
165 my($self, $resquest, $response)=@_;
166
167 if( @{$self->{todo}} ) {
168 $response->send(shift @{$self->{todo}});
169 }
170 else {
171 $response->close;
172 }
173 }
174
175 Another example can be found in t/30_stream.t. The parts dealing
176 with multipart/mixed are well documented and at the end of the
177 file.
178
179 NOTE: Changes in streaming mode are only verified when StreamHan‐
180 dler exits. So you must either turn streaming off in your
181 StreamHandler, or make sure that the StreamHandler will be called
182 again. This last is done by sending data to the client. If for
183 some reason you have no data to send, you can get the same result
184 with "continue". Remember that this will also cause the StreamHan‐
185 dler to be called one more time.
186
187 my $aliases=POE::Component::Filter::HTTP->new( ....);
188
189 # and then, when the end of the stream in met
190 $response->close;
191 $response->continue;
192
193 NOTE: even when the stream ends, the client connection will be held
194 open if Keepalive is active. To force the connection closed, set
195 the Connection header to close:
196
197 $resquest->header(Connection => 'close');
198
199 This might be a bug. Are there any cases where we'd want to keep
200 the connection open after a stream?
201
203 The "shutdown" event may be sent to the component indicating that it
204 should shut down. The event may be sent using the return value of the
205 new() method (which is a session id) by either post()ing or call()ing.
206
207 I've experienced some problems with the session not receiving the event
208 when it gets post()ed so call() is advised.
209
211 Please also take a look at HTTP::Response, HTTP::Request, URI, POE and
212 POE::Filter::HTTPD
213
215 Document Connection Response and Request objects.
216 Write more tests
217 Add a PoCo::Server::HTTP::Session that matches a http session against
218 poe session using cookies or other state system
219 Add more options to streaming
220 Figure out why post()ed "shutdown" events don't get received.
221 Probably lots of other API changes
222
224 Arthur Bergman, arthur@contiller.se
225
226 Additional hacking by Philip Gwyn, poe-at-pied.nu
227
228 Released under the same terms as POE.
229
230
231
232perl v5.8.8 2006-05-23 POE::Component::Server::HTTP(3)