seanmonstar / warp

A super-easy, composable, web server framework for warp speeds.
https://seanmonstar.com/post/176530511587/warp
MIT License
9.52k stars 714 forks source link

Different behaviour when using WebSockets with TLS #963

Open EricHier opened 2 years ago

EricHier commented 2 years ago

Version The output of cargo-tree tree | grep wrap: └── warp v0.3.2

Platform Darwin maries-mac 21.4.0 Darwin Kernel Version 21.4.0: Mon Feb 21 20:34:37 PST 2022; root:xnu-8020.101.4~2/RELEASE_X86_64 x86_64

Description We wrote a application having two routes, one WS route and one POST route. The routes work perfectly when TLS is disabled. When we enable TLS, a connection to the WS seemingly breaks the framework as no further connection of any kind is possible. To debug the bug, we implemented the warp::log::custom method to log all requests. No requests are logged after connecting with a WS to the application. We used Postman and the Python requests and websocket-client modules for our tests.

We tried this code:

[...]

#[tokio::main]
async fn main() {

    println!("Configuring websocket route");
    let ws_route = warp::path("ws")
        .and(warp::ws())
        .map(|ws: warp::ws::Ws| {
            ws.on_upgrade(move |socket| ws::client_connection(socket))
        });

    let change_state = warp::post()
        .and(warp::path("current"))
        .and(warp::body::bytes())
        .and_then(handlers::post_current);

    let incoming_log = warp::log::custom(|info| {
        eprintln!(
            "{} {} {} {:?}",
            info.method(),
            info.path(),
            info.status(),
            info.elapsed(),
        );
    });

    let routes = change_state.or(ws_route).with(warp::cors().allow_any_origin()).with(incoming_log);

    println!("Starting server");
    warp::serve(routes)
        .tls()
        .cert_path("./cert.crt")
        .key_path("./cert.key")
        .run(([0, 0, 0, 0], 8000)).await;
}

The full source code (besides the TLS keys of course) is available here.

seanmonstar commented 2 years ago

That seems odd. Could it be related to something happening inside ws::client_connection? Does the same problem happen if you use the websockets_chat example?

EricHier commented 2 years ago

We just tested your WS chat example and that does not work with TLS either. The webpage loads but it is not able to connect to the websocket.

EricHier commented 2 years ago

We only altered this line:

warp::serve(routes).tls().key_path("./cert.key").cert_path("./cert.crt").run(([127, 0, 0, 1], 3030)).await;
nyvs commented 2 years ago

I am having the same problem here. Using the websocket_chat app works fine, but tls doesn't work at all for me. Websocat prints something like this: websocat: WebSocket SSL error: error:1409441A:SSL routines:ssl3_read_bytes:tlsv1 alert decode error:ssl/record/rec_layer_s3.c:1543:SSL alert number 50

From microsoft.com:

50 decode_error A message could not be decoded because some field was out of the specified range or the length of the message was incorrect. This message is always fatal.

Also I need to say that I love the warp project, I am very thankful for it.

hongshengjie commented 1 year ago

I am having the same problem here.

GachiLord commented 10 months ago

Hello, is the issue still relevant on the latest version? I have same behaviour when I use port forwarding in vscode. But I am not sure it's warp's problem.