Skip to content

Commit 03c15d9

Browse files
committed
Add automatic retry for stale pooled connections on send
When a pooled connection fails during send_http_request(), automatically: 1. Destroy the stale connection 2. Create a fresh connection (with TLS if needed) 3. Retry sending once This fixes the flaky test_patch_request failure in CI where connections from the pool were occasionally dead/stale. The retry logic matches the existing retry behavior for recv failures. Fixes: httpmorph._client_c.ConnectionError: Failed to send request
1 parent 6cb0fa9 commit 03c15d9

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

src/core/httpmorph.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,9 +2228,48 @@ httpmorph_response_t* httpmorph_request_execute(
22282228
/* 3. Send HTTP/1.x Request */
22292229
bool using_proxy = (request->proxy_url != NULL);
22302230
if (send_http_request(ssl, sockfd, request, host, path, scheme, port, using_proxy, proxy_user, proxy_pass) != 0) {
2231-
response->error = HTTPMORPH_ERROR_NETWORK;
2232-
response->error_message = strdup("Failed to send request");
2233-
goto cleanup;
2231+
/* If send failed on a pooled connection, retry with fresh connection */
2232+
if (pooled_conn) {
2233+
/* Destroy the stale pooled connection */
2234+
pool_connection_destroy(pooled_conn);
2235+
pooled_conn = NULL;
2236+
sockfd = -1;
2237+
ssl = NULL;
2238+
2239+
/* Create new connection */
2240+
sockfd = tcp_connect(host, port, request->timeout_ms, &connect_time);
2241+
if (sockfd < 0) {
2242+
response->error = HTTPMORPH_ERROR_NETWORK;
2243+
response->error_message = strdup("Failed to connect after retry");
2244+
goto cleanup;
2245+
}
2246+
response->connect_time_us = connect_time;
2247+
2248+
/* New TLS handshake if needed */
2249+
if (use_tls) {
2250+
uint64_t tls_time = 0;
2251+
ssl = tls_connect(client->ssl_ctx, sockfd, host, client->browser_profile,
2252+
request->http2_enabled, &tls_time);
2253+
if (!ssl) {
2254+
response->error = HTTPMORPH_ERROR_TLS;
2255+
response->error_message = strdup("TLS handshake failed on retry");
2256+
goto cleanup;
2257+
}
2258+
response->tls_time_us = tls_time;
2259+
}
2260+
2261+
/* Retry sending request with fresh connection */
2262+
if (send_http_request(ssl, sockfd, request, host, path, scheme, port, using_proxy, proxy_user, proxy_pass) != 0) {
2263+
response->error = HTTPMORPH_ERROR_NETWORK;
2264+
response->error_message = strdup("Failed to send request after retry");
2265+
goto cleanup;
2266+
}
2267+
} else {
2268+
/* Not a pooled connection, fail immediately */
2269+
response->error = HTTPMORPH_ERROR_NETWORK;
2270+
response->error_message = strdup("Failed to send request");
2271+
goto cleanup;
2272+
}
22342273
}
22352274

22362275
/* 4. Receive HTTP/1.x Response */

0 commit comments

Comments
 (0)