mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-26 01:12:21 +00:00
fix(bedrock/base_aws_llm): remove lowercase authorization duplicate after SigV4 override
After the header normalization, the merge loop writes lowercase 'authorization' into request_headers_dict and the Authorization-override guard then writes uppercase 'Authorization' — both keys survive as separate entries in the plain dict. Fix by popping the lowercase key before writing the canonical uppercase one so HTTP clients only see a single Authorization header. Add test_sign_request_caller_authorization_overrides_sigv4 to cover the override branch (fixes Codecov missing-line report) and assert no duplicate key survives in the returned headers dict.
This commit is contained in:
parent
1c9af0428a
commit
53832e3ed6
2 changed files with 46 additions and 0 deletions
|
|
@ -1524,6 +1524,7 @@ class BaseAWSLLM:
|
|||
if header_value is not None:
|
||||
request_headers_dict[header_name] = header_value
|
||||
if "authorization" in headers: # prevent sigv4 from overwriting the auth header
|
||||
request_headers_dict.pop("authorization", None)
|
||||
request_headers_dict["Authorization"] = headers["authorization"]
|
||||
|
||||
return request_headers_dict, request.body
|
||||
|
|
|
|||
|
|
@ -539,6 +539,51 @@ def test_sign_request_with_sigv4():
|
|||
assert result_body == mock_request.body
|
||||
|
||||
|
||||
def test_sign_request_caller_authorization_overrides_sigv4():
|
||||
"""
|
||||
When a caller pre-supplies an Authorization header, _sign_request must not
|
||||
let SigV4's Authorization win. The returned dict should contain exactly one
|
||||
Authorization key (uppercase, canonical) with the caller's value — no
|
||||
duplicate lowercase 'authorization' entry alongside it.
|
||||
"""
|
||||
llm = BaseAWSLLM()
|
||||
|
||||
mock_credentials = Credentials("test_key", "test_secret", "test_token")
|
||||
mock_sigv4 = MagicMock()
|
||||
mock_request = MagicMock()
|
||||
mock_request.headers = {
|
||||
"Authorization": "AWS4-HMAC-SHA256 Credential=sigv4-generated",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
mock_request.body = b'{"prompt": "test"}'
|
||||
|
||||
caller_auth = "Bearer caller-supplied-token"
|
||||
|
||||
with (
|
||||
patch("botocore.auth.SigV4Auth", return_value=mock_sigv4),
|
||||
patch("botocore.awsrequest.AWSRequest", return_value=mock_request),
|
||||
patch.object(llm, "get_credentials", return_value=mock_credentials),
|
||||
patch.object(llm, "_get_aws_region_name", return_value="us-west-2"),
|
||||
):
|
||||
result_headers, _ = llm._sign_request(
|
||||
service_name="aws-external-anthropic",
|
||||
headers={"Authorization": caller_auth, "content-type": "application/json"},
|
||||
optional_params={"aws_region_name": "us-west-2"},
|
||||
request_data={"prompt": "test"},
|
||||
api_base="https://aws-external-anthropic.us-west-2.api.aws/v1/messages",
|
||||
)
|
||||
|
||||
# Caller's value must win over SigV4's generated one
|
||||
assert result_headers["Authorization"] == caller_auth
|
||||
|
||||
# Must not have a separate lowercase 'authorization' duplicate
|
||||
auth_keys = [k for k in result_headers if k.lower() == "authorization"]
|
||||
assert len(auth_keys) == 1, (
|
||||
f"Expected exactly one Authorization key, got {auth_keys}. "
|
||||
"Duplicate keys can cause unpredictable behaviour in HTTP clients."
|
||||
)
|
||||
|
||||
|
||||
def test_sign_request_with_api_key_bearer_token():
|
||||
"""
|
||||
Test that _sign_request uses the api_key parameter as a bearer token when provided
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue