mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-24 00:52:24 +00:00
Merge pull request #41141 from BerriAI/litellm_lit7694_forwarded_headers_body_leak
fix(openai): keep extra_headers out of the chat request body on the httpx handler path
(cherry picked from commit de55e22899)
This commit is contained in:
parent
4afb271ba3
commit
8a23af9bc6
2 changed files with 58 additions and 3 deletions
|
|
@ -2592,7 +2592,9 @@ def _complete_custom_openai(
|
|||
copilot_headers.update(extra_headers)
|
||||
extra_headers = copilot_headers
|
||||
|
||||
if extra_headers is not None:
|
||||
use_base_llm_http_handler: Final = get_secret_bool("EXPERIMENTAL_OPENAI_BASE_LLM_HTTP_HANDLER")
|
||||
|
||||
if extra_headers is not None and not use_base_llm_http_handler:
|
||||
optional_params["extra_headers"] = extra_headers
|
||||
|
||||
if litellm.enable_preview_features and metadata is not None: # [PREVIEW] allow metadata to be passed to OPENAI
|
||||
|
|
@ -2609,8 +2611,6 @@ def _complete_custom_openai(
|
|||
optional_params[k] = v
|
||||
|
||||
## COMPLETION CALL
|
||||
use_base_llm_http_handler: Final = get_secret_bool("EXPERIMENTAL_OPENAI_BASE_LLM_HTTP_HANDLER")
|
||||
|
||||
try:
|
||||
if use_base_llm_http_handler:
|
||||
response = base_llm_http_handler.completion(
|
||||
|
|
|
|||
|
|
@ -3795,3 +3795,58 @@ def test_azure_ai_speech_on_a_foundry_host_uses_the_azure_openai_deployment_rout
|
|||
|
||||
assert route.called
|
||||
assert response.content == b"mp3-bytes"
|
||||
|
||||
|
||||
FORWARDED_CLIENT_HEADERS: Final = {"x-forwarded-for": "10.0.0.1", "x-amzn-trace-id": "Root=1-lit7694"}
|
||||
|
||||
|
||||
def _chat_completion_json() -> Mapping[str, object]:
|
||||
return {
|
||||
"id": "chatcmpl-lit7694",
|
||||
"object": "chat.completion",
|
||||
"created": 1,
|
||||
"model": "gpt-5.4",
|
||||
"choices": [{"index": 0, "message": {"role": "assistant", "content": "ok"}, "finish_reason": "stop"}],
|
||||
"usage": {"prompt_tokens": 1, "completion_tokens": 1, "total_tokens": 2},
|
||||
}
|
||||
|
||||
|
||||
def _chat_completion_sse() -> bytes:
|
||||
chunk: Final = {
|
||||
"id": "chatcmpl-lit7694",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": 1,
|
||||
"model": "gpt-5.4",
|
||||
"choices": [{"index": 0, "delta": {"role": "assistant", "content": "ok"}, "finish_reason": "stop"}],
|
||||
}
|
||||
return f"data: {json.dumps(chunk)}\n\ndata: [DONE]\n\n".encode()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("stream", [False, True])
|
||||
def test_bridged_responses_with_openai_http_handler_keeps_forwarded_headers_out_of_the_body(
|
||||
respx_mock: respx.MockRouter, monkeypatch: pytest.MonkeyPatch, stream: bool
|
||||
):
|
||||
monkeypatch.setenv("EXPERIMENTAL_OPENAI_BASE_LLM_HTTP_HANDLER", "true")
|
||||
route: Final = respx_mock.post("https://api.openai.com/v1/chat/completions").mock(
|
||||
return_value=httpx.Response(200, content=_chat_completion_sse(), headers={"content-type": "text/event-stream"})
|
||||
if stream
|
||||
else httpx.Response(200, json=_chat_completion_json())
|
||||
)
|
||||
|
||||
response: Final = litellm.responses(
|
||||
model="openai/gpt-5.4",
|
||||
input="Reply with the single word ok",
|
||||
stream=stream,
|
||||
use_chat_completions_api=True,
|
||||
headers=dict(FORWARDED_CLIENT_HEADERS),
|
||||
api_key="sk-test",
|
||||
)
|
||||
if stream:
|
||||
list(response)
|
||||
|
||||
assert route.called
|
||||
request: Final = route.calls.last.request
|
||||
body: Final = json.loads(request.content)
|
||||
assert "extra_headers" not in body
|
||||
assert body["model"] == "gpt-5.4"
|
||||
assert {k: request.headers[k] for k in FORWARDED_CLIENT_HEADERS} == FORWARDED_CLIENT_HEADERS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue