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;
# 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);
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)
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;
}
}
# 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') {
response_write($self, $env, $res);
}
};
- $self->close if $@;
+ if ($@) {
+ err($self, "response_write error: $@");
+ $self->close;
+ }
}
sub response_header_write {
}
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 ($@) {
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 $@;
# 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.