Closed Alorel closed 11 months ago
This does not look like a bug on our side so far, though I wonder why it did not work on your side and if there are any specifics that your client stream expects (do you ensure that you read from the stream?). Have you checked what happens over the wire (with Wireshark or something)?
Also, I don't quite understand the step with a TLS connector - is there a reason to not use the provided client_async_tls()
?
If I work with the raw TCP stream and forego tungstenite, I'm able to write & flush the handshake headers, but not read the response.
Hmm, maybe this is the reason why tungstenite
does not work? 🙂 What happens when you try reading from the stream? Do you get any errors? - From your description, it looks like there is either a bug in a library that you're using or there is a certain bug in a user code (something that the library expects the user to perform in order to properly work).
I'm trying to make my websocket connection use Tor using arti-client and keep getting stuck on the handshake with
WebSocket protocol error: Handshake not finished
- could you point me in the right direction please?My understanding of Tungstenite's init process for wss endpoints, assuming
native-tls
is used:connect_async_with_config()
opens up a TCP connectionclient_async_tls_with_config()
wraps a tcp stream with a native tls connector & connects on the wrapperclient_async_with_config
which performs the handshakeTherefore, if I construct my Tor stream in place of the TCP stream, create the NativeTls connector myself, connect & pass that stream on to
client_async
(without_tls
) I should be able to connect to my wss endpoint the same way as with the regular tls connector, shouldn't I?The arti-client crate has an integration with
hyper
and an associated connector, but it uses APIs fromtls_api_native_tls
which don't appear to be compatible.Things I've confirmed to be working:
My connect code
```rust let (ws, _) = { let host = if let Some(host) = cfg.uri.authority() { host.as_str() } else { return Err(anyhow::Error::msg("URI missing host")); }; let port = if let Some(p) = cfg.uri.port() { p.as_u16() } else { 443 }; let mut req = Request::builder().uri(cfg.uri.clone()) .header::<_, &'static str>(header::USER_AGENT, USER_AGENT) .header::<_, &'static str>(header::UPGRADE, "websocket") .header::<_, &'static str>(header::CONNECTION, "Upgrade") .header::<_, &'static str>(header::SEC_WEBSOCKET_VERSION, "13") .header::<_, &str>(header::HOST, host) .header::<_, String>(header::SEC_WEBSOCKET_KEY, BASE64.encode(rand::random::<[u8; 16]>())); if let Some(c) = cfg.cookie { req = req.header::<_, String>(header::COOKIE, c); } let tls_stream = { let tor_stream = tor_client.connect((host, port)).await?; let tls_conn = TlsConnector::from(native_tls::TlsConnector::new()?); // wrap native tls in tokio-native-tls let tls_stream = tls_conn.connect(host, tor_stream).await?; MaybeTlsStream::NativeTls(tls_stream) }; tokio_tungstenite::client_async(req.body(())?, tls_stream) }.await?; // we time out here let (tx, rx) = ws.split(); ```If I work with the raw TCP stream and forego tungstenite, I'm able to write & flush the handshake headers, but not read the response.