Actix-web: websocket problem with ssl(h2)

Created on 3 Sep 2019  路  10Comments  路  Source: actix/actix-web

i have a running actix server based on the websocket-chat example. everything works fine. but when i add ssl support, i can't connect with a client based on examples/websocket/src/client.rs. i get an error "Error: Tunnels are not supported for http2 connection". the browsers still work fine with h2. without ssl chrome is using http 1.1, with it h2. i now there was some problem with the websocket/h2 story in the past...

is there a way around this, or a way to force HttpServer or Client to use http 1.1 ?

Most helpful comment

Websockets must use http/1.1 as long as RFC8441 is not implemented. I assume we are waiting for https://github.com/hyperium/h2/issues/347? Firefox seems to support it by default. Roughly this should be the code for Rustls:

# rustls = "0.16"
# webpki-roots = "0.18"

let mut cfg = rustls::ClientConfig::new();
cfg.alpn_protocols = vec![b"http/1.1".to_vec()];
cfg.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let connector = awc::Connector::new().rustls(Arc::new(cfg)).finish();
let client = awc::ClientBuilder::new().connector(connector).finish();

client
    .ws("wss://[URL here]")
    .connect()
    .await;

All 10 comments

Is this actix-web client error?

yes. it's the Client::new().ws("https://foo/ws").connect()function that returns the error.

I am also suffering from the same issue.

  awc::Client::new()
            .ws("wss://stream.binance.com:9443/ws/btcusdt@trade")
            .connect()
            .map_err(|e| {
                println!("Error: {}", e);
            })

And posted in the gitter chat now before I saw this.

1006 would probably help

Same issue here. Versions:

$ grep actix Cargo.toml 
actix = "^0.8.3"
actix-rt = "^0.2.2"
actix-web = { version="^1.0.0", features=["ssl"] }
actix-codec = "^0.1.2"

Code:

const BITTREX_API: &'static str = "https://api.bittrex.com/v3";
...
    actix::Arbiter::spawn(lazy(|| {
        Client::new()
            .ws(BITTREX_API)
            .connect()
            .map_err(|e| {
                println!("Error: {}", e);
            })
            .map(|(response, framed)| {
                println!("{:?}", response);
                let (sink, stream) = framed.split();
                let addr = ChatClient::create(|ctx| {
                    ChatClient::add_stream(stream, ctx);
                    ChatClient(SinkWrite::new(sink, ctx))
                });
            })
    }));

Use custom connector to force HTTP 1.1 only in ALPN extension:

let ssl = {
    let mut ssl = openssl::ssl:SslConnector::builder(openssl::ssl:SslMethod::tls()).unwrap();
    let _ = ssl.set_alpn_protos(b"\x08http/1.1");
    ssl.build()
};
let connector = awc::Connector::new().ssl(ssl).finish();
awc::ClientBuilder::new()
    .connector(connector)
    .finish()
    .ws("wss://XXX");

If you're using rust-tls, take a look at actix-http/src/client/connector.rs and use the corresponding method to set ALPN.

Same issue here.

Snippet:

let client = awc::Client::new();

client
    .ws("wss://[URL here]")
    .connect()
    .await;

Versions in Cargo.toml:

actix-rt = "1.0"
awc = { version = "1.0", features = [ "rustls" ] }

Websockets must use http/1.1 as long as RFC8441 is not implemented. I assume we are waiting for https://github.com/hyperium/h2/issues/347? Firefox seems to support it by default. Roughly this should be the code for Rustls:

# rustls = "0.16"
# webpki-roots = "0.18"

let mut cfg = rustls::ClientConfig::new();
cfg.alpn_protocols = vec![b"http/1.1".to_vec()];
cfg.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let connector = awc::Connector::new().rustls(Arc::new(cfg)).finish();
let client = awc::ClientBuilder::new().connector(connector).finish();

client
    .ws("wss://[URL here]")
    .connect()
    .await;

Websockets must use http/1.1 as long as RFC8441 is not implemented. I assume we are waiting for hyperium/h2#347? Firefox seems to support it by default. Roughly this should be the code for Rustls:

# rustls = "0.16"
# webpki-roots = "0.18"

let mut cfg = rustls::ClientConfig::new();
cfg.alpn_protocols = vec![b"http/1.1".to_vec()];
cfg.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let connector = awc::Connector::new().rustls(Arc::new(cfg)).finish();
let client = awc::ClientBuilder::new().connector(connector).finish();

client
    .ws("wss://[URL here]")
    .connect()
    .await;

This works

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gh67uyyghj picture gh67uyyghj  路  3Comments

yoshrc picture yoshrc  路  5Comments

kocoten1992 picture kocoten1992  路  3Comments

naturallymitchell picture naturallymitchell  路  4Comments

Eilie picture Eilie  路  5Comments