webSocketAcceptKey function

String? webSocketAcceptKey(
  1. Request request
)

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);
}