From 92fc73756f000fcd168eb8b9e266844c79c9b489 Mon Sep 17 00:00:00 2001 From: ospab Date: Thu, 21 May 2026 13:06:06 +0300 Subject: [PATCH] fix: use POST and Content-Length in UoT to prevent nginx chunked encoding --- ostp-client/src/transport/xhttp.rs | 18 ++++++++++++++---- ostp-server/src/transport/uot.rs | 4 ++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ostp-client/src/transport/xhttp.rs b/ostp-client/src/transport/xhttp.rs index 1b240ef..0fd4ecf 100644 --- a/ostp-client/src/transport/xhttp.rs +++ b/ostp-client/src/transport/xhttp.rs @@ -71,17 +71,27 @@ pub async fn connect_xhttp( // 1. Generate auth token let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_secs(); + let ts_bytes = timestamp.to_be_bytes(); let mut mac = HmacSha256::new_from_slice(access_key).unwrap_or_else(|_| HmacSha256::new_from_slice(b"").unwrap()); - mac.update(×tamp.to_be_bytes()); - let sig = base64::prelude::BASE64_STANDARD.encode(mac.finalize().into_bytes()); - let auth_token = format!("{}:{}", timestamp, sig); + mac.update(&ts_bytes); + let mac_bytes = mac.finalize().into_bytes(); + + let mut sig_bytes = Vec::with_capacity(8 + mac_bytes.len()); + sig_bytes.extend_from_slice(&ts_bytes); + sig_bytes.extend_from_slice(&mac_bytes); + + let auth_token = base64::Engine::encode( + &base64::engine::general_purpose::STANDARD_NO_PAD, + &sig_bytes + ); let http_host = if sni.is_empty() { target_ip.to_string() } else { sni.to_string() }; let req = format!( - "GET /stream HTTP/1.1\r\n\ + "POST /stream HTTP/1.1\r\n\ Host: {}\r\n\ Authorization: Bearer {}\r\n\ + Content-Length: 99999999999\r\n\ Connection: keep-alive\r\n\ \r\n", http_host, auth_token diff --git a/ostp-server/src/transport/uot.rs b/ostp-server/src/transport/uot.rs index 5db49cf..04f05a1 100644 --- a/ostp-server/src/transport/uot.rs +++ b/ostp-server/src/transport/uot.rs @@ -38,7 +38,7 @@ pub async fn handle_tcp_connection( let headers_str = String::from_utf8_lossy(&buf[..header_len]); // Fast-fail scanner bots - if !headers_str.starts_with("GET /stream HTTP/1.1\r\n") { + if !headers_str.starts_with("POST /stream HTTP/1.1\r\n") { send_404(&mut stream).await?; anyhow::bail!("invalid request line"); } @@ -108,7 +108,7 @@ pub async fn handle_tcp_connection( } // Reply 200 OK - let response = "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\n\r\n"; + let response = "HTTP/1.1 200 OK\r\nContent-Length: 99999999999\r\nConnection: keep-alive\r\n\r\n"; stream.write_all(response.as_bytes()).await?; info!("UoT client authenticated from {}", peer_addr);