]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/HTTP.pm
treewide: "require" + "use" cleanup and docs
[public-inbox.git] / lib / PublicInbox / HTTP.pm
index ad1a2f9f5e2e850e5f9e0eec0f62ebecf0b2dca3..1346901ad52300fd4b9985c18ba912502ce0f649 100644 (file)
@@ -11,13 +11,14 @@ package PublicInbox::HTTP;
 use strict;
 use warnings;
 use base qw(PublicInbox::DS);
-use fields qw(httpd env input_left remote_addr remote_port forward);
+use fields qw(httpd env input_left remote_addr remote_port forward alive);
 use bytes (); # only for bytes::length
 use Fcntl qw(:seek);
 use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
+use Plack::Util;
 use HTTP::Status qw(status_message);
 use HTTP::Date qw(time2str);
-use IO::Handle;
+use IO::Handle; # ->write
 use PublicInbox::DS qw(msg_more);
 use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT);
 use PublicInbox::Tmpfile;
@@ -164,7 +165,7 @@ sub app_dispatch {
        }
        # note: NOT $self->{sock}, we want our close (+ PublicInbox::DS::close),
        # to do proper cleanup:
-       $env->{'psgix.io'} = $self; # only for ->close
+       $env->{'psgix.io'} = $self; # for ->close or async_pass
        my $res = Plack::Util::run_app($self->{httpd}->{app}, $env);
        eval {
                if (ref($res) eq 'CODE') {
@@ -256,51 +257,47 @@ sub response_done {
        $self->write($alive ? \&next_request : \&close);
 }
 
-sub getline_response ($$) {
-       my ($self, $alive) = @_;
-       my $write = $alive == 2 ? \&chunked_write : \&identity_write;
-       my $pull; # DANGER: self-referential
-       $pull = sub {
-               my $forward = $self->{forward};
-               # limit our own running time for fairness with other
-               # clients and to avoid buffering too much:
-               my $buf = eval {
-                       local $/ = \8192;
-                       $forward->getline;
-               } if $forward;
-
-               if (defined $buf) {
-                       # may close in PublicInbox::DS::write
-                       $write->($self, $buf);
-
-                       if ($self->{sock}) {
-                               my $wbuf = $self->{wbuf} ||= [];
-                               push @$wbuf, $pull;
-
-                               # wbuf may be populated by $write->(...$buf),
-                               # no need to rearm if so:
-                               $self->requeue if scalar(@$wbuf) == 1;
-                               return; # likely
-                       }
-               } elsif ($@) {
-                       err($self, "response ->getline error: $@");
-                       $self->close;
+sub getline_pull {
+       my ($self) = @_;
+       my $forward = $self->{forward};
+
+       # limit our own running time for fairness with other
+       # clients and to avoid buffering too much:
+       my $buf = eval {
+               local $/ = \8192;
+               $forward->getline;
+       } if $forward;
+
+       if (defined $buf) {
+               # may close in PublicInbox::DS::write
+               if ($self->{alive} == 2) {
+                       chunked_write($self, $buf);
+               } else {
+                       identity_write($self, $buf);
                }
 
-               $pull = undef; # all done!
-               # avoid recursion
-               if (delete $self->{forward}) {
-                       eval { $forward->close };
-                       if ($@) {
-                               err($self, "response ->close error: $@");
-                               $self->close; # idempotent
-                       }
-               }
-               $forward = undef;
-               response_done($self, $alive);
-       };
+               if ($self->{sock}) {
+                       my $wbuf = $self->{wbuf} //= [];
+                       push @$wbuf, \&getline_pull;
 
-       $pull->(); # kick-off!
+                       # wbuf may be populated by {chunked,identity}_write()
+                       # above, no need to rearm if so:
+                       $self->requeue if scalar(@$wbuf) == 1;
+                       return; # likely
+               }
+       } elsif ($@) {
+               err($self, "response ->getline error: $@");
+               $self->close;
+       }
+       # avoid recursion
+       if (delete $self->{forward}) {
+               eval { $forward->close };
+               if ($@) {
+                       err($self, "response ->close error: $@");
+                       $self->close; # idempotent
+               }
+       }
+       response_done($self, delete $self->{alive});
 }
 
 sub response_write {
@@ -316,7 +313,8 @@ sub response_write {
                        response_done($self, $alive);
                } else {
                        $self->{forward} = $body;
-                       getline_response($self, $alive);
+                       $self->{alive} = $alive;
+                       getline_pull($self); # kick-off!
                }
        # these are returned to the calling application:
        } elsif ($alive == 2) {