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
- Login with
https://upstox.com/developer/api-documentation/authorize
- on backend it generates the oauth access token (success)
https://upstox.com/developer/api-documentation/get-token
- 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);