I am having issue with web socket connection/handshake from Firefox to my server written in Php.
Problem is when I try to connect client(using js/php or even websocket.org/echo.html) I get issue and the issue is client is firstly connected and then disconnected automatically. And at server, I am using fwrite
to to send message to client. And i have also noticed that for a client from firefox fwrite
returns 0
as a response, but at client side I can see server has posted handshake data.
Now I see problem is here, when server is writing but response is 0
and still browser(firefox) is getting response but it gets disconnected with the server at the same time. I even tried to compare(calculate) data in bytes, which server is posting to client. I see its exactly same.
Note:- Just to mention here, same php server script is working fine for Opera/Chrome/Safari browsers.
Below are the things which are involved in this issue;
- Firefox [71.0]
- Php [7.0]
- Apache
- Let's Encrypt SSL
# STREAM SOCKET CREATION OVER SSL(WSS)
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'local_cert', 'ssl-test.pem'); #change to your own ssl.pem path
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
$sock = stream_socket_server("ssl://".HOST_NAME.":".PORT,$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context) or die('Unable to start server, seems server is already running!');
// stream_set_blocking($sock,TRUE);
# PUTTING ALL(CURRENT/UPCOMING) SOCKET CONNECTIONS IN ARRAY
$clients = array();
# INFINTE LOOP THOURGH ALL SOCKECT CURRENT/UPCOMING CONNECTIONS, SEND/RECEIVE DATA
while (true) {
# ALL ACTIVE SOCKET CONNECTIONS
$read = $clients;
foreach($received_header as $key => $header){
if($header['time']+1 < microtime(true)){
$headers = [];
// echo $header['data'];
$lines = preg_split("/\r\n/", $header['data']);
foreach($lines as $line) {
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)){
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
// create handshake header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake" .PHP_EOL.
"Upgrade: websocket" .PHP_EOL.
"Connection: Upgrade" .PHP_EOL.
"Accept: text/html" .PHP_EOL.
"Sec-WebSocket-Accept: $secAccept".PHP_EOL.PHP_EOL;
// send handshake packet
if(!fwrite($clients[$key], $upgrade)){
file_put_contents('handshakes-est.txt', ($upgrade));
}
$handshakes[$key] = true;
$unset_key = $key;
}
}
/* i have rest of the script here which do further communication after connection is setup */
}
Below are some screen-shots to better understand connection behavior issue on Firefox.
Headers during handshake:
Connection behavior over websocket: