axum allows me to capture http headers in a handler with the TypedHeader
struct. For example:
async fn handler(TypedHeader(if_none_match): TypedHeader<IfNoneMatch>) -> String {
let etag = "foo".parse::<ETag>().unwrap();
if if_none_match.precondition_passes(&etag) {
String::from("success")
} else {
String::from("failure")
}
}
Now I'm wondering what happens if I get a request where the If-None-Match
header is missing. With some debugging, I found out that the handler will still be called and the precondition will pass. However, I'm wondering what the instance of IfNoneMatch
is now which I'm receiving? How is axum setting this instance and how can I determine whether the header was originally missing? I used the If-None-Match
http header as an example here, but I would be interested in a general answer.
If a TypedHeader
fails to extract from the request, it will reject the request and return a 400 status code and error message in the body by default.
If you want to handle the case where a TypedHeader
cannot be extracted, you can wrap it in an Option
:
async fn handler(maybe_if_none_match: Option<TypedHeader<IfNoneMatch>>) -> String {
}
The value will be Some
if the extraction was successful and None
otherwise.
However, a TypedHeader
may fail to be extracted due to an incorrectly encoded value. You may still wish to distinguish that case and if so you can wrap it in a Result
:
async fn handler(maybe_if_none_match: Result<TypedHeader<IfNoneMatch>, TypedHeaderRejection>) -> String {
}
The error type needs to match the rejection type of the FromRequestParts
implementation. Clearly the value will be Ok
if the extraction was successful and Err
otherwise with the error value.
This technique works for any extractor.