Bug 50948 - Connection not closed when CGI dies waiting for POST data
Summary: Connection not closed when CGI dies waiting for POST data
Status: REOPENED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_cgi (show other bugs)
Version: 2.2.17
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-19 10:16 UTC by Zach Lutho
Modified: 2012-08-12 09:15 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zach Lutho 2011-03-19 10:16:12 UTC
When a CGI program dies while it is waiting for the client to send its POST data, Apache does not reap the child process and close the connection but instead waits for whatever timeout is configured globally before closing the connection. This seems senseless as there's nothing to be done once the child has exited.

Consider this simple Perl script:

<snip>
#!/usr/bin/perl

$SIG{ALRM} = sub { die };
alarm 5;
sysread STDIN, $data, 4096;

END {
  print "Content-Type: text/plain\n\n";
  print $data;
}
</snip>

and this client request sending all the headers but no body and keeping the connection open:

<snip>
POST /test.cgi HTTP/1.1
Host: localhost
Content-Length: 10

</snip>

After the five seconds timeout the child will hang around as a zombie but the connection is still open.
Comment 1 Zach Lutho 2011-06-23 17:29:01 UTC
Ping?
Comment 2 Joe Orton 2011-06-24 08:38:33 UTC
mod_cgi does not discover the child has died until it reads or writes from the child's stdout or stdin respectively.  If the client is sending a body, mod_cgi will not write to the stdin until it reads a block from the client.  So, this is expected behaviour, sorry.  (It is a design constraint with httpd filters that it is not possible to wait for I/O across {client connection, pipes to children}.)
Comment 3 Carsten Gaebler 2012-08-12 09:15:57 UTC
How about allowing apr_bucket_read() to return when interrupted by a signal, i.e. implementing something in between APR_BLOCK_READ and APR_NONBLOCK_READ?