Future<WebSocket>
upgradeToWebSocket(HttpRequest request, [ dynamic protocolSelector(List<String> protocols), bool useStandardWebSocket ])
Source
static Future<WebSocket> upgradeToWebSocket(HttpRequest request, [
protocolSelector(List<String> protocols),
bool useStandardWebSocket
]) {
if (useStandardWebSocket == null) {
useStandardWebSocket = enableStandardWebSocket;
}
if (useStandardWebSocket) {
return WebSocketTransformer.upgrade(
request,
protocolSelector: protocolSelector
);
}
var response = request.response;
if (!WebSocketTransformer.isUpgradeRequest(request)) {
// Send error response.
response
..statusCode = HttpStatus.BAD_REQUEST
..close();
return new Future.error(
new WebSocketException("Invalid WebSocket upgrade request"));
}
Future<WebSocket> upgrade(String protocol) {
// Send the upgrade response.
response
..statusCode = HttpStatus.SWITCHING_PROTOCOLS
..headers.add(HttpHeaders.CONNECTION, "Upgrade")
..headers.add(HttpHeaders.UPGRADE, "websocket");
String key = request.headers.value("Sec-WebSocket-Key");
String 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.TCP_NODELAY, _tcpNoDelay);
return new 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 new Future(() => protocolSelector(protocols)).then((String protocol) {
if (protocols.indexOf(protocol) < 0) {
throw new WebSocketException(
"Selected protocol is not in the list of available protocols");
}
return protocol;
}).catchError((error) {
response
..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
..close();
throw error;
}).then((result) {
if (result is String) {
return upgrade(result);
}
return null;
}).then((WebSocket socket) {
return socket;
});
} else {
return upgrade(null);
}
}