How do I generate a connection reset programatically?
I would recommend doing this via a custom socket via CLI as messing with the apache process could be messy:
#!/usr/bin/php -q<?phpset_time_limit (0);$sock = socket_create(AF_INET, SOCK_STREAM, 0);socket_bind($sock, '1.1.1.1', 8081) or die('Could not bind to address');socket_listen($sock);$client = socket_accept($sock);sleep(1);$pid = getmypid();exec("kill -9 $pid");?>
This will generate the desired error in Firefox as the connection is closed before read.
If you feel insanely daring, you could throw this into a web script but I wouldn't even venture trying that unless you own the box and know what you're doing admin wise.
I believe you need to close the low-level socket fairly abruptly. You won't be able to do it from Javascript. For the other languages you'll generally need to get a handle on the underlying socket object and close() it manually.
I also doubt you can do this through Apache since it is Apache and not your application holding the socket. At best your efforts are likely to generate a HTTP 500 error which is not what you're after.
Update:
This script worked well enough to test our connection-reset workaround, so it's a partial answer.
If someone comes up with the full solution that works on a remote host, I'll gladly mark that as the answer.
The following script works every time when running and tested on the same machine. But when running on a remote host, the browser gets the following last 3 packets:
Source Dest Protocol Info<server> <client> TCP 8081 > 1835 [RST] Seq=2 Len=0<server> <client> TCP 8081 > 1835 [RST] Seq=2 Len=0<server> <client> TCP http > 1834 [ACK] Seq=34 Ack=1 Win=6756 Len=0
As you can see, the RST
flag is set and sent. But Firefox fails silently with a blank page -- no messages of any kind.
Script:
<?php $time_lim = 30; $listen_port = 8081; echo '<h1>Testing generation of a connection reset condition.</h1> <p><a target="_blank" href="http://' .$_SERVER["HTTP_HOST"]. ':' .$listen_port. '/"> Click here to load page that gets reset. You have ' . $time_lim . ' seconds.</a> </p> ' ; flush ();?><?php //-- Warning! If the script blocks, below, this is not counted against the time limit. set_time_limit ($time_lim); $socket = @socket_create_listen ($listen_port); if (!$socket) { print "Failed to create socket!\n"; exit; } socket_set_nonblock ($socket); //-- Needed, or else script executes until a client interacts with the socket. while (true) { //-- Use @ to suppress warnings. Exception handling didn't work. $client = @socket_accept ($socket); if ($client) break; } /*--- If l_onoff is non-zero and l_linger is zero, all the unsent data will be discarded and RST (reset) is sent to the peer in the case of a connection- oriented socket. */ $linger = array ('l_linger' => 0, 'l_onoff' => 1); socket_set_option ($socket, SOL_SOCKET, SO_LINGER, $linger); //--- If we just close, the Browser gets the RST flag but fails silently (completely blank). socket_close ($socket); echo "<p>Done.</p>";?>