use async_trait::async_trait;
use super::{Provider, ServerInfo};
pub struct CloudflareProvider {
base_url: String,
}
impl CloudflareProvider {
pub fn new() -> Self {
Self {
base_url: "https://speed.cloudflare.com".to_string(),
}
}
}
impl Default for CloudflareProvider {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl Provider for CloudflareProvider {
fn name(&self) -> &str {
"Cloudflare"
}
fn get_download_url(&self) -> String {
format!("{}/__down", self.base_url)
}
fn get_upload_url(&self) -> String {
format!("{}/__up", self.base_url)
}
fn get_ping_url(&self) -> String {
self.base_url.clone()
}
async fn get_servers(&self) -> anyhow::Result<Vec<ServerInfo>> {
Ok(vec![ServerInfo {
id: "cloudflare".to_string(),
name: "Cloudflare Edge".to_string(),
location: "Anycast".to_string(),
country: "Global".to_string(),
host: self.base_url.clone(),
latency_ms: None,
}])
}
async fn select_best_server(&self) -> anyhow::Result<Option<ServerInfo>> {
let mut server = ServerInfo {
id: "cloudflare".to_string(),
name: "Cloudflare Edge".to_string(),
location: "Anycast".to_string(),
country: "Global".to_string(),
host: self.base_url.clone(),
latency_ms: None,
};
if let Ok(ping) = crate::network::ping::single_ping(&self.base_url).await {
server.latency_ms = Some(ping);
}
Ok(Some(server))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cloudflare_urls() {
let provider = CloudflareProvider::new();
assert_eq!(
provider.get_download_url(),
"https://speed.cloudflare.com/__down"
);
assert_eq!(
provider.get_upload_url(),
"https://speed.cloudflare.com/__up"
);
}
#[tokio::test]
async fn test_cloudflare_servers() {
let provider = CloudflareProvider::new();
let servers = provider.get_servers().await.unwrap();
assert_eq!(servers.len(), 1);
}
}