diff --git a/Cargo.toml b/Cargo.toml index 177387f..e00f849 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ path = "src/bin/main.rs" [dependencies] async-shared-timeout = "0.2" -base64 = "0.22" +base64easy = "0.1" bytes = "1" chrono = "0.4" clap = { version = "4", features = ["derive"] } diff --git a/src/base64_wrapper.rs b/src/base64_wrapper.rs deleted file mode 100644 index 4ae091e..0000000 --- a/src/base64_wrapper.rs +++ /dev/null @@ -1,32 +0,0 @@ -use base64::{engine::general_purpose, Engine as _}; - -/// The base64 encoding engine to use when encoding/decoding data. -#[derive(Debug, Clone, Copy)] -pub(crate) enum Base64Engine { - /// Base64 Standard - Standard, - /// Base64 StandardNoPad - StandardNoPad, - /// Base64 UrlSafe - UrlSafe, - /// Base64 UrlSafeNoPad - UrlSafeNoPad, -} - -pub(crate) fn base64_encode(bytes: &[u8], engine: Base64Engine) -> String { - match engine { - Base64Engine::Standard => general_purpose::STANDARD.encode(bytes), - Base64Engine::StandardNoPad => general_purpose::STANDARD_NO_PAD.encode(bytes), - Base64Engine::UrlSafe => general_purpose::URL_SAFE.encode(bytes), - Base64Engine::UrlSafeNoPad => general_purpose::URL_SAFE_NO_PAD.encode(bytes), - } -} - -pub(crate) fn base64_decode(b64str: &str, engine: Base64Engine) -> Result, base64::DecodeError> { - match engine { - Base64Engine::Standard => general_purpose::STANDARD.decode(b64str), - Base64Engine::StandardNoPad => general_purpose::STANDARD_NO_PAD.decode(b64str), - Base64Engine::UrlSafe => general_purpose::URL_SAFE.decode(b64str), - Base64Engine::UrlSafeNoPad => general_purpose::URL_SAFE_NO_PAD.decode(b64str), - } -} diff --git a/src/config.rs b/src/config.rs index 85021c4..c6e678a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -377,9 +377,9 @@ impl Config { /// load from `ssr://...` style url pub fn from_ssr_url(url: &str) -> Result { - let engine = crate::Base64Engine::UrlSafeNoPad; + let engine = base64easy::EngineKind::UrlSafeNoPad; let url = url.trim_start_matches("ssr://"); - let url = crate::base64_decode(url, engine)?; + let url = base64easy::decode(url, engine)?; let url = String::from_utf8(url)?; // split string by `/?` let mut parts = url.split("/?"); @@ -395,7 +395,7 @@ impl Config { let protocol = parts0.remove(0); let method = parts0.remove(0); // none is default let obfs = parts0.remove(0); - let password = String::from_utf8(crate::base64_decode(parts0.remove(0), engine)?)?; + let password = String::from_utf8(base64easy::decode(parts0.remove(0), engine)?)?; if method != "none" { return Err("method is not none".into()); @@ -423,14 +423,14 @@ impl Config { if ot_enable != "1" { return Err("ot_enable is not 1".into()); } - let remarks = map.get("remarks").and_then(|r| match crate::base64_decode(r, engine) { + let remarks = map.get("remarks").and_then(|r| match base64easy::decode(r, engine) { Ok(decoded) => match String::from_utf8(decoded) { Ok(string) => Some(string), Err(_) => None, }, Err(_) => None, }); - let ot_domain = map.get("ot_domain").and_then(|r| match crate::base64_decode(r, engine) { + let ot_domain = map.get("ot_domain").and_then(|r| match base64easy::decode(r, engine) { Ok(decoded) => match String::from_utf8(decoded) { Ok(string) => Some(string), Err(_) => None, @@ -438,11 +438,11 @@ impl Config { Err(_) => None, }); let ot_path = map.get("ot_path").ok_or("ot_path is not set")?; - let ot_path = String::from_utf8(crate::base64_decode(ot_path, engine)?)?; + let ot_path = String::from_utf8(base64easy::decode(ot_path, engine)?)?; let ot_cert = map .get("ot_cert") - .and_then(|r| crate::base64_decode(r, engine).ok()) + .and_then(|r| base64easy::decode(r, engine).ok()) .and_then(|decoded| String::from_utf8(decoded).ok()) .filter(|s| !s.is_empty()); @@ -466,16 +466,16 @@ impl Config { pub fn generate_ssr_url(&self) -> Result { let client = self.client.as_ref().ok_or(Error::from("client is not set"))?; - let engine = crate::Base64Engine::UrlSafeNoPad; + let engine = base64easy::EngineKind::UrlSafeNoPad; let method = self.method.as_ref().map_or("none".to_string(), |m| m.clone()); let password = self.password.as_ref().map_or("password".to_string(), |p| p.clone()); - let password = crate::base64_encode(password.as_bytes(), engine); + let password = base64easy::encode(password.as_bytes(), engine); let remarks = self.remarks.as_ref().map_or("remarks".to_string(), |r| r.clone()); - let remarks = crate::base64_encode(remarks.as_bytes(), engine); + let remarks = base64easy::encode(remarks.as_bytes(), engine); let domain = client.server_domain.as_ref().map_or("".to_string(), |d| d.clone()); - let domain = crate::base64_encode(domain.as_bytes(), engine); + let domain = base64easy::encode(domain.as_bytes(), engine); let err = "tunnel_path is not set"; - let tunnel_path = crate::base64_encode(self.tunnel_path.extract().first().ok_or(err)?.as_bytes(), engine); + let tunnel_path = base64easy::encode(self.tunnel_path.extract().first().ok_or(err)?.as_bytes(), engine); let host = &client.server_host; let port = client.server_port; @@ -483,11 +483,11 @@ impl Config { url.push_str(&format!("&ot_domain={domain}&ot_path={tunnel_path}")); if let Some(ref ca) = client.certificate_content() { - let ca = crate::base64_encode(ca.as_bytes(), engine); + let ca = base64easy::encode(ca.as_bytes(), engine); url.push_str(&format!("&ot_cert={}", ca)); } - Ok(format!("ssr://{}", crate::base64_encode(url.as_bytes(), engine))) + Ok(format!("ssr://{}", base64easy::encode(url.as_bytes(), engine))) } } diff --git a/src/error.rs b/src/error.rs index 17ad4fe..6f6df65 100644 --- a/src/error.rs +++ b/src/error.rs @@ -13,7 +13,7 @@ pub enum Error { Json(#[from] serde_json::Error), #[error("Base64 error: {0}")] - Base64(#[from] base64::DecodeError), + Base64(#[from] base64easy::Error), #[error("tokio::sync::mpsc::error::SendError {0}")] MpscSend(#[from] tokio::sync::mpsc::error::SendError<()>), diff --git a/src/lib.rs b/src/lib.rs index 69c22cb..1ac13e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ pub(crate) mod android; pub(crate) mod api; -pub(crate) mod base64_wrapper; pub(crate) mod client; pub(crate) mod cmdopt; pub(crate) mod config; @@ -18,7 +17,6 @@ pub(crate) mod weirduri; pub mod win_svc; pub use api::{over_tls_client_run, over_tls_client_run_with_ssr_url, over_tls_client_stop, overtls_free_string, overtls_generate_url}; -use base64_wrapper::{base64_decode, base64_encode, Base64Engine}; use bytes::BytesMut; pub use client::run_client; pub use cmdopt::{ArgVerbosity, CmdOpt, Role}; @@ -39,25 +37,25 @@ pub(crate) fn addess_to_b64str(addr: &Address, url_safe: bool) -> String { let mut buf = BytesMut::with_capacity(1024); addr.write_to_buf(&mut buf); if url_safe { - base64_encode(&buf, Base64Engine::UrlSafeNoPad) + base64easy::encode(&buf, base64easy::EngineKind::UrlSafeNoPad) } else { - base64_encode(&buf, Base64Engine::StandardNoPad) + base64easy::encode(&buf, base64easy::EngineKind::StandardNoPad) } } pub(crate) fn b64str_to_address(s: &str, url_safe: bool) -> Result
{ let buf = if url_safe { - let result = base64_decode(s, Base64Engine::UrlSafeNoPad); + let result = base64easy::decode(s, base64easy::EngineKind::UrlSafeNoPad); if result.is_err() { - base64_decode(s, Base64Engine::UrlSafe)? + base64easy::decode(s, base64easy::EngineKind::UrlSafe)? } else { result? } } else { - let result = base64_decode(s, Base64Engine::StandardNoPad); + let result = base64easy::decode(s, base64easy::EngineKind::StandardNoPad); if result.is_err() { // backward compatibility for SSRoT - base64_decode(s, Base64Engine::Standard)? + base64easy::decode(s, base64easy::EngineKind::Standard)? } else { result? }