websockets-rs / rust-websocket

A WebSocket (RFC6455) library written in Rust
http://websockets-rs.github.io/rust-websocket/
MIT License
1.55k stars 223 forks source link

`ClientBuilder` panics with "Status code must be Switching Protocols" #160

Open mitchmindtree opened 6 years ago

mitchmindtree commented 6 years ago

I'm currently attempting to use rust-websocket to connect to btcmarkets' websocket, however when building a rust-websocket client I get

thread 'btcmarkets' panicked at 'called `Result::unwrap()` on an `Err` value: ResponseError("Status code must be Switching Protocols")'

This is is the rust code I have for attempting to connect to the btcmarkets websocket:

        // Connect client.
        const CONNECTION: &'static str = "https://socket.btcmarkets.net";
        let client = ClientBuilder::new(CONNECTION)
            .unwrap()
            .connect_insecure()?;

I've tried adding "rust-websocket" and "websocket" protocols but the same error occurs. That said I don't really know what I'm doing with the add_protocol method or how protocols are used by websockets (this is my first time programatically connecting to a websocket).

I tried the example node.js code provided by btcmarkets and it seems to work fine - here's that code:

var socket = require('socket.io-client')('https://socket.btcmarkets.net', {secure: true, transports: ['websocket'], upgrade: false});
var instrument = 'BTC';
var currency = 'AUD';
var eventName = 'newTicker'; 
var channelName = 'Ticker-BTCMarkets-' + instrument + "-" + currency;

socket.on('connect', function(){
    console.log('connected');
    socket.emit('join', channelName);
});

socket.on(eventName, function(data){
    console.log(data);
});

socket.on('disconnect', function(){
    console.log('disconnected');
});

If you could offer any advice on the cause of this error and how I might work around it that would be greatly appreciated!

agyx commented 6 years ago

I managed to get it to work with this code:

let mut client = ClientBuilder::new(url)
        .unwrap()
        .connect(None)
        .unwrap();

ref: https://github.com/nstoddard/websocket-client/blob/master/src/lib.rs

JMLX42 commented 5 years ago

Same issue as @mitchmindtree here. The solution proposed by @agyx does not work.

JMLX42 commented 5 years ago

In my case, there were two mistakes on my end:

After fixing this, it works as expected!

Edit: using connect_insecure() I actually still get the panic. But connect(None) works. So @agyx comment does work.

vi commented 5 years ago

In any case it be usual error rather than panic. I though it was an unwrap inside rust-websocket code.

JMLX42 commented 5 years ago

I tried to do it with connect() by passing a custom TlsConnector but it fails with the same error:

let url = format!("wss://{}/live/{}?profile=owner", &client.backend, &file.unwrap().id);
let mut headers = Headers::new();
headers.set(Cookie(vec![client.auth_cookie.clone().unwrap()]));

let tls = TlsConnector::builder()
    .danger_accept_invalid_certs(client.insecure)
    .build()
    .unwrap();

debug!("connecting to {}", url);

let mut ws = ClientBuilder::new(url.as_str())
    .unwrap()
    .add_protocol("binary")
    .custom_headers(&headers)
    .connect(Some(tls))
    .unwrap();

debug!("successfully connected");
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ResponseError("Status code must be Switching Protocols")', src/libcore/result.rs:1009:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:72
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:60
             at src/libstd/panicking.rs:210
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:225
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:488
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:395
   6: rust_begin_unwind
             at src/libstd/panicking.rs:322
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:95
   8: core::result::unwrap_failed
             at /rustc/d99a320cba42f661aebfa1293b7b2ec3603dda75/src/libcore/macros.rs:26
   9: <core::result::Result<T, E>>::unwrap
             at /rustc/d99a320cba42f661aebfa1293b7b2ec3603dda75/src/libcore/result.rs:808
  10: <smartshape_cli::smartshape::cli::command::live::LiveListenCommand as smartshape_cli::smartshape::cli::command::Command>::run
             at src/smartshape/cli/command/live.rs:254
  11: smartshape_cli::main
             at src/main.rs:32
  12: std::rt::lang_start::{{closure}}
             at /rustc/d99a320cba42f661aebfa1293b7b2ec3603dda75/src/libstd/rt.rs:74
  13: std::panicking::try::do_call
             at src/libstd/rt.rs:59
             at src/libstd/panicking.rs:307
  14: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:102
  15: std::rt::lang_start_internal
             at src/libstd/panicking.rs:286
             at src/libstd/panic.rs:398
             at src/libstd/rt.rs:58
  16: std::rt::lang_start
             at /rustc/d99a320cba42f661aebfa1293b7b2ec3603dda75/src/libstd/rt.rs:74
  17: main
  18: __libc_start_main
  19: _start

The exact same code works with the same server code but with a "secured" connection (not self-signed certificates and client.insecure == false).

JMLX42 commented 5 years ago

@vi any idea of how we could solve this? Thank you for your help.

vi commented 5 years ago

@promethe42 Is the problem really client-side, not server-side?

Can it be reproduced with ws:// instead of wss://. If yes, a traffic dump is advice (can be captured in multiple ways).

JMLX42 commented 5 years ago

@vi since the exact same server code works when the SSL checks are enabled then I would say yes: the problem appears to be client side.

I'll try to get a dump to confirm it.

x1957 commented 5 years ago

Is there any update? I have the same problem.

jammymalina commented 5 years ago

Any update on this?