phasync
WebSocket / handshake

Method

WebSocket::handshake

For framework adapters: decide a handshake from the parts of any request, answering nothing.

Description#

public static WebSocket::handshake(
    string $method,
    string $version,
    array $headers,
    bool $hasBody,
    array $subprotocols = [],
    ?array $origins = null
): WebSocketHandshake

WebSocket::from and WebSocket::accept are this decision on a ClientRequest, so an adapter whose framework has its own request object (PSR-7, Symfony) gets the same answer, byte for byte: it sends a refusal as an ordinary response, which the framework's middleware may decorate, and for an acceptance it returns a 101 response with these headers and, when the connection reaches swerve, hands it to WebSocket::upgrade. Applications use from() and don't call this.

Parameters#

$method string
The request method
$version string
The HTTP version without the prefix: '1.1'
$headers array
The request headers: lowercase name => the values, in order, as ClientRequest::getRequestHeaders
$hasBody bool
Whether the request has a body (a handshake has none)
$subprotocols array = []
See accept()
$origins ?array = null
See accept()

Return values#

WebSocketHandshake

Examples#

Example 1Decisions for four requests
use Swerve\WebSocket;

$websocket = [
    'host'                  => ['example.com'],
    'upgrade'               => ['websocket'],
    'connection'            => ['Upgrade'],
    'sec-websocket-key'     => ['dGhlIHNhbXBsZSBub25jZQ=='],
    'sec-websocket-version' => ['13'],
    'sec-websocket-protocol' => ['chat.v2, chat.v1'],
];
$requests = [
    'a WebSocket handshake' => $websocket,
    'a plain GET'           => ['host' => ['example.com']],
    'a wrong version'       => ['sec-websocket-version' => ['8']] + $websocket,
    'a foreign origin'      => ['origin' => ['https://evil.example']] + $websocket,
];
foreach ($requests as $what => $headers) {
    $decision = WebSocket::handshake('GET', '1.1', $headers, false, subprotocols: ['chat.v1'], origins: ['https://example.com']);
    echo str_pad($what, 24), $decision->status, ' ', $decision->subprotocol ?? $decision->body, "\n";
}
Output
a WebSocket handshake   101 chat.v1
a plain GET             426 This address speaks WebSocket
a wrong version         400 Not a WebSocket handshake
a foreign origin        403 This origin may not connect