ce0cbd552d
- Add missing nym-http-api-client dependencies to multiple crates - Add NymApiClientExt trait imports where needed - Fix type mismatches from NymApiClient to unified Client - Add error conversions for NymAPIError in various error enums - Implement missing trait methods (get_current_rewarded_set, get_all_basic_nodes_with_metadata, get_all_described_nodes) - Fix type conversions for RewardedSetResponse in network monitor - Update all API client instantiation to use new unified HTTP client
123 lines
3.3 KiB
Rust
123 lines
3.3 KiB
Rust
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
//! Utilities for and implementation of request tunneling
|
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use tracing::warn;
|
|
|
|
use crate::ClientBuilder;
|
|
|
|
// #[cfg(feature = "tunneling")]
|
|
#[derive(Debug)]
|
|
pub(crate) struct Front {
|
|
pub(crate) policy: FrontPolicy,
|
|
enabled: AtomicBool,
|
|
}
|
|
|
|
impl Clone for Front {
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
policy: self.policy.clone(),
|
|
enabled: AtomicBool::new(self.enabled.load(Ordering::Relaxed)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Front {
|
|
pub(crate) fn new(policy: FrontPolicy) -> Self {
|
|
Self {
|
|
enabled: AtomicBool::new(policy == FrontPolicy::Always),
|
|
policy,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn is_enabled(&self) -> bool {
|
|
match self.policy {
|
|
FrontPolicy::Off => false,
|
|
FrontPolicy::OnRetry => self.enabled.load(Ordering::Relaxed),
|
|
FrontPolicy::Always => true,
|
|
}
|
|
}
|
|
|
|
// Used to indicate that the client hit an error that should trigger the retry policy
|
|
// to enable fronting.
|
|
pub(crate) fn retry_enable(&self) {
|
|
if self.is_enabled() {
|
|
return;
|
|
}
|
|
if matches!(self.policy, FrontPolicy::OnRetry) {
|
|
self.enabled.store(true, Ordering::Relaxed);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Default, PartialEq, Clone)]
|
|
#[cfg(feature = "tunneling")]
|
|
/// Policy for when to use domain fronting for HTTP requests.
|
|
pub enum FrontPolicy {
|
|
/// Always use domain fronting for all requests.
|
|
Always,
|
|
/// Only use domain fronting when retrying failed requests.
|
|
OnRetry,
|
|
#[default]
|
|
/// Never use domain fronting.
|
|
Off,
|
|
}
|
|
|
|
impl ClientBuilder {
|
|
/// Enable and configure request tunneling for API requests.
|
|
#[cfg(feature = "tunneling")]
|
|
pub fn with_fronting(mut self, policy: FrontPolicy) -> Self {
|
|
let front = Front::new(policy);
|
|
|
|
// Check if any of the supplied urls even support fronting
|
|
if !self.urls.iter().any(|url| url.has_front()) {
|
|
warn!("fronting is enabled, but none of the supplied urls have configured fronting domains");
|
|
}
|
|
|
|
self.front = Some(front);
|
|
|
|
self
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::{ApiClientCore, Url, NO_PARAMS};
|
|
|
|
#[tokio::test]
|
|
async fn nym_api_works() {
|
|
let url1 = Url::new(
|
|
"https://validator.global.ssl.fastly.net",
|
|
Some(vec!["https://yelp.global.ssl.fastly.net"]),
|
|
)
|
|
.unwrap(); // fastly
|
|
|
|
// let url2 = Url::new(
|
|
// "https://validator.nymtech.net",
|
|
// Some(vec!["https://cdn77.com"]),
|
|
// ).unwrap(); // cdn77
|
|
|
|
let client = ClientBuilder::new::<_, &str>(url1)
|
|
.expect("bad url")
|
|
.with_fronting(FrontPolicy::Always)
|
|
.build::<&str>()
|
|
.expect("failed to build client");
|
|
|
|
let response = client
|
|
.send_request::<_, (), &str, &str, &str>(
|
|
reqwest::Method::GET,
|
|
&["api", "v1", "network", "details"],
|
|
NO_PARAMS,
|
|
None,
|
|
)
|
|
.await
|
|
.expect("failed get request");
|
|
|
|
// println!("{response:?}");
|
|
assert_eq!(response.status(), 200);
|
|
}
|
|
}
|