Feersum::Connection::Handle - PSGI-style reader/writer objects.
For read handles:
my $buf;
my $r = delete $env{'psgi.input'};
$r->read($buf, 1, 1); # read the second byte of input without moving offset
$r->read($buf, $env{CONTENT_LENGTH}); # append the whole input
$r->close(); # discards any un-read() data
# assuming the handle is "open":
$r->seek(2,SEEK_CUR); # returns 1, discards skipped bytes
$r->seek(-1,SEEK_CUR); # returns 0, can't seek back
# not yet supported, throws exception:
# $r->poll_cb(sub { .... });
For write handles:
$w->write("scalar");
$w->write(\"scalar ref");
$w->write_array(\@some_stuff);
$w->poll_cb(sub {
# use $_[0] instead of $w to avoid a closure
$_[0]->write(\"some data");
# can close() or unregister the poll_cb in here
$_[0]->close();
});
For both:
$h->response_guard(guard { response_is_complete() });
See the PSGI spec for more information on how read/write handles are used (The
Delayed Response and Streaming Body section has details on the writer).
The reader is obtained via
"$env->{'psgi.input'}".
- "$r->read($buf, $len)"
- Read the first $len bytes of the request body into
the buffer specified by $buf (similar to how
sysread works).
The calls to "$r->read()"
will never block. Currently, the entire body is read into memory (or
perhaps to a temp file) before the Feersum request handler is even
called. This behaviour MAY change. Regardless, Feersum will be
doing some buffering so
"psgix.input.buffered" is set in the
PSGI env hash.
- "$r->seek(...)"
- Seeking is partially supported. Feersum discards skipped-over bytes to
conserve memory.
$r->seek(0,SEEK_CUR); # returns 1
$r->seek(-1,SEEK_CUR); # returns 0
$r->seek(-1,SEEK_SET); # returns 0
$r->seek(2,SEEK_CUR); # returns 1, discards skipped bytes
$r->seek(42,SEEK_SET); # returns 1 if room, discards skipped bytes
$r->seek(-8,SEEK_END); # returns 1 if room, discards skipped bytes
- "$r->close()"
- Discards the remainder of the input buffer.
- "$r->poll_cb(sub { .... })"
- NOT YET SUPPORTED. PSGI only defined poll_cb for the Writer
object.
The writer is obtained under PSGI by sending a code/headers pair to the
"starter" callback. Under Feersum, calls to
"$req->start_streaming" return one.
- "$w->write("scalar")"
- Send the scalar as a "T-E: chunked" chunk.
The calls to
"$w->write()" will never block and
data is buffered until transmitted. This behaviour is indicated by
"psgix.output.buffered" in the PSGI
env hash (Twiggy supports this too, for example).
- "$w->write(\"scalar ref")"
- Works just like
"write("scalar")" above. This
extension is indicated by
"psgix.body.scalar_refs" in the PSGI env
hash.
- "$w->write_array(\@array)"
- Pass in an array-ref and it works much like the two
"write()" calls above, except it's way
more efficient than calling "write()"
over and over. Undefined elements of the array are ignored.
- "$w->close()"
- Close the HTTP response (which triggers the "T-E: chunked"
terminating chunk to be sent). This method is implicitly called when the
last reference to the writer is dropped.
- "$w->poll_cb(sub { .... })"
- Register a callback to be called when the write buffer is empty. Pass in
"undef" to unset. The sub can call
"close()".
A reference to the writer is passed in as the first and only
argument to the sub. It's recommended that you use
$_[0] rather than closing-over on
$w to prevent a circular reference.
Methods in common to both types of handles.
- "$h->response_guard($guard)"
- Register a guard to be triggered when the response is completely sent and
the socket is closed. A "guard" in this context is some object
that will do something interesting in its DESTROY/DEMOLISH method. For
example, Guard.
The guard is *not* attached to this handle object; the guard
is attached to the response.
"psgix.output.guard" is the
PSGI-env extension that indicates this method.
- "$h->fileno"
- Returns the file descriptor number for this connection.
Jeremy Stashewsky, "stash@cpan.org"
Copyright (C) 2010 by Jeremy Stashewsky & Socialtext Inc.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself, either Perl version 5.8.7 or,
at your option, any later version of Perl 5 you may have available.