> Peter Valdemar Mørch wrote: > > Hi, > > > > I'm trying to find out how to detect user hitting 'stop' aka 'abort' > > in modperl 2. I found documentation on how it works in modperl 1 ( > > http://perl.apache.org/docs/1.0/guide/debug.html#Detecting_Aborted_Connections > > - short version: $r->print returns success and $r->connection->aborted > > tells whether user hit abort ). > > > > However, I've tested the situation to be quite different in modperl 2: > > > > When the user hits 'stop', the *second* $r->rflush() generates an exception > >> Apache2::RequestIO::rflush: (103) Software caused connection > > as long as ~ 100ms has passed between the two rflush-es. > > > > Here is my understanding of what happens: > > > > When the user hits 'stop' in the browser, the browser sends a TCP > > packet with the FIN flag set. Apache2/modperl doesn't react to that > > and $r->connection->aborted still returns false. A subsequent > > $r->print and $r->rflush works fine. Apache now sends whatever was > > printed to the browser. The browser now sends RST ("Hey, I really want > > to kill this connection!") to Apache and after that, $r->print still > > succeeds (returns true), but $r->rflush dies (because now the client > > has closed the socket hard). "Second" $r->rflush really means "the > > first $r->rflush after Apache received the client's 'RST' ", so if I > > issue many $r->print("foo"); $r->rflush() in quick succession they all > > pass. Around 100ms needs to pass between $r->rflush-es for the second > > $r->rflush to fail. If tested this with Firefox and Chromium. > > > > So: After the user hits 'stop', the second $r->rflush (requiring a > > delay) generates an exception that can be used to determine that the > > user has hit 'stop'. > > > > Have I understood this correctly? Is there any way I can get Apache to > > react to the first TCP FIN, and have $r->connection->aborted return > > true at that point? Or otherwise detect reliably when the user has hit > > 'stop' in modperl 2 without having to wait an additional > > server-client-server roundtrip time? > > Hi. > Just my two cent, maybe just to dampen your expectations a little bit. > This topic is probably as old as the WWW itself, and there just is no magic > bullet here. > Think of the following : > The whole FIN, ACK, RST etc.. exchange concerns /one/ TCP connection, between > your browser > and whatever it is talking to directly. For example, a HTTP proxy server, or > a firewall. > And then, this proxy/firewall has /another/ TCP connection with the next node > in the chain > (which may be your webserver or still another intermediary, like a > load-balancer e.g.). > And in-between, there are buffers and a lot of piping, and delays. > So, expecting your mod_perl script to be able to detect instantly when the > user at the > browser half a planet away presses the "stop" button, is /never/ going to be > guaranteed. > I'm not saying that you cannot try to catch such a thing as early as possible. > But if your ultimate aim is to find a way where instant detection is > guaranteed, then give > it up. It is just not possible, given how the Internet, and TCP/IP and HTTP > work.
In addition to that, there is variation among web browser and smart phone vendors in the way they tear down sockets. Some may close the socket immediately (a good practice in my opinion), while others may just let the resource get garbage collected or even have an unknown bug that results in a temporary or permanent resource leak on the client-side. The same problems can occur with proxy servers, and for localized end-user products that intercept all traffic (e.g., for the purpose of scanning for viruses or other suspicious activity) there can be problems as well. I've seen big problems with long timeouts with some of these client-side products where the server has lingering connections after the QUIT phase with POP3 connections, and removing the firewalling software resolved the problem (but this isn't a solution that helps you because many users insist on running these programs, are working at companies that require it, etc.). Making sure you have adequate resources to handle the load on the server-side is likely less time-consuming than figuring out how every web browser does (and will) handle the user pressing the "Stop" button behind-the-scenes, although the KeepAlive and KeepAliveTImeout directives may be helpful to you: http://httpd.apache.org/docs/current/mod/core.html#keepalive http://httpd.apache.org/docs/current/mod/core.html#keepalivetimeout Note: The KeepAliveTimeout directive is only available starting with Apache HTTPd v2.3.2. Have you've already experimented with the Timeout directive? If not, then I suggest you start with this directive before using the KeepAlive and KeepAliveTimeout directives: http://httpd.apache.org/docs/current/mod/core.html#timeout Randolf Richardson - rand...@inter-corporate.com Inter-Corporate Computer & Network Services, Inc. Beautiful British Columbia, Canada http://www.inter-corporate.com/