Skip to content

Commit

Permalink
Fix gzip, and add gzip to client to server proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
NotReeceHarris committed Jan 21, 2025
1 parent 623298a commit 8679589
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 126 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cSpell.words": [
"flate",
"httparse",
"keepalive",
"pnet",
"reqwest",
"serde"
Expand Down
85 changes: 82 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ tokio = { version = "1.36", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
base64 = "0.22"
http = "1.2"
flate2 = "1.0"
httparse = "1.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
54 changes: 36 additions & 18 deletions client/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use flate2::read::{DeflateDecoder, GzDecoder};
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
use reqwest::Client;
use httparse::Request as HttpParseRequest;
use serde_json::json;
use std::io::Read;
use std::collections::HashMap;
use std::error::Error;
use serde::Deserialize;
Expand Down Expand Up @@ -118,6 +120,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Forward request to proxy server
match client.get(&proxy_url).send().await {
Ok(proxy_response) => {

let status = proxy_response.status();
println!("📥 Proxy response: {} {}",
status.as_u16(),
Expand All @@ -135,26 +138,41 @@ async fn main() -> Result<(), Box<dyn Error>> {
})
.collect();

if let Ok(body) = proxy_response.bytes().await {

let decoded = serde_json::from_slice::<ProxyResponse>(&body).unwrap();
let decoded_status = http::StatusCode::from_u16(decoded.status).unwrap();
let decoded_headers = decoded.headers.iter().map(|(k, v)| format!("{}: {}\r\n", k, v)).collect::<String>();
let decoded_body = BASE64.decode(&decoded.body).unwrap();
let content_encoding = proxy_response.headers().get(reqwest::header::CONTENT_ENCODING);
let mut decompressed_data = Vec::new();

// Handle different content encoding types (gzip, deflate)
match content_encoding.and_then(|v| v.to_str().ok()) {
Some("gzip") => {
let compressed_data = proxy_response.bytes().await.unwrap();
let mut decoder = GzDecoder::new(&compressed_data[..]);
decoder.read_to_end(&mut decompressed_data).unwrap();
}
Some("deflate") => {
let compressed_data = proxy_response.bytes().await.unwrap();
let mut decoder = DeflateDecoder::new(&compressed_data[..]);
decoder.read_to_end(&mut decompressed_data).unwrap();
}
_ => {
decompressed_data = proxy_response.bytes().await.unwrap().to_vec();
}
}

println!("📦 Response body size: {} bytes", body.len());
println!("{}", decoded_headers);
let decoded = serde_json::from_slice::<ProxyResponse>(&decompressed_data).unwrap();
let decoded_status = http::StatusCode::from_u16(decoded.status).unwrap();
let decoded_headers = decoded.headers.iter().map(|(k, v)| format!("{}: {}\r\n", k, v)).collect::<String>();
let decoded_body = BASE64.decode(&decoded.body).unwrap();

let status_line = format!(
"HTTP/1.1 {} {}\r\n",
decoded_status.as_u16(),
decoded_status.canonical_reason().unwrap_or("")
);
let _ = stream.write_all(status_line.as_bytes()).await;
let _ = stream.write_all(decoded_headers.as_bytes()).await;
let _ = stream.write_all(b"\r\n").await;
let _ = stream.write_all(&decoded_body).await;
}
let status_line = format!(
"HTTP/1.1 {} {}\r\n",
decoded_status.as_u16(),
decoded_status.canonical_reason().unwrap_or("")
);

let _ = stream.write_all(status_line.as_bytes()).await;
let _ = stream.write_all(decoded_headers.as_bytes()).await;
let _ = stream.write_all(b"\r\n").await;
let _ = stream.write_all(&decoded_body).await;

}
Err(e) => {
Expand Down
2 changes: 1 addition & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
tokio = { version = "1.36", features = ["full"] }
warp = "0.3"
warp = { version = "0.3", features = ["compression", "tls"] }
reqwest = { version = "0.12.12", default-features = false, features = ["blocking", "json"] }
base64 = "0.22.1"
serde = { version = "1.0", features = ["derive"] }
Expand Down
Loading

0 comments on commit 8679589

Please sign in to comment.