diff options
Diffstat (limited to 'lib/PublicInbox/GetlineResponse.pm')
-rw-r--r-- | lib/PublicInbox/GetlineResponse.pm | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/PublicInbox/GetlineResponse.pm b/lib/PublicInbox/GetlineResponse.pm new file mode 100644 index 00000000..290cce74 --- /dev/null +++ b/lib/PublicInbox/GetlineResponse.pm @@ -0,0 +1,40 @@ +# Copyright (C) all contributors <meta@public-inbox.org> +# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> + +# For generic PSGI servers (not public-inbox-httpd/netd) which assumes their +# getline response bodies can be backpressure-aware for slow clients +# This depends on rpipe being _blocking_ on getline. +package PublicInbox::GetlineResponse; +use v5.12; + +sub response { + my ($qsp) = @_; + my ($res, $rbuf); + do { # read header synchronously + sysread($qsp->{rpipe}, $rbuf, 65536); + $res = $qsp->parse_hdr_done($rbuf); # fills $bref + } until defined($res); + my ($wcb, $filter) = $qsp->yield_pass(undef, $res) or return; + my $self = $res->[2] = bless { + qsp => $qsp, + filter => $filter, + }, __PACKAGE__; + my ($bref) = @{delete $qsp->{yield_parse_hdr}}; + $self->{rbuf} = $$bref if $$bref ne ''; + $wcb->($res); +} + +sub getline { + my ($self) = @_; + my $rpipe = $self->{qsp}->{rpipe} // do { + delete($self->{qsp})->finish; + return; # EOF was set on previous call + }; + my $buf = delete($self->{rbuf}) // $rpipe->getline; + $buf // delete($self->{qsp}->{rpipe}); # set EOF for next call + $self->{filter} ? $self->{filter}->translate($buf) : $buf; +} + +sub close {} + +1; |