proxy_fetch 0.1.12

A smart proxy management library for Rust, engineered for high-availability and fault-tolerant network requests. / 一个为 Rust 设计的智能代理管理库,专为高可用和容错的网络请求而构建。
Documentation
use std::{sync::Arc, time::Duration};

use base64::{engine::general_purpose::STANDARD, Engine as _};
use futures::future;
use log::{info, warn};
use reqwest::Url;
use url_fmt::url_fmt;
use zset::{Api, Zset};

use crate::{error::Result, proxy::Proxy};

pub async fn refresh(
  subscription_url: Url,
  proxy_zset: Arc<Zset<String, Proxy, i64>>,
) -> Result<()> {
  let client = reqwest::Client::builder()
    .redirect(reqwest::redirect::Policy::limited(10))
    .danger_accept_invalid_certs(true)
    .build()?;

  match client.get(subscription_url.clone()).send().await {
    Ok(resp) => {
      if let Ok(body) = resp.text().await {
        let decoded = STANDARD.decode(body)?;
        let decoded = String::from_utf8_lossy(&decoded);
        for ss_url in decoded.lines() {
          let name = url_fmt(ss_url);
          if !proxy_zset.contains(&name) {
            if let Ok(proxy) = Proxy::new(&name, ss_url) {
              info!("+ {}", name);
              proxy_zset.add(proxy, 0);
            }
          }
        }
      }
    }
    Err(err) => {
      warn!("{subscription_url} : {}", err);
    }
  }
  Ok(())
}

pub async fn refresh_li(
  subscription_ss_li: &[Url],
  proxy_zset: Arc<Zset<String, Proxy, i64>>,
) -> Result<()> {
  loop {
    future::join_all(subscription_ss_li.iter().map(|url| {
      let proxy_zset = Arc::clone(&proxy_zset);
      async move { xerr::log!(refresh(url.clone(), proxy_zset).await) }
    }))
    .await;

    if proxy_zset.is_empty() {
      warn!("ss subscription is empty");
      tokio::time::sleep(Duration::from_secs(1)).await;
    } else {
      break;
    }
  }
  Ok(())
}