Tuesday, July 19, 2011

How to kill an HTTP connection and continue processing (PHP and Apache2)

Today I fell onto yet another really neat trick with HTTP: closing the connection without closing the server side process that's handling the request. It's actually a really simple trick and only involves sending the right headers to the browser on which the browser cuts the connection. The magic headers:
Content-length: 0
Connection: close
And example of using this with PHP:
<?php
header("Connection: close");
header("Content-length: 0");
flush(); # flush will send the headers we just defined,

# from here on out, the browser has (at least should have) closed the connection,
# here is where we get to do all the time taking tasks without blocking the users browser
file_put_contents('/tmp/demo.txt', time(), FILE_APPEND);
sleep(5);
file_put_contents('/tmp/demo.txt', time(), FILE_APPEND);
In this case we're not actually sending any kind of result/output to the browser other than the headers to direct it to kill the connection. Another possibility would be using this together with content buffering so we can send an actual response and set the correct headers:
<?php
ob_start();

echo "<html><head></head><body>";
echo "<h1>this is a demo</h1>";
echo "</body></html>";

header("Connection: close");
header("Content-length: " . (string)ob_get_length());

ob_end_flush();
ob_flush();
flush();

sleep(5);
# work, work and more work...
# send a mail, log actions to files, databases, ... all that really slow stuff ^^
file_put_contents('/tmp/tmp_OB', 'this is a test');