fix(rust): ignore blank Tencent Messages credentials

This commit is contained in:
Yujong Lee 2026-10-10 17:41:56 -07:00
parent 5f2d8adaa3
commit e0cd521bb6
2 changed files with 33 additions and 1 deletions

View file

@ -20,6 +20,15 @@ fn tencent_call(call: MessagesCall) -> MessagesCall {
#[case::deployment_key(&[], "x-api-key", "deployment-key")]
#[case::forwarded_key(&[("X-Api-Key", "caller-key")], "x-api-key", "caller-key")]
#[case::forwarded_bearer(&[("Authorization", "Bearer caller")], "authorization", "Bearer caller")]
#[case::blank_key(&[("X-Api-Key", " \t")], "x-api-key", "deployment-key")]
#[case::blank_authorization(&[("Authorization", " \t")], "x-api-key", "deployment-key")]
#[case::empty_bearer(&[("Authorization", "bEaReR \t")], "x-api-key", "deployment-key")]
#[case::blank_authorization_with_key(
&[("Authorization", "Bearer "), ("X-Api-Key", "caller-key")], "x-api-key", "caller-key"
)]
#[case::blank_key_with_bearer(
&[("X-Api-Key", " "), ("Authorization", "Bearer caller")], "authorization", "Bearer caller"
)]
#[tokio::test]
async fn credentials_reach_the_selected_provider(
tencent_call: MessagesCall,
@ -36,6 +45,12 @@ async fn credentials_reach_the_selected_provider(
.await;
let sent = only_request(&upstream).await;
assert_eq!(sent.header_values(header), [credential]);
let other_header = if header == "x-api-key" {
"authorization"
} else {
"x-api-key"
};
assert!(sent.header_values(other_header).is_empty());
let version = DEFAULT_HEADERS
.iter()
.find_map(|(name, value)| (*name == "anthropic-version").then_some(*value))
@ -69,12 +84,20 @@ async fn credentials_and_base_resolve_from_the_secret_source(tencent_call: Messa
}
#[rstest]
#[case::absent(&[])]
#[case::blank_key(&[("x-api-key", " \t")])]
#[case::blank_authorization(&[("authorization", " \t")])]
#[case::empty_bearer(&[("authorization", "Bearer \t")])]
#[tokio::test]
async fn missing_credentials_fail_before_sending(tencent_call: MessagesCall) {
async fn missing_credentials_fail_before_sending(
tencent_call: MessagesCall,
#[case] forwarded: &[(&str, &str)],
) {
let upstream = upstream([message_response()]).await;
let error = run(MessagesCall {
api_key: None,
api_base: Some(upstream.uri()),
extra_headers: headers(forwarded.iter().copied()),
..tencent_call
})
.await

View file

@ -46,6 +46,15 @@ impl BaseMessagesConfig for TencentAnthropicMessagesConfig {
_params: &LitellmParams,
env: &dyn Fn(&str) -> Option<String>,
) -> Result<ValidatedEnvironment, Error> {
let headers: Headers = headers
.into_iter()
.filter(|(name, value)| {
let value = value.trim();
!((name.eq_ignore_ascii_case("x-api-key") && value.is_empty())
|| (name.eq_ignore_ascii_case("authorization")
&& (value.is_empty() || value.eq_ignore_ascii_case("bearer"))))
})
.collect();
if has_anthropic_credential(&headers) {
return Ok(ValidatedEnvironment {
headers,