From 816ca009b9024f7ca9b9be1897cb3705628c652c Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Wed, 26 Nov 2025 18:24:54 +0800 Subject: [PATCH] fix: gzip --- Cargo.lock | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/crypto.rs | 4 +- src/main.rs | 8 ++- src/proxy.rs | 45 ++++++++-------- 5 files changed, 171 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 524d527..22a372c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aes" version = "0.8.4" @@ -22,6 +28,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -37,6 +58,22 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "async-compression" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b37fc50485c4f3f736a4fb14199f6d5f5ba008d7f28fe710306c92780f004c07" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd", + "zstd-safe", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -122,6 +159,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.19.0" @@ -150,6 +208,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -203,6 +263,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -242,6 +311,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -636,6 +715,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.82" @@ -712,6 +801,15 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "1.1.0" @@ -741,6 +839,7 @@ dependencies = [ "serde_json", "thiserror", "tokio", + "tower-http", "tracing", "tracing-subscriber", ] @@ -810,6 +909,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "potential_utf" version = "0.1.4" @@ -968,9 +1073,11 @@ version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ + "async-compression", "base64", "bytes", "futures-core", + "futures-util", "http", "http-body", "http-body-util", @@ -990,6 +1097,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", + "tokio-util", "tower", "tower-http", "tower-service", @@ -1355,13 +1463,17 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ + "async-compression", "bitflags", "bytes", + "futures-core", "futures-util", "http", "http-body", "iri-string", "pin-project-lite", + "tokio", + "tokio-util", "tower", "tower-layer", "tower-service", @@ -1935,3 +2047,31 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 1da9f88..df5a200 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] axum = "0.8" tokio = { version = "1", features = ["full"] } +tower-http = { version = "0.6", features = ["compression-full"] } hyper = { version = "1", features = ["full"] } serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -19,4 +20,4 @@ anyhow = "1" thiserror = "2" http-body-util = "0.1.1" chrono = { version = "0.4", features = ["clock"] } -reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false } +reqwest = { version = "0.12", features = ["json", "rustls-tls", "gzip", "deflate"], default-features = false } diff --git a/src/crypto.rs b/src/crypto.rs index abcd642..b421d58 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,10 +1,10 @@ use std::fmt; use aes::Aes128; -use base64::{engine::general_purpose::STANDARD, Engine as _}; +use base64::{Engine as _, engine::general_purpose::STANDARD}; use cbc::{ - cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit}, Decryptor, + cipher::{BlockDecryptMut, KeyIvInit, block_padding::Pkcs7}, }; type Aes128CbcDec = Decryptor; diff --git a/src/main.rs b/src/main.rs index 4b07f8b..2298590 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ use std::{net::SocketAddr, sync::Arc}; use anyhow::Context; -use axum::{routing::any, Router}; +use axum::{Router, routing::any}; use dotenvy::dotenv; +use tower_http::compression::CompressionLayer; use tracing::{error, info, level_filters::LevelFilter}; -use tracing_subscriber::{fmt, prelude::*, EnvFilter}; +use tracing_subscriber::{EnvFilter, fmt, prelude::*}; mod crypto; mod proxy; @@ -54,6 +55,8 @@ async fn main() -> anyhow::Result<()> { // Create a reqwest client that ignores SSL certificate verification let client = reqwest::Client::builder() + .gzip(true) + .deflate(true) .danger_accept_invalid_certs(true) .build()?; @@ -68,6 +71,7 @@ async fn main() -> anyhow::Result<()> { // Build our application with a single route let app = Router::new() .route("/{*path}", any(proxy::proxy_handler)) + .layer(CompressionLayer::new().gzip(true)) .with_state(state); // Run the server diff --git a/src/proxy.rs b/src/proxy.rs index 9f301fc..b192522 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -10,7 +10,7 @@ use http_body_util::BodyExt; use serde_json::Value; use tracing::{error, info, warn}; -use crate::{crypto, AppState}; +use crate::{AppState, crypto}; pub async fn proxy_handler( State(state): State>, @@ -61,7 +61,7 @@ pub async fn proxy_handler( } }; - let (resp_parts, resp_body_bytes) = match clone_response(resp).await { + let (resp_parts, resp_body) = match clone_response(resp).await { Ok(tuple) => tuple, Err(_) => { return ( @@ -73,7 +73,7 @@ pub async fn proxy_handler( }; let decrypted_response_log = - match process_and_log_response(&resp_body_bytes, &state.key, &state.iv).await { + match process_and_log_response(&resp_body, &state.key, &state.iv).await { Ok(log) => log, Err(e) => { warn!("Failed to process response for logging: {}", e); @@ -93,7 +93,7 @@ pub async fn proxy_handler( *response_builder.headers_mut().unwrap() = resp_parts.headers; } response_builder - .body(axum::body::Body::from(resp_body_bytes)) + .body(axum::body::Body::from(resp_body)) .unwrap() } @@ -101,35 +101,32 @@ fn process_and_log_request(body_bytes: &Bytes, key: &str, iv: &str) -> anyhow::R let mut request_data: Value = serde_json::from_slice(body_bytes)?; if let Some(params_value) = request_data.get_mut("params") - && let Some(params_str) = params_value.as_str() { - let params_str_owned = params_str.to_string(); - match crypto::decrypt(¶ms_str_owned, key, iv) { - Ok(decrypted_str) => { - let decrypted_params: Value = serde_json::from_str(&decrypted_str) - .unwrap_or(Value::String(decrypted_str)); - *params_value = decrypted_params; - } - Err(e) => { - *params_value = Value::String(format!("decrypt failed: {}", e)); - } + && let Some(params_str) = params_value.as_str() + { + let params_str_owned = params_str.to_string(); + match crypto::decrypt(¶ms_str_owned, key, iv) { + Ok(decrypted_str) => { + let decrypted_params: Value = + serde_json::from_str(&decrypted_str).unwrap_or(Value::String(decrypted_str)); + *params_value = decrypted_params; + } + Err(e) => { + *params_value = Value::String(format!("decrypt failed: {}", e)); } } + } Ok(request_data) } -async fn process_and_log_response( - body_bytes: &Bytes, - key: &str, - iv: &str, -) -> anyhow::Result { - let decrypted = crypto::decrypt(std::str::from_utf8(body_bytes)?, key, iv)?; +async fn process_and_log_response(body_text: &str, key: &str, iv: &str) -> anyhow::Result { + let decrypted = crypto::decrypt(body_text, key, iv)?; let formatted: Value = serde_json::from_str(&decrypted)?; Ok(serde_json::to_string_pretty(&formatted)?) } async fn clone_response( resp: reqwest::Response, -) -> anyhow::Result<(axum::http::response::Parts, Bytes)> { +) -> anyhow::Result<(axum::http::response::Parts, String)> { let mut parts_builder = axum::http::response::Builder::new() .status(resp.status()) .version(resp.version()); @@ -138,7 +135,7 @@ async fn clone_response( *parts_builder.headers_mut().unwrap() = resp.headers().clone(); } let parts = parts_builder.body(())?.into_parts().0; - let body_bytes = resp.bytes().await?; + let body_text = resp.text().await?; - Ok((parts, body_bytes)) + Ok((parts, body_text)) }