upgradeToWebSocket static method
Future<WebSocket>
upgradeToWebSocket(
- HttpRequest request, [
- dynamic protocolSelector()?,
- bool? useStandardWebSocket
Implementation
static Future<WebSocket> upgradeToWebSocket(
HttpRequest request, [
Function(List<String> protocols)? protocolSelector,
bool? useStandardWebSocket,
]) {
useStandardWebSocket ??= enableStandardWebSocket;
if (useStandardWebSocket) {
return WebSocketTransformer.upgrade(
request,
protocolSelector: protocolSelector,
);
}
var response = request.response;
if (!WebSocketTransformer.isUpgradeRequest(request)) {
// Send error response.
response
..statusCode = HttpStatus.badRequest
..close();
return Future.error(
WebSocketException('Invalid WebSocket upgrade request'),
);
}
Future<WebSocket> upgrade(String? protocol) {
// Send the upgrade response.
response
..statusCode = HttpStatus.switchingProtocols
..headers.add(HttpHeaders.connectionHeader, 'Upgrade')
..headers.add(HttpHeaders.upgradeHeader, 'websocket');
var key = request.headers.value('Sec-WebSocket-Key')!;
var accept = base64.encode(
sha1.convert('$key$_webSocketGUID'.codeUnits).bytes,
);
response.headers.add('Sec-WebSocket-Accept', accept);
if (protocol != null) {
response.headers.add('Sec-WebSocket-Protocol', protocol);
}
response.headers.contentLength = 0;
return response.detachSocket().then((socket) {
socket.setOption(SocketOption.tcpNoDelay, _tcpNoDelay);
return WebSocket.fromUpgradedSocket(
socket,
protocol: protocol,
serverSide: true,
);
});
}
var protocols = request.headers['Sec-WebSocket-Protocol'];
if (protocols != null && protocolSelector != null) {
// The suggested protocols can be spread over multiple lines, each
// consisting of multiple protocols. To unify all of them, first join
// the lists with ', ' and then tokenize.
protocols = HttpHelper.tokenizeFieldValue(protocols.join(', '));
return Future(
() => protocolSelector(protocols!)
.then((dynamic protocol) {
if (!protocols!.contains(protocol)) {
throw WebSocketException(
'Selected protocol is not in the list of available protocols',
);
}
return protocol;
})
.catchError((dynamic error) {
response
..statusCode = HttpStatus.internalServerError
..close();
throw error;
})
.then((dynamic result) {
if (result is String) {
return upgrade(result);
}
return null;
})
.then((WebSocket socket) {
return socket;
}),
);
} else {
return upgrade(null);
}
}