tldr;
- very minimal stream socket server in
PHP
- acts strange since sometimes it successfully serves
HTTP
request and sometimes fails within the very same process - acts strange across different browsers - almost every time fails in
Chrome
and never inIE11
code:
$server = stream_socket_server("tcp://0.0.0.0:4444", $errno, $errorMessage);
if ($server === false)
throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
$e = "\r\n";
$headers = array(
"HTTP/1.1 200 OK",
"Date: " . date('D') . ', ' . date('m') . ' ' . date('M') . ' ' . date('Y') . ' ' . date('H:i:s') . ' GMT' ,
'Server: MySpeedy',
'Connection: close',
'Content-Type: text/plain',
'Content-Length: 2'
);
$headers = implode($e, $headers) . $e . $e .'ok';
for (;;)
{
$client = stream_socket_accept($server);
if ($client)
{
echo 'Connection accepted from '.stream_socket_get_name($client, false) . $e;
fwrite($client, $headers);
fclose($client);
}
}
gives me this http response (telnet results):
HTTP/1.1 200 OK
Date: Fri, 11 Nov 2015 20:09:02 GMT
Server: MySpeedy
Connection: close
Content-Type: text/plain
Content-Length: 2
ok
And that leads me to these results:
ERR_CONNECTION_RESET
in Chrome, almost every time (maybe 1 in 20-30 requests get expected response)The connection was reset
in Firefox, approximately 1 in 2-3 requests- Correct, expected response in Internet Explorer 11 every time (yay, IE is the best in something).
What am I doing wrong? Is it up to http headers (I couldn't say if I've formatted them incorrectly) or socket loop or..?
You don't read the HTTP request from the client but instead simply send your response and close the connection. But closing the socket while there are still data to read will cause a connection reset send back to the client and that's what you will see in Chrome with ERR_CONNECTION_RESET. Other browsers might behave differently and it is also a timing issue if the browser can display the response before handling the reset.
To fix it first read the full request from the client before you close the socket.