Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

Commit 95ceea0

Browse files
committed
Test the 64 KiB cap and timeout on serve GET error bodies
7fdad36 capped a serve GET's error body at 64 KiB and bounded its read by the body timeout, but the existing test only used caller caps under 64 KiB and never stalled, so it passed with or without the commit. Add a test for a >64 KiB body under a 1 MiB caller cap and one for a body that stalls after its headers; both fail without 7fdad36. Also update body_timeout's doc, which still said it bounds only the archive read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011f9aeS41XjBLw8LQsUUTYU
1 parent 7fdad36 commit 95ceea0

1 file changed

Lines changed: 63 additions & 1 deletion

File tree

‎crates/socket-patch-core/src/api/client.rs‎

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ pub struct VendorRetryPolicy {
340340
/// connect + response headers (a black-holed or stalled host fails the
341341
/// attempt instead of hanging the run).
342342
pub attempt_timeout: Duration,
343-
/// Bound on one archive GET's body read.
343+
/// Bound on one serve GET's body read (the archive/artifact bytes, or
344+
/// an error body).
344345
pub body_timeout: Duration,
345346
}
346347

@@ -2956,6 +2957,67 @@ mod patch_api_seam_tests {
29562957
let err = api.download_artifact(&url, 8).await.unwrap_err();
29572958
assert_eq!(err.to_string(), "artifact download failed with status 500");
29582959
}
2960+
2961+
/// An error body over 64 KiB is dropped even under a large caller cap,
2962+
/// so a hostile or broken server can't make the message huge.
2963+
#[tokio::test]
2964+
async fn trait_download_error_body_is_capped_at_64_kib() {
2965+
use wiremock::matchers::{method, path};
2966+
use wiremock::{Mock, MockServer, ResponseTemplate};
2967+
let server = MockServer::start().await;
2968+
Mock::given(method("GET"))
2969+
.and(path("/err.whl"))
2970+
.respond_with(ResponseTemplate::new(500).set_body_string("x".repeat(70 * 1024)))
2971+
.mount(&server)
2972+
.await;
2973+
let client = ApiClient::new(ApiClientOptions {
2974+
api_url: server.uri(),
2975+
api_token: None,
2976+
route: ApiRoute::Proxy,
2977+
})
2978+
.with_vendor_retry(VendorRetryPolicy::none());
2979+
let api: &dyn PatchApi = &client;
2980+
let url = format!("{}/err.whl", server.uri());
2981+
let err = api.download_artifact(&url, 1 << 20).await.unwrap_err();
2982+
assert_eq!(err.to_string(), "artifact download failed with status 500");
2983+
}
2984+
2985+
/// A stalled error body is dropped at the body timeout instead of
2986+
/// holding the attempt open.
2987+
#[tokio::test]
2988+
async fn trait_download_stalled_error_body_is_bounded_in_time() {
2989+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
2990+
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
2991+
let addr = listener.local_addr().unwrap();
2992+
tokio::spawn(async move {
2993+
let (mut sock, _) = listener.accept().await.unwrap();
2994+
let mut buf = [0u8; 4096];
2995+
let _ = sock.read(&mut buf).await;
2996+
let _ = sock
2997+
.write_all(
2998+
b"HTTP/1.1 503 Service Unavailable\r\nContent-Length: 100\r\n\r\npartial",
2999+
)
3000+
.await;
3001+
tokio::time::sleep(Duration::from_secs(20)).await;
3002+
});
3003+
let client = ApiClient::new(ApiClientOptions {
3004+
api_url: format!("http://{addr}"),
3005+
api_token: None,
3006+
route: ApiRoute::Proxy,
3007+
})
3008+
.with_vendor_retry(VendorRetryPolicy {
3009+
body_timeout: Duration::from_millis(300),
3010+
..VendorRetryPolicy::none()
3011+
});
3012+
let api: &dyn PatchApi = &client;
3013+
let started = std::time::Instant::now();
3014+
let err = api
3015+
.download_artifact(&format!("http://{addr}/err.whl"), 1 << 20)
3016+
.await
3017+
.unwrap_err();
3018+
assert!(started.elapsed() < Duration::from_secs(5));
3019+
assert_eq!(err.to_string(), "artifact download failed with status 503");
3020+
}
29593021
}
29603022

29613023
#[cfg(test)]

0 commit comments

Comments
 (0)