user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH] http: improve error handling for aborted responses
@ 2016-04-29 20:03  7% Eric Wong
  0 siblings, 0 replies; 1+ results
From: Eric Wong @ 2016-04-29 20:03 UTC (permalink / raw)
  To: meta

We need to abort connections properly if a response is prematurely
truncated.  This includes problems with serving static files, since
a clumsy admin or broken FS could return truncated responses and
inadvertently leave a client waiting (since the client saw
"Content-Length" in the header and expected a certain length).
---
 lib/PublicInbox/GitHTTPBackend.pm | 19 ++++++++++++++-----
 lib/PublicInbox/HTTP.pm           |  9 +++++++++
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm
index 30efa83..4b39693 100644
--- a/lib/PublicInbox/GitHTTPBackend.pm
+++ b/lib/PublicInbox/GitHTTPBackend.pm
@@ -95,6 +95,7 @@ sub serve_dumb {
 			$len -= $r;
 			$fh->write($buf);
 		}
+		die "$f truncated with $len bytes remaining\n" if $len;
 		$fh->close;
 	}
 }
@@ -191,14 +192,21 @@ sub serve_smart {
 			$fh = undef;
 		}
 		if ($rpipe) {
-			$rpipe->close; # _may_ be Danga::Socket::close
+			# _may_ be Danga::Socket::close via
+			# PublicInbox::HTTPD::Async::close:
+			$rpipe->close;
 			$rpipe = undef;
 			$nr_running--;
 		}
-		if (defined $pid && $pid != waitpid($pid, 0)) {
-			$err->print("git http-backend ($git_dir): $?\n");
-		} else {
-			$pid = undef;
+		if (defined $pid) {
+			my $e = $pid == waitpid($pid, 0) ?
+				$? : "PID:$pid still running?";
+			if ($e) {
+				$err->print("http-backend ($git_dir): $e\n");
+				if (my $io = $env->{'psgix.io'}) {
+					$io->close;
+				}
+			}
 		}
 		return unless $res;
 		my $dumb = serve_dumb($cgi, $git, $path);
@@ -245,6 +253,7 @@ sub serve_smart {
 		} # else { keep reading ... }
 	};
 	if (my $async = $env->{'pi-httpd.async'}) {
+		# $async is PublicInbox::HTTPD::Async->new($rpipe, $cb)
 		$rpipe = $async->($rpipe, $cb);
 		sub { ($res) = @_ } # let Danga::Socket handle the rest.
 	} else { # synchronous loop for other PSGI servers
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index c7fb954..973da34 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -135,6 +135,9 @@ sub app_dispatch ($) {
 	sysseek($env->{'psgi.input'}, 0, SEEK_SET) or
 			die "BUG: psgi.input seek failed: $!";
 
+	# note: NOT $self->{sock}, we want our close (+ Danga::Socket::close),
+	# to do proper cleanup:
+	$env->{'psgix.io'} = $self; # only for ->close
 	my $res = Plack::Util::run_app($self->{httpd}->{app}, $env);
 	eval {
 		if (ref($res) eq 'CODE') {
@@ -371,6 +374,12 @@ sub quit {
 sub event_hup { $_[0]->close }
 sub event_err { $_[0]->close }
 
+sub close {
+	my $self = shift;
+	$self->{env} = undef;
+	$self->SUPER::close(@_);
+}
+
 sub write ($$) : method {
 	my PublicInbox::HTTP $self = $_[0];
 	return 1 if (defined($_[1]) && ref($_[1]) eq '' && $_[1] eq '');
-- 
EW


^ permalink raw reply related	[relevance 7%]

Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2016-04-29 20:03  7% [PATCH] http: improve error handling for aborted responses Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).