mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2025-12-30 00:53:50 +00:00
Fix websocket service disconnect on invalid handshake (#7447)
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* FusionPBX
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FusionPBX
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mark J Crane <markjcrane@fusionpbx.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008-2025
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mark J Crane <markjcrane@fusionpbx.com>
|
||||
* Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Description of invalid_handshake_exception
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class invalid_handshake_exception extends \socket_exception {
|
||||
public function __construct($id = null, string $message = "Invalid handshake", int $code = 0, ?\Throwable $previous = null) {
|
||||
return parent::__construct($id, $message, $code, $previous);
|
||||
}
|
||||
}
|
||||
@@ -37,5 +37,5 @@ class socket_exception extends \Exception {
|
||||
$this->id = $id;
|
||||
return parent::__construct($message, $code, $previous);
|
||||
}
|
||||
public function getResourceId() { return $this->resource_id; }
|
||||
public function getResourceId() { return $this->id; }
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ class websocket_server {
|
||||
}
|
||||
}
|
||||
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request_header, $matches)) {
|
||||
throw new \RuntimeException("Invalid WebSocket handshake");
|
||||
throw new \invalid_handshake_exception($socket, "Invalid WebSocket handshake");
|
||||
}
|
||||
$key = trim($matches[1]);
|
||||
$accept_key = base64_encode(
|
||||
|
||||
@@ -528,15 +528,22 @@ class websocket_service extends service {
|
||||
if ($client_socket === $this->server_socket) {
|
||||
$conn = @stream_socket_accept($this->server_socket, 0);
|
||||
if ($conn) {
|
||||
// complete handshake on blocking socket
|
||||
stream_set_blocking($conn, true);
|
||||
$this->handshake($conn);
|
||||
// switch to non-blocking for further reads
|
||||
stream_set_blocking($conn, false);
|
||||
// add them to the websocket list
|
||||
$this->clients[] = $conn;
|
||||
// notify websocket on_connect listeners
|
||||
$this->trigger_connect($conn);
|
||||
try {
|
||||
// complete handshake on blocking socket
|
||||
stream_set_blocking($conn, true);
|
||||
$this->handshake($conn);
|
||||
// switch to non-blocking for further reads
|
||||
stream_set_blocking($conn, false);
|
||||
// add them to the websocket list
|
||||
$this->clients[] = $conn;
|
||||
// notify websocket on_connect listeners
|
||||
$this->trigger_connect($conn);
|
||||
} catch (invalid_handshake_exception $ex) {
|
||||
$resource = $ex->getResourceId();
|
||||
$this->warning('Invalid handshake from resource ' . $resource);
|
||||
$this->disconnect_client($resource);
|
||||
$this->warning('Disconnected resource ' . $resource);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -756,7 +763,7 @@ class websocket_service extends service {
|
||||
}
|
||||
}
|
||||
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request_header, $matches)) {
|
||||
throw new \RuntimeException("Invalid WebSocket handshake");
|
||||
throw new invalid_handshake_exception($resource, "Invalid WebSocket handshake");
|
||||
}
|
||||
$key = trim($matches[1]);
|
||||
$accept_key = base64_encode(
|
||||
|
||||
Reference in New Issue
Block a user