diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-11 16:03:03 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-15 19:18:32 +0100 |
| commit | 7dd8c0d8b8a1c0712887f09cd9708961a8516ea2 (patch) | |
| tree | 38c0724668349de3588de111f82749d90b9c2701 | |
| parent | 528b4c434cc2730681b637d3716facb0d9a78e9c (diff) | |
| download | mullvadvpn-7dd8c0d8b8a1c0712887f09cd9708961a8516ea2.tar.xz mullvadvpn-7dd8c0d8b8a1c0712887f09cd9708961a8516ea2.zip | |
Add etag argument to the relay list RPC
| -rw-r--r-- | mullvad-daemon/src/relays.rs | 11 | ||||
| -rw-r--r-- | mullvad-rpc/src/bin/relay_list.rs | 2 | ||||
| -rw-r--r-- | mullvad-rpc/src/relay_list.rs | 38 | ||||
| -rw-r--r-- | mullvad-types/src/relay_list.rs | 2 |
4 files changed, 41 insertions, 12 deletions
diff --git a/mullvad-daemon/src/relays.rs b/mullvad-daemon/src/relays.rs index c3c2e7e365..ee53b7dde2 100644 --- a/mullvad-daemon/src/relays.rs +++ b/mullvad-daemon/src/relays.rs @@ -826,7 +826,7 @@ impl RelayListUpdater { cmd = cmd_rx.next() => { match cmd { Some(_) => { - self.consume_new_relay_list(self.rpc_client.relay_list().await).await; + self.consume_new_relay_list(self.rpc_client.relay_list(None).await).await; }, None => { log::error!("Relay list updater shutting down"); @@ -841,14 +841,15 @@ impl RelayListUpdater { async fn consume_new_relay_list( &mut self, - result: Result<RelayList, mullvad_rpc::rest::Error>, + result: Result<Option<RelayList>, mullvad_rpc::rest::Error>, ) { match result { - Ok(relay_list) => { + Ok(Some(relay_list)) => { if let Err(err) = self.update_cache(relay_list).await { log::error!("Failed to update relay list cache: {}", err); } } + Ok(None) => log::debug!("Relay list is up-to-date"), Err(err) => { log::error!( "Failed to fetch new relay list: {}. Will retry in {} minutes", @@ -875,8 +876,8 @@ impl RelayListUpdater { fn download_relay_list( rpc_handle: RelayListProxy, - ) -> impl Future<Output = Result<RelayList, mullvad_rpc::rest::Error>> + 'static { - let download_futures = move || rpc_handle.relay_list(); + ) -> impl Future<Output = Result<Option<RelayList>, mullvad_rpc::rest::Error>> + 'static { + let download_futures = move || rpc_handle.relay_list(None); let exponential_backoff = ExponentialBackoff::from_millis(EXPONENTIAL_BACKOFF_DELAY_MS) .factor(EXPONENTIAL_BACKOFF_FACTOR) diff --git a/mullvad-rpc/src/bin/relay_list.rs b/mullvad-rpc/src/bin/relay_list.rs index 8213d736da..e3ca00a9bc 100644 --- a/mullvad-rpc/src/bin/relay_list.rs +++ b/mullvad-rpc/src/bin/relay_list.rs @@ -10,7 +10,7 @@ async fn main() { MullvadRpcRuntime::new(tokio::runtime::Handle::current()).expect("Failed to load runtime"); let relay_list_request = RelayListProxy::new(runtime.mullvad_rest_handle()) - .relay_list() + .relay_list(None) .await; let relay_list = match relay_list_request { diff --git a/mullvad-rpc/src/relay_list.rs b/mullvad-rpc/src/relay_list.rs index b6784d3fda..cdf72c8c1f 100644 --- a/mullvad-rpc/src/relay_list.rs +++ b/mullvad-rpc/src/relay_list.rs @@ -1,7 +1,7 @@ /// A module dedicated to retrieving the relay list from the master API. use crate::rest; -use hyper::{Method, StatusCode}; +use hyper::{header, Method, StatusCode}; use mullvad_types::{location, relay_list}; use talpid_types::net::wireguard; @@ -27,7 +27,10 @@ impl RelayListProxy { } /// Fetch the relay list - pub fn relay_list(&self) -> impl Future<Output = Result<relay_list::RelayList, rest::Error>> { + pub fn relay_list( + &self, + etag: Option<String>, + ) -> impl Future<Output = Result<Option<relay_list::RelayList>, rest::Error>> { let service = self.handle.service.clone(); let request = self.handle.factory.request("/v1/relays", Method::GET); @@ -35,13 +38,35 @@ impl RelayListProxy { let mut request = request?; request.set_timeout(RELAY_LIST_TIMEOUT); + let has_tag = etag.is_some(); + if let Some(tag) = etag { + request.add_header("If-None-Match", tag)?; + } + let response = service.request(request).await?; + if has_tag && response.status() == StatusCode::NOT_MODIFIED { + return Ok(None); + } if response.status() != StatusCode::OK { return rest::handle_error_response(response).await; } - Ok(rest::deserialize_body::<ServerRelayList>(response) - .await? - .into_relay_list()) + + 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 + } + }); + + Ok(Some( + rest::deserialize_body::<ServerRelayList>(response) + .await? + .into_relay_list(etag), + )) }; future } @@ -57,7 +82,7 @@ struct ServerRelayList { } impl ServerRelayList { - fn into_relay_list(self) -> relay_list::RelayList { + fn into_relay_list(self, etag: Option<String>) -> relay_list::RelayList { let mut countries = BTreeMap::new(); let Self { locations, @@ -90,6 +115,7 @@ impl ServerRelayList { relay_list::RelayList { + etag, countries: countries .into_iter() .map(|(_key, country)| country) diff --git a/mullvad-types/src/relay_list.rs b/mullvad-types/src/relay_list.rs index c3bbc33b6f..863e704792 100644 --- a/mullvad-types/src/relay_list.rs +++ b/mullvad-types/src/relay_list.rs @@ -21,12 +21,14 @@ use talpid_types::net::{ #[cfg_attr(target_os = "android", derive(IntoJava))] #[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct RelayList { + pub etag: Option<String>, pub countries: Vec<RelayListCountry>, } impl RelayList { pub fn empty() -> Self { Self { + etag: None, countries: Vec::new(), } } |
