diff options
| author | Jon Petersson <jon.petersson@mullvad.net> | 2025-03-10 13:45:43 +0100 |
|---|---|---|
| committer | Jon Petersson <jon.petersson@mullvad.net> | 2025-03-31 11:39:29 +0200 |
| commit | efbb2c3c0c95f7e7a195c03e9d2483ec731a578e (patch) | |
| tree | c297326cb661c12986e00c14ef8f47bd0cd37337 /mullvad-api/src | |
| parent | 2640cd40b6a7a2468945b5c4c4be42bbe509c4e5 (diff) | |
| download | mullvadvpn-efbb2c3c0c95f7e7a195c03e9d2483ec731a578e.tar.xz mullvadvpn-efbb2c3c0c95f7e7a195c03e9d2483ec731a578e.zip | |
Implement call for getting relays on Rust side
Diffstat (limited to 'mullvad-api/src')
| -rw-r--r-- | mullvad-api/src/relay_list.rs | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/mullvad-api/src/relay_list.rs b/mullvad-api/src/relay_list.rs index f19961bc8a..2b34996c23 100644 --- a/mullvad-api/src/relay_list.rs +++ b/mullvad-api/src/relay_list.rs @@ -2,7 +2,7 @@ use crate::rest; -use hyper::{header, StatusCode}; +use hyper::{body::Incoming, header, Error, StatusCode}; use mullvad_types::{location, relay_list}; use talpid_types::net::wireguard; @@ -29,44 +29,57 @@ impl RelayListProxy { } /// Fetch the relay list - pub fn relay_list( + pub async fn relay_list( &self, etag: Option<String>, - ) -> impl Future<Output = Result<Option<relay_list::RelayList>, rest::Error>> + use<> { - let service = self.handle.service.clone(); - let request = self.handle.factory.get("app/v1/relays"); + ) -> Result<Option<relay_list::RelayList>, rest::Error> { + let response = self.relay_list_response(etag.clone()).await.map_err(rest::Error::from)?; - async move { - let mut request = request? - .timeout(RELAY_LIST_TIMEOUT) - .expected_status(&[StatusCode::NOT_MODIFIED, StatusCode::OK]); + if etag.is_some() && response.status() == StatusCode::NOT_MODIFIED { + return Ok(None); + } - if let Some(ref tag) = etag { - request = request.header(header::IF_NONE_MATCH, tag)?; - } + let etag = Self::extract_etag(&response); - let response = service.request(request).await?; - if etag.is_some() && response.status() == StatusCode::NOT_MODIFIED { - return Ok(None); - } + let relay_list: ServerRelayList = response.deserialize().await?; + Ok(Some(relay_list.into_relay_list(etag))) + } - let etag = response - .headers() - .get(header::ETAG) - .and_then(|tag| match tag.to_str() { - Ok(tag) => Some(tag.to_string()), - Err(_) => { - log::error!("Ignoring invalid tag from server: {:?}", tag.as_bytes()); - None - } - }); + pub async fn relay_list_response( + &self, + etag: Option<String>, + ) -> Result<rest::Response<Incoming>, rest::Error> { + let service = self.handle.service.clone(); + let request = self.handle.factory.get("app/v1/relays"); - let relay_list: ServerRelayList = response.deserialize().await?; - Ok(Some(relay_list.into_relay_list(etag))) + let mut request = request? + .timeout(RELAY_LIST_TIMEOUT) + .expected_status(&[StatusCode::NOT_MODIFIED, StatusCode::OK]); + + if let Some(ref tag) = etag { + request = request.header(header::IF_NONE_MATCH, tag)?; } + + let response = service.request(request).await?; + + Ok(response) + } + + pub fn extract_etag(response: &rest::Response<Incoming>) -> Option<String> { + response + .headers() + .get(header::ETAG) + .and_then(|tag| match tag.to_str() { + Ok(tag) => Some(tag.to_string()), + Err(_) => { + log::error!("Ignoring invalid tag from server: {:?}", tag.as_bytes()); + None + } + }) } } + #[derive(Debug, serde::Deserialize)] struct ServerRelayList { locations: BTreeMap<String, Location>, |
