-
- return event_read_input($self) if defined $self->{env};
-
- my $off = length($self->{rbuf});
- my $r = sysread($self->{sock}, $self->{rbuf}, 8192, $off);
- if (defined $r) {
- return $self->close if $r == 0;
- return rbuf_process($self);
- }
- return if $!{EAGAIN}; # no need to call watch_read(1) again
-
- # common for clients to break connections without warning,
- # would be too noisy to log here:
- return $self->close;
-}
-
-sub rbuf_process {
- my ($self) = @_;
-
- my %env = %{$self->{httpd}->{env}}; # full hash copy
- my $r = parse_http_request($self->{rbuf}, \%env);
-
- # We do not support Trailers in chunked requests, for now
- # (they are rarely-used and git (as of 2.7.2) does not use them)
- if ($r == -1 || $env{HTTP_TRAILER} ||
- # this length-check is necessary for PURE_PERL=1:
- ($r == -2 && length($self->{rbuf}) > 0x4000)) {
- return quit($self, 400);
+ local $SIG{__WARN__} = $self->{srv_env}->{'pi-httpd.warn_cb'};
+ return unless $self->flush_write && $self->{sock};
+
+ # 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 ref($self->{env});
+
+ my $rbuf = $self->{rbuf} // (\(my $x = ''));
+ my %env = %{$self->{srv_env}}; # full hash copy
+ my $r;
+ while (($r = parse_http_request($$rbuf, \%env)) < 0) {
+ # We do not support Trailers in chunked requests, for
+ # now (they are rarely-used and git (as of 2.7.2) does
+ # not use them).
+ # this length-check is necessary for PURE_PERL=1:
+ if ($r == -1 || $env{HTTP_TRAILER} ||
+ ($r == -2 && length($$rbuf) > 0x4000)) {
+ return quit($self, 400);
+ }
+ $self->do_read($rbuf, 8192, length($$rbuf)) or return;