Websocket does not connect

I’m trying to connect to the market feed data websocket but it keeps giving 400 with the following body

body: "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>cloudflare</center>\r\n</body>\r\n</html>\r\n"


 Request: Request {
    method: GET,
    uri: wss://wsfeeder-api.upstox.com/market-data-feeder/v2/upstox-developer-api/feeds?requestId=<requestId_received>code=<CODE>,
    version: HTTP/1.1,
    headers: {
        "host": "https://api.upstox.com",
        "origin": "http://localhost:11004",
        "api-version": "2.0",
        "user-agent": "Mozilla/5.0",
        "accept": "*/*",
        "authorization": "Bearer <oauth_access_token>",
        "upgrade": "websocket",
        "connection": "upgrade",
        "sec-websocket-key": "<generated_key>",
        "sec-websocket-version": "13",
    },
    body: Empty,
}

Response: Response {
    status: 400,
    version: HTTP/1.1,
    headers: {
        "server": "cloudflare",
        "date": "Tue, 09 Jan 2024 21:35:33 GMT",
        "content-type": "text/html",
        "content-length": "155",
        "connection": "close",
        "cf-ray": "-",
    },
    body: Body(
        Streaming,
    ),
}

I have been trying for hours to try to get this to work to no avail.

Steps to reproduce

  1. Login with https://upstox.com/developer/api-documentation/authorize
  2. on backend it generates the oauth access token (success) https://upstox.com/developer/api-documentation/get-token
  3. get the wss url to subscribe to wss https://upstox.com/developer/api-documentation/get-market-data-feed-authorize, this part fails with 400

Following is the rust code i’m using

let wss_url =
        upstox_sdk::apis::websocket_api::get_market_data_feed_authorize(&global_upstox_config)
            .await
            .context("Failed to get market data feed")?
            .data
            .context("Could not get data from wss_redirect_url")?
            .authorized_redirect_uri
            .context("Could not get authorized_redirect_uri from wss_redirect_url")?;

    let domain = tokio_rustls::rustls::pki_types::ServerName::try_from("api.upstox.com")
        .context("Failed to parse domain")?;

    let tcp_stream = tokio::net::TcpStream::connect("api.upstox.com:443")
        .await
        .context("Failed to connect to tcp stream")?;

    let tls_connector = tls_connector().unwrap();

    let tls_stream = tls_connector
        .connect(domain, tcp_stream)
        .await
        .context("Failed to connect to tls stream")?;

    let req = hyper::Request::builder()
        .method("GET")
        .uri(&wss_url)
        .header("Host", &wss_url)
        .header(hyper::header::UPGRADE, "websocket")
        .header(hyper::header::CONNECTION, "upgrade")
        .header(
            "Sec-WebSocket-Key",
            fastwebsockets::handshake::generate_key(),
        )
        .header("Sec-WebSocket-Version", "13")
        .body(http_body_util::Empty::<bytes::Bytes>::new())
        .context("Failed to build request")?;

    let (mut sender, conn) =
        hyper::client::conn::http1::handshake(hyper_util::rt::TokioIo::new(tls_stream))
            .await
            .context("Failed to connect to websocket")?;
    let fut = Box::pin(async move {
        if let Err(e) = conn.with_upgrades().await {
            eprintln!("Error polling connection: {}", e);
        }
    });

    (&SpawnExecutor).execute(fut);

    let response = sender
        .send_request(req)
        .await
        .context("Failed to send request")?;

    tracing::info!("Response: {response:#?}");

    let frame_stream = response
        .into_body()
        .collect()
        .await
        .context("Failed to collect body")?
        .to_bytes();

    println!(
        "body: {:#?}",
        String::from_utf8(frame_stream.to_vec()).unwrap_or_default()
    );
    tracing::info!("Response body: {:#?}", frame_stream);

My guess is something on the api request is missing and thats why its getting rejected however i’ve been following the api docs to the tee. not sure what i’ve missed.

Thank you for contacting us. We’ll review the matter and respond accordingly. As we currently lack a readily available example of Rust WebSocket (unlike Python, Node, PHP, and Java), it might take us some time to prepare one. In the meantime, we suggest you briefly explore our existing example codes in other languages to see if anything correlates with your needs.

Hi thanks for replying. That makes sense, howere is there a way to see what’s wrong on the request so that I can be unblocked? I can help with writing up the websocket example in rust. What’s the wss port, I’m guessing it’s 443 as one is not specified in the URL. I’m pretty sure cloudflare logs will give you an idea of what’s missing or what I’m doing wrong.

I based my code off of the nodejs example code

Please provide your client ID. A representative will contact you from outside to discuss and arrange the subsequent steps.

Client Id: 5afd01ef-c976-4f78-8ac7-d0d8566d13ad

Any updates on this?

Hi @Deep_Vora - I will be calling you soon

Can we please use email or chat?

@Deep_Vora - Okay, can you help me with your email Id? will take this forward on emails

I’ve sent it to you on a message on this platform