.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.el \{\
. de IX
..
.\}
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "POE::Filter::HTTPD 3pm"
.TH POE::Filter::HTTPD 3pm "2012-05-15" "perl v5.14.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
POE::Filter::HTTPD \- parse simple HTTP requests, and serialize HTTP::Response
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& #!perl
\&
\& use warnings;
\& use strict;
\&
\& use POE qw(Component::Server::TCP Filter::HTTPD);
\& use HTTP::Response;
\&
\& POE::Component::Server::TCP\->new(
\& Port => 8088,
\& ClientFilter => \*(AqPOE::Filter::HTTPD\*(Aq, ### <\-\- HERE WE ARE!
\&
\& ClientInput => sub {
\& my $request = $_[ARG0];
\&
\& # It\*(Aqs a response for the client if there was a problem.
\& if ($request\->isa("HTTP::Response")) {
\& my $response = $request;
\&
\& $request = $response\->request;
\& warn "ERROR: ", $request\->message if $request;
\&
\& $_[HEAP]{client}\->put($response);
\& $_[KERNEL]\->yield("shutdown");
\& return;
\& }
\&
\& my $request_fields = \*(Aq\*(Aq;
\& $request\->headers()\->scan(
\& sub {
\& my ($header, $value) = @_;
\& $request_fields .= (
\& "
$header | $value |
"
\& );
\& }
\& );
\&
\& my $response = HTTP::Response\->new(200);
\& $response\->push_header( \*(AqContent\-type\*(Aq, \*(Aqtext/html\*(Aq );
\& $response\->content(
\& "Your Request" .
\& "Details about your request:" .
\& "" .
\& ""
\& );
\&
\& $_[HEAP]{client}\->put($response);
\& $_[KERNEL]\->yield("shutdown");
\& }
\& );
\&
\& print "Aim your browser at port 8088 of this host.\en";
\& POE::Kernel\->run();
\& exit;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
POE::Filter::HTTPD interprets input streams as \s-1HTTP\s0 0.9, 1.0 or 1.1
requests. It returns a HTTP::Request objects upon successfully
parsing a request.
.PP
On failure, it returns an HTTP::Response object describing the
failure. The intention is that application code will notice the
HTTP::Response and send it back without further processing. The
erroneous request object is sometimes available via the
\&\*(L"$r\->request\*(R" in HTTP::Response method. This is illustrated in the
\&\*(L"\s-1SYNOPSIS\s0\*(R".
.PP
For output, POE::Filter::HTTPD accepts HTTP::Response objects and
returns their corresponding streams.
.PP
Please see HTTP::Request and HTTP::Response for details about
how to use these objects.
.SH "PUBLIC FILTER METHODS"
.IX Header "PUBLIC FILTER METHODS"
POE::Filter::HTTPD implements the basic POE::Filter interface.
.SH "CAVEATS"
.IX Header "CAVEATS"
Some versions of libwww are known to generate invalid \s-1HTTP\s0. For
example, this code (adapted from the HTTP::Request::Common
documentation) will cause an error in a POE::Filter::HTTPD daemon:
.PP
\&\s-1NOTE:\s0 Using this test with libwww\-perl/5.834 showed that it added
the proper \s-1HTTP/1\s0.1 data! We're not sure which version of \s-1LWP\s0 fixed
this. This example is valid for older \s-1LWP\s0 installations, beware!
.PP
.Vb 2
\& use HTTP::Request::Common;
\& use LWP::UserAgent;
\&
\& my $ua = LWP::UserAgent\->new();
\& $ua\->request(POST \*(Aqhttp://example.com\*(Aq, [ foo => \*(Aqbar\*(Aq ]);
.Ve
.PP
By default, HTTP::Request is \s-1HTTP\s0 version agnostic. It makes no
attempt to add an \s-1HTTP\s0 version header unless you specifically declare
a protocol using \f(CW\*(C`$request\->protocol(\*(AqHTTP/1.0\*(Aq)\*(C'\fR.
.PP
According to the \s-1HTTP\s0 1.0 \s-1RFC\s0 (1945), when faced with no \s-1HTTP\s0 version
header, the parser is to default to \s-1HTTP/0\s0.9. POE::Filter::HTTPD
follows this convention. In the transaction detailed above, the
Filter::HTTPD based daemon will return a 400 error since \s-1POST\s0 is not a
valid \s-1HTTP/0\s0.9 request type.
.PP
Upon handling a request error, it is most expedient and reliable to
respond with the error and shut down the connection. Invalid \s-1HTTP\s0
requests may corrupt the request stream. For example, the absence of
a Content-Length header signals that a request has no content.
Requests with content but not that header will be broken into a
content-less request and invalid data. The invalid data may also
appear to be a request! Hilarity will ensue, possibly repeatedly,
until the filter can find the next valid request. By shutting down
the connection on the first sign of error, the client can retry its
request with a clean connection and filter.
.SH "Streaming Media"
.IX Header "Streaming Media"
It is possible to use POE::Filter::HTTPD for streaming content, but an
application can use it to send headers and then switch to
POE::Filter::Stream.
.PP
From the input handler (the InputEvent handler if you're using wheels,
or the ClientInput handler for POE::Component::Server::TCP):
.PP
.Vb 4
\& my $response = HTTP::Response\->new(200);
\& $response\->push_header(\*(AqContent\-type\*(Aq, \*(Aqaudio/x\-mpeg\*(Aq);
\& $_[HEAP]{client}\->put($response);
\& $_[HEAP]{client}\->set_output_filter(POE::Filter::Stream\->new());
.Ve
.PP
Then the output-flushed handler (FlushEvent for POE::Wheel::ReadWrite,
or ClientFlushed for POE::Component::Server::TCP) can \fIput()\fR chunks of
the stream as needed.
.PP
.Vb 3
\& my $bytes_read = sysread(
\& $_[HEAP]{file_to_stream}, my $buffer = \*(Aq\*(Aq, 4096
\& );
\&
\& if ($bytes_read) {
\& $_[HEAP]{client}\->put($buffer);
\& }
\& else {
\& delete $_[HEAP]{file_to_stream};
\& $_[KERNEL]\->yield("shutdown");
\& }
.Ve
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Please see POE::Filter for documentation regarding the base
interface.
.PP
The \s-1SEE\s0 \s-1ALSO\s0 section in \s-1POE\s0 contains a table of contents covering
the entire \s-1POE\s0 distribution.
.PP
HTTP::Request and HTTP::Response explain all the wonderful
things you can do with these classes.
.SH "BUGS"
.IX Header "BUGS"
Many aspects of \s-1HTTP\s0 1.0 and higher are not supported, such as
keep-alive. A simple I/O filter can't support keep-alive, for
example. A number of more feature-rich \s-1POE\s0 \s-1HTTP\s0 servers are on the
\&\s-1CPAN\s0. See
.SH "AUTHORS & COPYRIGHTS"
.IX Header "AUTHORS & COPYRIGHTS"
POE::Filter::HTTPD was contributed by Artur Bergman. Documentation is
provided by Rocco Caputo.
.PP
Please see \s-1POE\s0 for more information about authors and contributors.