webSocketAcceptKey function
The Sec-WebSocket-Accept value for request, or null when the
request is not a WebSocket opening handshake a server can accept
(RFC 6455 4.2.1).
That is a GET with Upgrade: websocket, Connection: Upgrade, version
13 and a key of 16 base64 bytes.
RelicServer answers a non-GET upgrade with 405 before calling this, so
the method check here serves direct callers.
Implementation
String? webSocketAcceptKey(Request request) {
if (request.method != Method.get) return null;
final headers = request.headers;
try {
final upgrade = headers.upgrade;
if (upgrade == null ||
!upgrade.protocols.any(
(p) => p.protocol.toLowerCase() == 'websocket',
)) {
return null;
}
final connection = headers.connection;
if (connection == null || !connection.isUpgrade) return null;
} on HeaderException {
return null;
}
if (headers.value(HeaderName.secWebsocketVersion)?.trim() != '13') {
return null;
}
final key = headers.value(HeaderName.secWebsocketKey)?.trim();
if (key == null) return null;
final Uint8List raw;
try {
raw = base64.decode(key);
} on FormatException {
return null;
}
if (raw.length != 16) return null;
return base64.encode(sha1.convert(utf8.encode('$key$_guid')).bytes);
}