NAME
Hyperman::Writer - the object that writes a response body a piece at a time
SYNOPSIS
# from a psgi.streaming responder
sub {
my $env = shift;
return sub {
my $respond = shift;
my $w = $respond->([ 200, [ 'Content-Type' => 'text/plain' ] ]);
$w->write("a piece;");
$w->write("another");
$w->close;
};
}
# or from the stream seam, which also works on HTTP/2 and on TLS
sub {
my $env = shift;
return sub {
my $w = Hyperman::stream($env, 200,
[ 'Content-Type' => 'text/plain' ]);
$w->write($_) for @chunks;
$w->close;
};
}
DESCRIPTION
Two methods and one promise: what you write goes out in order, and when you close it the body has ended. You never construct one - it comes back from a psgi.streaming responder or from "stream" in Hyperman.
Underneath there are three transports, and a writer is a blessed arrayref whose shape says which:
an EOF-delimited HTTP/1.1 connection, where closing the body closes the socket (there is no chunked response encoding: the response carries
Connection: closeand the client reads to end of file);an HTTP/2 stream, buffered until close and then submitted as one response;
an ABI v6 stream handle, which is the transport-neutral one. The same three calls write over HTTP/1.1 or over an HTTP/2 stream, in clear or under TLS, and the branch lives inside the handle rather than in the caller. This is what "stream" in Hyperman hands back.
Three shapes rather than three classes, because they are one contract. Code holding a writer never has to ask which it has.
METHODS
write
$w->write($bytes);
Append to the body. The bytes are copied, so the caller may reuse its buffer.
Writing to a stream whose connection has gone is dropped rather than fatal: by then the reader is already lost, and a producer looping over rows has nothing useful to do with an exception. A C consumer that does want to know - to stop a query, or to release a subscription - gets the reason from the C ABI's stream_write instead, along with the backpressure signal that says when to pause. See "Stream handles" in Hyperman.
close
$w->close;
End the body. On HTTP/1.1 that closes the connection, because the response was EOF-delimited; on HTTP/2 it ends that stream and leaves the connection serving its others.
Closing twice is harmless. A writer that goes out of scope without being closed is closed then, the way a lexical filehandle is - but close it yourself where you can, so the body ends when you meant it to and not when the last reference happens to go.
SEE ALSO
Hyperman, and "stream" in Hyperman for the seam that returns a transport-neutral writer.
AUTHOR
LNATION, <email at lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION.
This is free software, licensed under the Artistic License 2.0.