Open AwaisKhan74 opened 9 months ago
I am getting this error: Bad response 'Sec-WebSocket-Accept' header
Here is my code snippet WebSocketChannel.connect(Uri.parse(wsUrl)); upoun debging websocket_impl.dart I found these values
nonce="cKPAQxX7w6REzh3smWpAYA==" accept="Kfh9QIsMVZcl6xEPYxPHzW8SZ8w="
Expected results It should compare accept and nonce and return true. As it is connecting to socket while connecting from postman or JS.
Actual results The fluter say bad request sec-websocket header. The List for expectedAccept and orignalAccept differ but thy shouldn't.
Code sample: WebSocketChannel.connect(Uri.parse(wsUrl)); values in headers are nonce="cKPAQxX7w6REzh3smWpAYA==" accept="Kfh9QIsMVZcl6xEPYxPHzW8SZ8w=" code from flutter to run is static Future connect( String url, Iterable? protocols, Map<String, dynamic>? headers, {CompressionOptions compression = CompressionOptions.compressionDefault, HttpClient? customClient}) { Uri uri = Uri.parse(url); if (!uri.isScheme("ws") && !uri.isScheme("wss")) { throw WebSocketException("Unsupported URL scheme '${uri.scheme}'"); }
Random random = Random(); // Generate 16 random bytes. Uint8List nonceData = Uint8List(16); for (int i = 0; i < 16; i++) { nonceData[i] = random.nextInt(256); } String nonce = base64Encode(nonceData); final callerStackTrace = StackTrace.current; uri = Uri( scheme: uri.isScheme("wss") ? "https" : "http", userInfo: uri.userInfo, host: uri.host, port: uri.port, path: uri.path, query: uri.query, fragment: uri.fragment); return (customClient ?? _httpClient).openUrl("GET", uri).then((request) { if (uri.userInfo != null && uri.userInfo.isNotEmpty) { // If the URL contains user information use that for basic // authorization. String auth = base64Encode(utf8.encode(uri.userInfo)); request.headers.set(HttpHeaders.authorizationHeader, "Basic $auth"); } if (headers != null) { headers.forEach((field, value) => request.headers.add(field, value)); } // Setup the initial handshake. request.headers ..set(HttpHeaders.connectionHeader, "Upgrade") ..set(HttpHeaders.upgradeHeader, "websocket") ..set("Sec-WebSocket-Key", nonce) ..set("Cache-Control", "no-cache") ..set("Sec-WebSocket-Version", "13"); if (protocols != null) { request.headers.add("Sec-WebSocket-Protocol", protocols.toList()); } if (compression.enabled) { request.headers .add("Sec-WebSocket-Extensions", compression._createHeader()); } return request.close(); }).then((response) { Future<WebSocket> error(String message) { // Flush data. response.detachSocket().then((socket) { socket.destroy(); }); return Future<WebSocket>.error( WebSocketException(message), callerStackTrace); } var connectionHeader = response.headers[HttpHeaders.connectionHeader]; if (response.statusCode != HttpStatus.switchingProtocols || connectionHeader == null || !connectionHeader.any((value) => value.toLowerCase() == "upgrade") || response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() != "websocket") { return error("Connection to '$uri' was not upgraded to websocket"); } String? accept = response.headers.value("Sec-WebSocket-Accept"); if (accept == null) { return error( "Response did not contain a 'Sec-WebSocket-Accept' header"); } _SHA1 sha1 = _SHA1(); sha1.add("$nonce$_webSocketGUID".codeUnits); List<int> expectedAccept = sha1.close(); List<int> receivedAccept = base64Decode(accept); if (expectedAccept.length != receivedAccept.length) { return error( "Response header 'Sec-WebSocket-Accept' is the wrong length"); } for (int i = 0; i < expectedAccept.length; i++) { if (expectedAccept[i] != receivedAccept[i]) { return error("Bad response 'Sec-WebSocket-Accept' header"); } } var protocol = response.headers.value('Sec-WebSocket-Protocol'); _WebSocketPerMessageDeflate? deflate = negotiateClientCompression(response, compression); return response.detachSocket().then<WebSocket>((socket) => _WebSocketImpl._fromSocket( socket, protocol, compression, false, deflate)); });
}
static _WebSocketPerMessageDeflate? negotiateClientCompression( HttpClientResponse response, CompressionOptions compression) { String extensionHeader = response.headers.value('Sec-WebSocket-Extensions') ?? "";
var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); if (compression.enabled && hv.value == PER_MESSAGE_DEFLATE) { var serverNoContextTakeover = hv.parameters.containsKey(_serverNoContextTakeover); var clientNoContextTakeover = hv.parameters.containsKey(_clientNoContextTakeover); int getWindowBits(String type) { var o = hv.parameters[type]; if (o == null) { return DEFAULT_WINDOW_BITS; } return int.tryParse(o) ?? DEFAULT_WINDOW_BITS; } return _WebSocketPerMessageDeflate( clientMaxWindowBits: getWindowBits(_clientMaxWindowBits), serverMaxWindowBits: getWindowBits(_serverMaxWindowBits), clientNoContextTakeover: clientNoContextTakeover, serverNoContextTakeover: serverNoContextTakeover); } return null;
I am getting this error: Bad response 'Sec-WebSocket-Accept' header
Here is my code snippet WebSocketChannel.connect(Uri.parse(wsUrl)); upoun debging websocket_impl.dart I found these values
nonce="cKPAQxX7w6REzh3smWpAYA==" accept="Kfh9QIsMVZcl6xEPYxPHzW8SZ8w="
Expected results It should compare accept and nonce and return true. As it is connecting to socket while connecting from postman or JS.
Actual results The fluter say bad request sec-websocket header. The List for expectedAccept and orignalAccept differ but thy shouldn't.
Code sample: WebSocketChannel.connect(Uri.parse(wsUrl)); values in headers are nonce="cKPAQxX7w6REzh3smWpAYA==" accept="Kfh9QIsMVZcl6xEPYxPHzW8SZ8w=" code from flutter to run is static Future connect(
String url, Iterable? protocols, Map<String, dynamic>? headers,
{CompressionOptions compression = CompressionOptions.compressionDefault,
HttpClient? customClient}) {
Uri uri = Uri.parse(url);
if (!uri.isScheme("ws") && !uri.isScheme("wss")) {
throw WebSocketException("Unsupported URL scheme '${uri.scheme}'");
}
}
static _WebSocketPerMessageDeflate? negotiateClientCompression( HttpClientResponse response, CompressionOptions compression) { String extensionHeader = response.headers.value('Sec-WebSocket-Extensions') ?? "";
}