about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-03-01 08:19:12 +0000
committerEric Wong <e@80x24.org>2016-03-01 08:33:52 +0000
commit2d7d6d91b8894052b8b6088defaf7ea1711eba06 (patch)
tree0607a8db3fb3b178465a892123d41b86138559b8 /lib
parentf5f7d2138f8a50e44d7363295be0676f9a124524 (diff)
downloadpublic-inbox-2d7d6d91b8894052b8b6088defaf7ea1711eba06.tar.gz
Better to throw the error back to the client ASAP if we're
out-of-descriptors.  We will need to implement idle client
expiration for long-lived HTTP connections.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/HTTP.pm16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index aaae7ab5..17e74475 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -71,7 +71,10 @@ sub rbuf_process {
         return quit($self, 400) if $r == -1 || $env{HTTP_TRAILER};
         return $self->watch_read(1) if $r < 0; # incomplete
         $self->{rbuf} = substr($self->{rbuf}, $r);
+
         my $len = input_prepare($self, \%env);
+        defined $len or return write_err($self); # EMFILE/ENFILE
+
         $len ? event_read_input($self) : app_dispatch($self);
 }
 
@@ -116,7 +119,10 @@ sub app_dispatch ($) {
                 $host =~ s/:(\d+)\z// and $env->{SERVER_PORT} = $1;
                 $env->{SERVER_NAME} = $host;
         }
-        sysseek($env->{'psgi.input'}, 0, SEEK_SET) or die "input seek failed: $!";
+
+        sysseek($env->{'psgi.input'}, 0, SEEK_SET) or
+                        die "BUG: psgi.input seek failed: $!";
+
         my $res = Plack::Util::run_app($self->{httpd}->{app}, $env);
         eval {
                 if (ref($res) eq 'CODE') {
@@ -222,13 +228,17 @@ sub input_prepare {
         if ($len) {
                 $input = IO::File->new_tmpfile;
         } elsif (env_chunked($env)) {
-                $input = IO::File->new_tmpfile;
                 $len = CHUNK_START;
+                $input = IO::File->new_tmpfile;
         }
+
+        # TODO: expire idle clients on ENFILE / EMFILE
+        return unless $input;
+
         binmode $input;
         $env->{'psgi.input'} = $input;
         $self->{env} = $env;
-        $self->{input_left} = $len;
+        $self->{input_left} = $len || 0;
 }
 
 sub env_chunked { ($_[0]->{HTTP_TRANSFER_ENCODING} || '') =~ /\bchunked\b/i }