diff --git a/src/glean/api_client/_hooks/x_glean.py b/src/glean/api_client/_hooks/x_glean.py index 6aa88575..5ca01721 100644 --- a/src/glean/api_client/_hooks/x_glean.py +++ b/src/glean/api_client/_hooks/x_glean.py @@ -61,20 +61,10 @@ def before_request( config_experimental, ) - # Create new headers dict with existing headers - new_headers = dict(request.headers) - if deprecated_value: - new_headers["X-Glean-Exclude-Deprecated-After"] = deprecated_value + request.headers["X-Glean-Exclude-Deprecated-After"] = deprecated_value if experimental_value: - new_headers["X-Glean-Experimental"] = experimental_value + request.headers["X-Glean-Experimental"] = experimental_value - # Return new request with updated headers - return httpx.Request( - method=request.method, - url=request.url, - headers=new_headers, - content=request.content, - extensions=request.extensions, - ) + return request diff --git a/tests/test_x_glean_hook.py b/tests/test_x_glean_hook.py index 14bb4a1f..1c4dcdd5 100644 --- a/tests/test_x_glean_hook.py +++ b/tests/test_x_glean_hook.py @@ -239,5 +239,27 @@ def test_preserves_request_method_and_url(self): assert str(result.url) == "https://api.example.com/v1/search" + def test_handles_multipart_streaming_request(self): + """Should handle multipart requests without raising RequestNotRead. + + Multipart file uploads use a streaming body. The previous implementation + reconstructed the request via httpx.Request(..., content=request.content), + which raised httpx.RequestNotRead on streaming bodies. + """ + hook = XGlean() + request = httpx.Request( + "POST", + "https://example.com/rest/api/v1/uploadchatfiles", + data={"field": "value"}, + files={"file": ("test.csv", b"a,b\n1,2", "text/csv")}, + ) + context = create_mock_context(include_experimental=True) + + result = hook.before_request(context, request) + + assert result.headers.get("X-Glean-Experimental") == "true" + assert result.method == "POST" + + if __name__ == "__main__": pytest.main([__file__])