diff --git a/core/kordophone/src/api/http_client.rs b/core/kordophone/src/api/http_client.rs index c28c952..537d495 100644 --- a/core/kordophone/src/api/http_client.rs +++ b/core/kordophone/src/api/http_client.rs @@ -397,62 +397,64 @@ impl APIInterface for HTTPAPIClient { let uri = self .uri_for_endpoint(&endpoint, Some(self.websocket_scheme()))?; - log::debug!("Connecting to websocket: {:?}", uri); + loop { + log::debug!("Connecting to websocket: {:?}", uri); - let auth = self.auth_store.get_token().await; - let host = uri.authority().unwrap().host(); - let mut request = TungsteniteRequest::builder() - .header("Host", host) - .header("Connection", "Upgrade") - .header("Upgrade", "websocket") - .header("Sec-WebSocket-Version", "13") - .header("Sec-WebSocket-Key", generate_key()) - .uri(uri.to_string()) - .body(()) - .expect("Unable to build websocket request"); + let auth = self.auth_store.get_token().await; + let host = uri.authority().unwrap().host(); + let mut request = TungsteniteRequest::builder() + .header("Host", host) + .header("Connection", "Upgrade") + .header("Upgrade", "websocket") + .header("Sec-WebSocket-Version", "13") + .header("Sec-WebSocket-Key", generate_key()) + .uri(uri.to_string()) + .body(()) + .expect("Unable to build websocket request"); - match &auth { - Some(token) => { - request.headers_mut().insert( - "Authorization", - format!("Bearer: {}", token).parse().unwrap(), - ); + match &auth { + Some(token) => { + request.headers_mut().insert( + "Authorization", + format!("Bearer: {}", token).parse().unwrap(), + ); + } + None => { + log::warn!(target: "websocket", "Proceeding without auth token."); + } } - None => { - log::warn!(target: "websocket", "Proceeding without auth token."); - } - } - log::debug!("Websocket request: {:?}", request); + log::debug!("Websocket request: {:?}", request); - match connect_async(request).await.map_err(Error::from) { - Ok((socket, response)) => { - log::debug!("Websocket connected: {:?}", response.status()); - Ok(WebsocketEventSocket::new(socket)) - } - Err(e) => match &e { - Error::ClientError(ce) => match ce.as_str() { - "HTTP error: 401 Unauthorized" | "Unauthorized" => { - // Try to authenticate - if let Some(credentials) = &self.auth_store.get_credentials().await { - log::warn!("Websocket connection failed, attempting to authenticate"); - let new_token = self.authenticate(credentials.clone()).await?; - self.auth_store.set_token(new_token.to_string()).await; + match connect_async(request).await.map_err(Error::from) { + Ok((socket, response)) => { + log::debug!("Websocket connected: {:?}", response.status()); + break Ok(WebsocketEventSocket::new(socket)) + } + Err(e) => match &e { + Error::ClientError(ce) => match ce.as_str() { + "HTTP error: 401 Unauthorized" | "Unauthorized" => { + // Try to authenticate + if let Some(credentials) = &self.auth_store.get_credentials().await { + log::warn!("Websocket connection failed, attempting to authenticate"); + let new_token = self.authenticate(credentials.clone()).await?; + self.auth_store.set_token(new_token.to_string()).await; - // try again on the next attempt. - return Err(Error::Unauthorized); - } else { - log::error!("Websocket unauthorized, no credentials provided"); - return Err(Error::ClientError( - "Unauthorized, no credentials provided".into(), - )); + // try again on the next attempt. + continue; + } else { + log::error!("Websocket unauthorized, no credentials provided"); + break Err(Error::ClientError( + "Unauthorized, no credentials provided".into(), + )); + } } - } - _ => Err(e), - }, + _ => break Err(e), + }, - _ => Err(e), - }, + _ => break Err(e), + }, + } } } }