oxidecomputer / oxidecomputer/dropshot

Header names with capital letters are not deserialized

Open
#1,373 2 comments 0 reactions 1 assignee View on GitHub

@ahl is already working on this.

Since Aug 22, 2025.

Dominant language
Rust
Stars
1.2k
Forks
104
Avg merge
1d 19h
Merged PRs (30d)
22

Description

Headers with (renamed) names that include capital letters fail to deserialize.

For example:

#[derive(Serialize, Deserialize, JsonSchema)]
pub struct MyHeaders {
    header_a: String,
    #[serde(rename = "X-Header-B")]
    header_b: String,
}

#[endpoint {
    method = GET,
    path = "/test",
}]
pub async fn get_test(
    rqctx: RequestContext<AppContext>,
    header_params: Header<MyHeaders>,
) -> Result<HttpResponseOk<()>, HttpError> {
    info!("rqctx headers: {:?}", rqctx.request.headers());
    let headers = header_params.into_inner();
    info!("Headers: {:?}, {:?}", headers.header_a, headers.header_b);

    Ok(HttpResponseOk(()))
}

Using the following request

Image

causes the following error:

thread 'tokio-runtime-worker' panicked at /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dropshot-0.16.2/src/extractor/header.rs:53:44:
called `Result::unwrap()` on an `Err` value: "missing field `X-Header-B`"
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Jul 18 08:31:05.526 ERRO handler panicked; propogating panic, uri: /test, method: GET, req_id: 921b5a49-668e-4a6a-9e48-284ff37f91cb, remote_addr: 127.0.0.1:60506, local_addr: 127.0.0.1:8020

Removing the #[serde(rename = "X-Header-B")] reveals in the logs:

rqctx headers: {"accept": "application/json, text/plain, */*", "user-agent": "bruno-runtime/2.7.0", "header_a": "header_a value", "x-header-b": "header_b value", "header_b": "header_b value", "request-start-time": "1752827600143", "accept-encoding": "gzip, compress, deflate, br", "host": "localhost:8020", "connection": "keep-alive"}

So the error seems to be caused by "X-Header-B" being renamed to "x-header-b" in the request context. Since HTTP headers are not case-sensitive, I think deserialization should generally not be case sensitive either.

If someone could tell me where to best introduce this change, I am happy to make a PR for this.

As a workaround, it seems like it's sufficient to specify an alias, e.g. #[serde(rename = "X-Header-B", alias = "x-header-b")]

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.