X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FHTTP.pm;h=df328904a86b57e318879afa67da71ecea35ee8f;hb=95bdac7f09c69036efed537a4d03d5bdd2ae4eb6;hp=e350daaff1c003bb3cd9ab43cb154b0d09e86d64;hpb=a1ad66cc2ae871c28d64325894d63ed08d3b6c1b;p=public-inbox.git
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index e350daaf..df328904 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2016-2019 all contributors
+# Copyright (C) 2016-2020 all contributors
# License: AGPL-3.0+
#
# Generic PSGI server for convenience. It aims to provide
@@ -15,9 +15,10 @@ 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;
@@ -79,7 +80,7 @@ sub event_step { # called by PublicInbox::DS
# only read more requests if we've drained the write buffer,
# otherwise we can be buffering infinitely w/o backpressure
- return read_input($self) if defined $self->{env};
+ return read_input($self) if ref($self->{env});
my $rbuf = $self->{rbuf} // (\(my $x = ''));
$self->do_read($rbuf, 8192, bytes::length($$rbuf)) or return;
rbuf_process($self, $rbuf);
@@ -123,7 +124,6 @@ sub read_input ($;$) {
my ($self, $rbuf) = @_;
$rbuf //= $self->{rbuf} // (\(my $x = ''));
my $env = $self->{env};
- return if $env->{REMOTE_ADDR}; # in app dispatch
return read_input_chunked($self, $rbuf) if env_chunked($env);
# env->{CONTENT_LENGTH} (identity)
@@ -152,9 +152,10 @@ sub app_dispatch {
my ($self, $input, $rbuf) = @_;
$self->rbuf_idle($rbuf);
my $env = $self->{env};
+ $self->{env} = undef; # for exists() check in ->busy
$env->{REMOTE_ADDR} = $self->{remote_addr};
$env->{REMOTE_PORT} = $self->{remote_port};
- if (my $host = $env->{HTTP_HOST}) {
+ if (defined(my $host = $env->{HTTP_HOST})) {
$host =~ s/:([0-9]+)\z// and $env->{SERVER_PORT} = $1;
$env->{SERVER_NAME} = $host;
}
@@ -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') {
@@ -173,7 +174,10 @@ sub app_dispatch {
response_write($self, $env, $res);
}
};
- $self->close if $@;
+ if ($@) {
+ err($self, "response_write error: $@");
+ $self->close;
+ }
}
sub response_header_write {
@@ -276,12 +280,12 @@ sub getline_pull {
}
if ($self->{sock}) {
- my $wbuf = $self->{wbuf} //= [];
- push @$wbuf, \&getline_pull;
+ # autovivify wbuf
+ my $new_size = push(@{$self->{wbuf}}, \&getline_pull);
# wbuf may be populated by {chunked,identity}_write()
# above, no need to rearm if so:
- $self->requeue if scalar(@$wbuf) == 1;
+ $self->requeue if $new_size == 1;
return; # likely
}
} elsif ($@) {
@@ -451,7 +455,6 @@ sub quit {
sub close {
my $self = $_[0];
- delete $self->{env}; # prevent circular references
if (my $forward = delete $self->{forward}) {
eval { $forward->close };
err($self, "forward ->close error: $@") if $@;
@@ -462,7 +465,7 @@ sub close {
# for graceful shutdown in PublicInbox::Daemon:
sub busy () {
my ($self) = @_;
- ($self->{rbuf} || $self->{env} || $self->{wbuf});
+ ($self->{rbuf} || exists($self->{env}) || $self->{wbuf});
}
# Chunked and Identity packages are used for writing responses.