Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mitchmindtree opened this issue Jan 14, 2018 · 10 comments
Open

Comments

@mitchmindtree
Copy link

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
Copy link

agyx commented Oct 22, 2018

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
Copy link

JMLX42 commented Jan 9, 2019

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

@JMLX42
Copy link

JMLX42 commented Jan 9, 2019

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

  • my WSS URL was missing a get parameter
  • I forgot to call add_protocol() to specify the WebSocket protocol

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
Copy link
Member

vi commented Jan 10, 2019

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

@JMLX42
Copy link

JMLX42 commented Jan 10, 2019

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
Copy link

JMLX42 commented Jan 24, 2019

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

@vi
Copy link
Member

vi commented Jan 24, 2019

@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
Copy link

JMLX42 commented Jan 25, 2019

@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
Copy link
Contributor

x1957 commented Mar 31, 2019

Is there any update? I have the same problem.

@jammymalina
Copy link

Any update on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants