fix: reject invalid HTTP read hints and report actual parallelism bounds

Return InvalidParameter for an invalid applied generic read_preference while preserving dedicated-header precedence. Format the query.parallelism diagnostic from the supplied maximum so wire errors do not incorrectly report the public cap.

Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com>
This commit is contained in:
discord9
2026-10-15 14:57:48 +08:00
parent 161f77532f
commit 16f15d4ea1
2 changed files with 17 additions and 8 deletions
+16 -7
View File
@@ -20,6 +20,7 @@ use common_telemetry::debug;
use session::context::QueryContext;
use session::hints::is_reserved_extension_key;
use crate::error::{InvalidParameterSnafu, Result};
use crate::hint_headers;
pub async fn extract_hints(mut request: Request<Body>, next: Next) -> Response {
@@ -31,8 +32,10 @@ pub async fn extract_hints(mut request: Request<Body>, next: Next) -> Response {
Ok(hints) => hints,
Err(error) => return error.into_response(),
};
if let Some(query_ctx) = request.extensions_mut().get_mut::<QueryContext>() {
apply_hints(query_ctx, hints, dedicated_read_preference);
if let Some(query_ctx) = request.extensions_mut().get_mut::<QueryContext>()
&& let Err(error) = apply_hints(query_ctx, hints, dedicated_read_preference)
{
return error.into_response();
}
next.run(request).await
}
@@ -41,7 +44,7 @@ fn apply_hints(
query_ctx: &mut QueryContext,
hints: Vec<(String, String)>,
dedicated_read_preference: bool,
) {
) -> Result<()> {
for (key, value) in hints {
if is_reserved_extension_key(&key) {
debug!(
@@ -51,15 +54,20 @@ fn apply_hints(
continue;
}
if key.eq_ignore_ascii_case(session::hints::READ_PREFERENCE_HINT) {
if !dedicated_read_preference
&& let Ok(preference) = value.parse::<session::ReadPreference>()
{
if !dedicated_read_preference {
let preference = value.parse::<session::ReadPreference>().map_err(|_| {
InvalidParameterSnafu {
reason: format!("Invalid read_preference hint: {value}"),
}
.build()
})?;
query_ctx.set_read_preference(preference);
}
} else {
query_ctx.set_extension(key, value);
}
}
Ok(())
}
#[cfg(test)]
@@ -106,7 +114,8 @@ mod tests {
("ttl".to_string(), "7d".to_string()),
],
false,
);
)
.unwrap();
assert_eq!(
query_ctx.remote_query_id(),
+1 -1
View File
@@ -60,7 +60,7 @@ pub fn parse_query_option(
return InvalidConfigValueSnafu {
name: key,
value,
hint: "query.parallelism must be between 1 and 1024",
hint: format!("query.parallelism must be between 1 and {max_parallelism}"),
}
.fail();
}