Skip to main content

rama_http_headers/common/
access_control_request_method.rs

1use rama_core::telemetry::tracing;
2use rama_http_types::{HeaderName, HeaderValue, Method};
3
4use crate::{Error, HeaderDecode, HeaderEncode, TypedHeader};
5
6/// `Access-Control-Request-Method` header, as defined on
7/// [mdn](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Access-Control-Request-Method).
8///
9/// The `Access-Control-Request-Method` header indicates which method will be
10/// used in the actual request as part of the preflight request.
11/// # ABNF
12///
13/// ```text
14/// Access-Control-Request-Method: \"Access-Control-Request-Method\" \":\" Method
15/// ```
16///
17/// # Example values
18/// * `GET`
19///
20/// # Examples
21///
22/// ```
23/// use rama_http_headers::AccessControlRequestMethod;
24/// use rama_http_types::Method;
25///
26/// let req_method = AccessControlRequestMethod::from(Method::GET);
27/// ```
28#[derive(Clone, Debug, PartialEq, Eq, Hash)]
29pub struct AccessControlRequestMethod(pub Method);
30
31impl TypedHeader for AccessControlRequestMethod {
32    fn name() -> &'static HeaderName {
33        &::rama_http_types::header::ACCESS_CONTROL_REQUEST_METHOD
34    }
35}
36
37impl HeaderDecode for AccessControlRequestMethod {
38    fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
39        values
40            .next()
41            .and_then(|value| Method::from_bytes(value.as_bytes()).ok())
42            .map(AccessControlRequestMethod)
43            .ok_or_else(Error::invalid)
44    }
45}
46
47impl HeaderEncode for AccessControlRequestMethod {
48    fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
49        // For the more common methods, try to use a static string.
50        let s = match self.0 {
51            Method::GET => "GET",
52            Method::POST => "POST",
53            Method::PUT => "PUT",
54            Method::DELETE => "DELETE",
55            Method::HEAD => "HEAD",
56            Method::OPTIONS => "OPTIONS",
57            Method::CONNECT => "CONNECT",
58            Method::PATCH => "PATCH",
59            Method::TRACE => "TRACE",
60            _ => {
61                match HeaderValue::from_str(self.0.as_ref()) {
62                    Ok(value) => values.extend(::std::iter::once(value)),
63                    Err(err) => {
64                        tracing::debug!(
65                            "failed to encode access-control-request-method value as header: {err}"
66                        );
67                    }
68                }
69                return;
70            }
71        };
72
73        values.extend(::std::iter::once(HeaderValue::from_static(s)));
74    }
75}
76
77impl From<Method> for AccessControlRequestMethod {
78    fn from(method: Method) -> Self {
79        Self(method)
80    }
81}
82
83impl From<AccessControlRequestMethod> for Method {
84    fn from(method: AccessControlRequestMethod) -> Self {
85        method.0
86    }
87}