Skip to content

Conversation

ahl
Copy link
Collaborator

@ahl ahl commented Aug 21, 2025

Fixes #1380, #1373.

The Header extractor (which I wrote) was very poor. In particular it didn't consider the case of required header (or of deserialization failing for any reason). This PR intends to address the issues of robustness and add proper handling for the case-insensitivity of headers. We do so while preserving desired casing for the OpenAPI output.

An alternative approach would have been to require lower-case naming for headers with the ability to use schemars attributes to direct the OpenAPI output (e.g. #[serde(rename = "x-my-header")] #[schemars(rename = "X-My-Header")]). But this seemed confusing and error-prone.

@ahl ahl requested review from davepacheco and hawkw and removed request for davepacheco August 21, 2025 22:22
Comment on lines 29 to 30
/// OpenAPI document output. Case-insensitive name conflicts may lead to
/// unexpected behavior, and should be avoided. For example, only one of the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to make sense of "Case-insensitive name conflicts may lead to unexpected behavior, and should be avoided".

Who is this advice for? Why not just say "Since HTTP headers are case-insensitive, we automatically treat headers as lowercase. Upper-case characters are still allowed for OpenAPI documents, but they are converted to lowercase when deserializing and dealing with extraction conflicts".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved the phrasing; thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt similarly about that line but couldn't figure how to state the problem

fn rename(fields: &'static [&'static str]) -> BTreeMap<String, String> {
fields
.iter()
.map(|field| (field.to_lowercase(), field.to_string()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the lifetime too much of a pain to return the "value" here as a &'static str? seems unnecessary to perform the string allocation (via field.to_string()) on the case-unchanged string here

@ahl ahl removed the request for review from hawkw August 25, 2025 21:36
@ahl ahl merged commit a33be8e into main Aug 26, 2025
11 checks passed
@ahl ahl deleted the better-headers branch August 26, 2025 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dropshot panics when it fails to extract headers
3 participants