summaryrefslogtreecommitdiffhomepage
path: root/mullvad-api/src
diff options
context:
space:
mode:
authorJon Petersson <jon.petersson@mullvad.net>2025-03-10 13:45:43 +0100
committerJon Petersson <jon.petersson@mullvad.net>2025-03-31 11:39:29 +0200
commitefbb2c3c0c95f7e7a195c03e9d2483ec731a578e (patch)
treec297326cb661c12986e00c14ef8f47bd0cd37337 /mullvad-api/src
parent2640cd40b6a7a2468945b5c4c4be42bbe509c4e5 (diff)
downloadmullvadvpn-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.rs69
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>,