You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Fi Dot <fi...@gmail.com> on 2009/10/22 00:18:15 UTC

[users@httpd] Trying to detect client dropping connection before CGI process is finished, stuck...:(

Dear All,





I seem to be completely stuck with trying to detect client dropping
connection, no matter how hard I try.



I start with a simple Perl script running as a standard CGI app:



   #!/usr/bin/perl



   use strict;



   Log("$$: starting process");



   $SIG{PIPE} = sub { Log("$$: PIPE!!"); };

   $SIG{TERM} = sub { Log("$$: TERM!!");  };

   $SIG{HUP} = sub { Log("$$: HUP"); };

   $SIG{INT} = sub { Log("$$: INT"); };



   Log("$$: Processing request");



   print "\n\n";



   for(1 .. 10)

   {

     Log("$$: Sleep $_ ");

     sleep(1);

   }



   print "Content\n";



   Log("$$: Done");





I also have tried the following modification of the script for mod_perl:





   #!/usr/bin/perl



   use strict;



   use Apache2::RequestRec;

   use Apache2::Connection;



   Log("$$: starting process");



   $SIG{PIPE} = sub { Log("$$: PIPE!!"); };

   $SIG{TERM} = sub { Log("$$: TERM!!");  };

   $SIG{HUP} = sub { Log("$$: HUP"); };

   $SIG{INT} = sub { Log("$$: INT"); };



   local our $Conn = Apache2::RequestRec->connection();



   Log("$$: Processing request");



   print "\n\n";



   for(1 .. 10)

   {

     Log("$$: Sleep $_, aborted:", $Conn->aborted());

     sleep(1);

   }



   print "Content\n";



   Log("$$: Done");





and another modification for mod_fcgid (same idea with trying to intercept
signals and both with and w/o trying to use Apache2::Connection).



Log() function just outputs messages to a log file, that i am tail -f 'ing.





I make a request using curl,



curl http://localhost/script.pl



and also have tried LWP::UserAgent.



The way I test it is run the request process (either curl or a simple .pl
with a request made via LWP::UserAgent), and Control-C at some point (while
watching 'Sleep XX' messages appear in the log file).



In all three cases with both LWP and curl i see the same behavior - no
indication of a client dropping the connection (even with aborted() method
of mod_perl) whatsoever, no signals, no messages about client dropping
connection appearing in error.log of the server (LogLevel is set to 'info'),
etc. The CGI process in CGI case doesn't get terminated and / or killed; it
continues to loop and sleep until 10 seconds pass.





>From what I have been able to find, I tried:



* Looks like adding print STDOUT in the loop should cause PIPE signal
('broken pipe'), I tried adding 'print STDOUT " "' right before sleep() call
in the loop with no luck.

* Trying to see if the same print before sleep() would return failure
('print STDOUT " " or Log("Print failed!")', w/o any luck

* In mod_perl tests, trying to use Apache2::RequestRec->print() instead of
print.

* LogLevel info should be giving me messages about clients dropping
connections in error.log. I am not seeing any.





In addition, I clearly recall solving the same problem under mod_perl and
Apache using $Conn->aborted() method, and it worked (but that was a
different version of Apache 2 and mod_perl, unfortunately, I don’t have that
env right now to compare…).



I have tried this on 2 versions of Apache and mod_perl,



* Ubuntu + apache 2.2.8 / mod_perl 2.0.3:



  root@vmubuntu ~/api # apache2 -V

  Server version: Apache/2.2.8 (Ubuntu)

  Server built:   Feb  2 2008 04:03:01

  Server's Module Magic Number: 20051115:11

  Server loaded:  APR 1.2.11, APR-Util 1.2.12

  Compiled using: APR 1.2.11, APR-Util 1.2.12

  Architecture:   32-bit

  Server MPM:     Prefork

    threaded:     no

      forked:     yes (variable process count)

  Server compiled with....

   -D APACHE_MPM_DIR="server/mpm/prefork"

   -D APR_HAS_SENDFILE

   -D APR_HAS_MMAP

   -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)

   -D APR_USE_SYSVSEM_SERIALIZE

   -D APR_USE_PTHREAD_SERIALIZE

   -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT

   -D APR_HAS_OTHER_CHILD

   -D AP_HAVE_RELIABLE_PIPED_LOGS

   -D DYNAMIC_MODULE_LIMIT=128

   -D HTTPD_ROOT=""

   -D SUEXEC_BIN="/usr/lib/apache2/suexec"

   -D DEFAULT_PIDLOG="/var/run/apache2.pid"

   -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"

   -D DEFAULT_LOCKFILE="/var/run/apache2/accept.lock"

   -D DEFAULT_ERRORLOG="logs/error_log"

   -D AP_TYPES_CONFIG_FILE="/etc/apache2/mime.types"

   -D SERVER_CONFIG_FILE="/etc/apache2/apache2.conf"



* Gentoo + apache 2.2.11 + mod_perl 2.0.4:



   newcore tmp # apache2 -V

   Server version: Apache/2.2.11 (Unix)

   Server built:   Oct 21 2009 16:42:25

   Server's Module Magic Number: 20051115:21

   Server loaded:  APR 1.2.8, APR-Util 1.2.8

   Compiled using: APR 1.2.8, APR-Util 1.2.8

   Architecture:   32-bit

   Server MPM:     Prefork

     threaded:     no

       forked:     yes (variable process count)

   Server compiled with....

    -D APACHE_MPM_DIR="server/mpm/prefork"

    -D APR_HAS_SENDFILE

    -D APR_HAS_MMAP

    -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)

    -D APR_USE_SYSVSEM_SERIALIZE

    -D APR_USE_PTHREAD_SERIALIZE

    -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT

    -D APR_HAS_OTHER_CHILD

    -D AP_HAVE_RELIABLE_PIPED_LOGS

    -D DYNAMIC_MODULE_LIMIT=128

    -D HTTPD_ROOT="/usr"

    -D SUEXEC_BIN="/usr/sbin/suexec"

    -D DEFAULT_PIDLOG="/var/run/httpd.pid"

    -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"

    -D DEFAULT_LOCKFILE="/var/run/accept.lock"

    -D DEFAULT_ERRORLOG="logs/error_log"

    -D AP_TYPES_CONFIG_FILE="/etc/apache2/mime.types"

    -D SERVER_CONFIG_FILE="/etc/apache2/httpd.conf"







As you can see, both servers are running prefork mpm.

 Would anyone have a suggestion for this problem? Ideally I would like
either to be able to somehow detect client dropping connection from his side
from within the script, or Apache itself just killing the worker / CGI
process whenever it detects that.


Fi.