#Secure websocket server in Axum

9 messages · Page 1 of 1 (latest)

orchid wadi
#

How can I make a websocket server in axum that accepts secure connections? Currently I just have something that's mostly copied from the chat example:

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let app = Router::new().route("/websocket", get(websocket_handler));
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    Server::bind(&addr)
        .serve(app.into_make_service_with_connect_info::<SocketAddr>())
        .await?;
    Ok(())
}

async fn websocket_handler(
    ws: WebSocketUpgrade,
    ConnectInfo(ip_address): ConnectInfo<SocketAddr>,
) -> impl IntoResponse {
    ws.on_upgrade(move |socket| {
        let (sender, receiver) = socket.split();
        let user = UserWithSocket {
            user: User::Uninitialized,
            sender,
            receiver,
            ip_address,
        };
        websocket(user)
    })
}

async fn websocket(mut user: UserWithSocket) {
    println!("{} connected", user.ip_address);

    while let Some(Ok(msg)) = user.receiver.next().await {
        if process_websocket_message(msg, &mut user).await.is_break() {
            break;
        }
    }

    println!("{} disconnected", user.ip_address);
}

and it works fine when I try to connect to ws://127.0.0.1:3000/websocket but if I try to use a secure connection by changing ws to wss then I can't connect. How can I allow secure connections? I can't find anything about this anywhere online or in the documentation

left blade
left blade
orchid wadi
#


const HTTP_PORT: u16 = 7878;
const HTTPS_PORT: u16 = 3000;

async fn redirect_http_to_https() {
    fn make_https(host: String, uri: Uri) -> Result<Uri, BoxError> {
        let mut parts = uri.into_parts();

        parts.scheme = Some(axum::http::uri::Scheme::HTTPS);

        if parts.path_and_query.is_none() {
            parts.path_and_query = Some("/".parse().unwrap());
        }

        let https_host = host.replace(&HTTP_PORT.to_string(), &HTTPS_PORT.to_string());
        parts.authority = Some(https_host.parse()?);

        Ok(Uri::from_parts(parts)?)
    }

    let redirect = move |Host(host): Host, uri: Uri| async move {
        match make_https(host, uri) {
            Ok(uri) => Ok(Redirect::permanent(&uri.to_string())),
            Err(_) => Err(StatusCode::BAD_REQUEST),
        }
    };

    let addr = SocketAddr::from(([127, 0, 0, 1], HTTP_PORT));

    Server::bind(&addr)
        .serve(redirect.into_make_service())
        .await
        .unwrap();
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    dotenvy::dotenv()?;
    tokio::spawn(redirect_http_to_https());

    let config = RustlsConfig::from_pem_file(
        PathBuf::from(std::env::var("CERT_DIR")?).join("cert.pem"),
        PathBuf::from(std::env::var("CERT_DIR")?).join("key.pem"),
    )
    .await?;

    let app = Router::new().route("/websocket", get(websocket_handler));

    let addr = SocketAddr::from(([127, 0, 0, 1], HTTPS_PORT));
    axum_server::bind_rustls(addr, config)
        .serve(app.into_make_service_with_connect_info::<SocketAddr>())
        .await?;

    Ok(())
}
left blade
orchid wadi
#

nothing

#

well just Firefox can’t establish a connection to the server at wss://127.0.0.1:3000/websocket. which is the same as what i got before, and the same as when the server isn't running at all

#

anyway i'm going to ask in the tokio server