fix: update Content-Length header when MITM modifies request body

The MITM modifier kept original HTTP headers (including Content-Length)
when replacing the body. When injecting a ~200KB image into a ~66KB
request, Google would only read Content-Length bytes, then hang waiting
for a new request that never comes.

Now we regex-replace the Content-Length header value to match the actual
rechunked body size after modification.
This commit is contained in:
Nikketryhard
2026-02-15 18:02:13 -06:00
parent 89bea030cc
commit 1a6bfa5b53

View File

@@ -578,9 +578,13 @@ async fn handle_http_over_tls(
};
if let Some(modified_body) = super::modify::modify_request(&raw_body, tool_ctx.as_ref()) {
// Rebuild request_buf: original headers + rechunked modified body
// Rebuild request_buf: headers (with updated Content-Length) + rechunked modified body
let new_chunked = super::modify::rechunk(&modified_body);
let mut new_buf = request_buf[..headers_end].to_vec();
// Fix Content-Length header to match new body size
let header_str = String::from_utf8_lossy(&request_buf[..headers_end]);
let updated_headers = update_content_length(&header_str, new_chunked.len());
let mut new_buf = updated_headers.into_bytes();
new_buf.extend_from_slice(&new_chunked);
request_buf = new_buf;
}
@@ -1030,3 +1034,15 @@ fn parse_http_request_meta(buf: &[u8]) -> (usize, usize, bool) {
(headers_end, content_length, is_streaming)
}
/// Rewrite the Content-Length header in raw HTTP headers to match a new body size.
/// If no Content-Length header is found, returns the headers unchanged.
fn update_content_length(headers: &str, new_body_len: usize) -> String {
use regex::Regex;
let re = Regex::new(r"(?im)^content-length:\s*\d+").unwrap();
if re.is_match(headers) {
re.replace(headers, format!("Content-Length: {new_body_len}"))
.to_string()
} else {
headers.to_string()
}
}