Skip to main content

http_msgsign/
components.rs

1pub mod derive;
2mod field;
3mod name;
4pub mod params;
5pub(crate) mod values;
6
7pub use self::{derive::Derive, field::*, name::*};
8
9use std::fmt::{Display, Formatter};
10
11use http::{Request, Response};
12
13use crate::errors::HttpComponentError;
14use crate::sign::ExchangeRecord;
15
16/// Canonical HTTP messages as per the rules defined in [RFC9421 HTTP Message Components](https://datatracker.ietf.org/doc/html/rfc9421#name-http-message-components)
17#[derive(Debug, Eq, PartialEq, Hash)]
18pub struct HttpComponent {
19    pub(crate) id: String,
20    pub(crate) value: Option<String>,
21}
22
23impl Display for HttpComponent {
24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25        // Empty HTTP fields can also be signed when present in a message.
26        // https://datatracker.ietf.org/doc/html/rfc9421#section-2.1-13
27        match self.value {
28            Some(ref value) => write!(f, "{}: {}", self.id, value),
29            None => write!(f, "{}: ", self.id),
30        }
31    }
32}
33
34pub trait ToComponent {
35    fn to_component(&self, target_field: &TargetField)
36    -> Result<HttpComponent, HttpComponentError>;
37}
38
39impl<B> ToComponent for Request<B> {
40    fn to_component(
41        &self,
42        target_field: &TargetField,
43    ) -> Result<HttpComponent, HttpComponentError> {
44        target_field.seek_request(self)
45    }
46}
47
48impl<B> ToComponent for Response<B> {
49    fn to_component(
50        &self,
51        target_field: &TargetField,
52    ) -> Result<HttpComponent, HttpComponentError> {
53        target_field.seek_response(self)
54    }
55}
56
57impl<Req, Res> ToComponent for ExchangeRecord<'_, Req, Res> {
58    fn to_component(
59        &self,
60        target_field: &TargetField,
61    ) -> Result<HttpComponent, HttpComponentError> {
62        target_field.seek_record(self)
63    }
64}