aws_smithy_http_server/instrumentation/sensitivity/
response.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! A builder whose methods allow for configuration of [`MakeFmt`] implementations over parts of [`http::Response`].
7
8use std::fmt::{Debug, Error, Formatter};
9
10use http::{header::HeaderName, HeaderMap};
11
12use crate::instrumentation::{MakeFmt, MakeIdentity};
13
14use super::{
15    headers::{HeaderMarker, MakeHeaders},
16    MakeSensitive,
17};
18
19/// Allows the modification the responses status code [`Display`](std::fmt::Display) and headers
20/// [`Debug`] to accommodate sensitivity.
21///
22/// This enjoys [`MakeFmt`] for [`&HeaderMap`](HeaderMap) and [`StatusCode`](http::StatusCode).
23#[derive(Clone)]
24pub struct ResponseFmt<Headers, StatusCode> {
25    headers: Headers,
26    status_code: StatusCode,
27}
28
29impl<Headers, StatusCode> Debug for ResponseFmt<Headers, StatusCode> {
30    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
31        f.debug_struct("ResponseFmt").finish_non_exhaustive()
32    }
33}
34
35/// Default [`ResponseFmt`].
36pub type DefaultResponseFmt = ResponseFmt<MakeIdentity, MakeIdentity>;
37
38impl Default for DefaultResponseFmt {
39    fn default() -> Self {
40        Self {
41            headers: MakeIdentity,
42            status_code: MakeIdentity,
43        }
44    }
45}
46
47impl DefaultResponseFmt {
48    /// Constructs a new [`ResponseFmt`] with no redactions.
49    pub fn new() -> Self {
50        Self::default()
51    }
52}
53
54impl<Header, StatusCode> ResponseFmt<Header, StatusCode> {
55    /// Marks headers as sensitive using a closure.
56    ///
57    /// See [`SensitiveHeaders`](super::headers::SensitiveHeaders) for more info.
58    pub fn header<F>(self, header: F) -> ResponseFmt<MakeHeaders<F>, StatusCode>
59    where
60        F: Fn(&HeaderName) -> HeaderMarker,
61    {
62        ResponseFmt {
63            headers: MakeHeaders(header),
64            status_code: self.status_code,
65        }
66    }
67
68    /// Marks request status code as sensitive.
69    pub fn status_code(self) -> ResponseFmt<Header, MakeSensitive> {
70        ResponseFmt {
71            headers: self.headers,
72            status_code: MakeSensitive,
73        }
74    }
75}
76
77impl<'a, Headers, StatusCode> MakeFmt<&'a HeaderMap> for ResponseFmt<Headers, StatusCode>
78where
79    Headers: MakeFmt<&'a HeaderMap>,
80{
81    type Target = Headers::Target;
82
83    fn make(&self, source: &'a HeaderMap) -> Self::Target {
84        self.headers.make(source)
85    }
86}
87
88impl<Headers, StatusCode> MakeFmt<http::StatusCode> for ResponseFmt<Headers, StatusCode>
89where
90    StatusCode: MakeFmt<http::StatusCode>,
91{
92    type Target = StatusCode::Target;
93
94    fn make(&self, source: http::StatusCode) -> Self::Target {
95        self.status_code.make(source)
96    }
97}