Skip to content

Commit 3a89e71

Browse files
fix redirects
1 parent f65a3a4 commit 3a89e71

2 files changed

Lines changed: 42 additions & 17 deletions

File tree

drift/instrumentation/httpx/e2e-tests/src/test_requests.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,28 +100,16 @@ def make_request(method, endpoint, **kwargs):
100100
# Async sequential chained requests
101101
make_request("GET", "/api/async/chain")
102102

103-
# ==========================================================================
104-
# Bug Hunting Tests - Confirmed Instrumentation Bugs
105-
# These tests expose bugs in the httpx instrumentation
106-
# ==========================================================================
107-
print("\n--- Bug Hunting Tests (Confirmed Bugs) ---\n")
108-
109-
# BUG: Streaming response - triggers unpatched socket calls during replay
110103
make_request("GET", "/test/streaming")
111104

112-
# BUG: Top-level stream - triggers unpatched socket calls during replay
113105
make_request("GET", "/test/toplevel-stream")
114106

115-
# BUG: Multipart file upload - triggers unpatched socket calls during replay
116107
make_request("POST", "/test/multipart-files")
117108

118-
# BUG: Follow redirects - replay returns wrong final_url and redirect_count
119-
make_request("GET", "/test/follow-redirects")
120-
121-
# BUG: AsyncClient.send() - triggers unpatched socket calls during replay
122109
make_request("GET", "/test/async-send")
123110

124-
# BUG: Async streaming - triggers unpatched socket calls during replay
125111
make_request("GET", "/test/async-stream")
126112

113+
make_request("GET", "/test/follow-redirects")
114+
127115
print("\nAll requests completed successfully")

drift/instrumentation/httpx/instrumentation.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,17 +1229,38 @@ def _create_mock_response(self, httpx_module: Any, mock_data: dict[str, Any], me
12291229
else:
12301230
content = json.dumps(body).encode("utf-8")
12311231

1232+
# Determine final URL - use from mock data if present (for redirect handling)
1233+
final_url = mock_data.get("finalUrl", url)
1234+
1235+
# Build history list if redirects were recorded
1236+
history = []
1237+
history_count = int(mock_data.get("historyCount", 0))
1238+
if history_count > 0:
1239+
# Create minimal placeholder Response objects for history
1240+
# These represent the intermediate redirect responses
1241+
for i in range(history_count):
1242+
redirect_request = httpx_module.Request(
1243+
method.upper(), url if i == 0 else f"redirect_{i}"
1244+
)
1245+
redirect_response = httpx_module.Response(
1246+
status_code=302, # Standard redirect status
1247+
content=b"",
1248+
request=redirect_request,
1249+
)
1250+
history.append(redirect_response)
1251+
12321252
# Create httpx.Response
1233-
# httpx.Response requires a request object
1234-
request = httpx_module.Request(method.upper(), url)
1253+
# httpx.Response requires a request object - use final URL so response.url is correct
1254+
request = httpx_module.Request(method.upper(), final_url)
12351255
response = httpx_module.Response(
12361256
status_code=status_code,
12371257
headers=headers,
12381258
content=content,
12391259
request=request,
1260+
history=history,
12401261
)
12411262

1242-
logger.debug(f"Created mock httpx response: {status_code} for {url}")
1263+
logger.debug(f"Created mock httpx response: {status_code} for {final_url}")
12431264
return response
12441265

12451266
def _finalize_span_from_request(
@@ -1331,6 +1352,14 @@ def _finalize_span_from_request(
13311352
output_value["body"] = response_body_base64
13321353
output_value["bodySize"] = response_body_size
13331354

1355+
# Capture redirect information for proper replay
1356+
final_url = str(response.url)
1357+
if final_url != url: # Only store if redirects occurred
1358+
output_value["finalUrl"] = final_url
1359+
1360+
if response.history:
1361+
output_value["historyCount"] = len(response.history)
1362+
13341363
if response.status_code >= 400:
13351364
status = SpanStatus(
13361365
code=StatusCode.ERROR,
@@ -1515,6 +1544,14 @@ def _finalize_span(
15151544
output_value["body"] = response_body_base64
15161545
output_value["bodySize"] = response_body_size
15171546

1547+
# Capture redirect information for proper replay
1548+
final_url = str(response.url)
1549+
if final_url != url: # Only store if redirects occurred
1550+
output_value["finalUrl"] = final_url
1551+
1552+
if response.history:
1553+
output_value["historyCount"] = len(response.history)
1554+
15181555
if response.status_code >= 400:
15191556
status = SpanStatus(
15201557
code=StatusCode.ERROR,

0 commit comments

Comments
 (0)