Skip to main content

security_client_rs/http/
mod.rs

1//! The HTTP transport and wire types shared by every endpoint.
2//!
3//! [`Method`], [`StatusCode`] and the [`headers`] types come from the `http` crate.
4mod body;
5mod response;
6#[cfg(feature = "tracing")]
7mod trace;
8mod transport;
9
10pub use body::Body;
11pub(crate) use body::to_json;
12pub use http::{Method, StatusCode};
13pub use response::{Empty, Raw, Response};
14pub use transport::{Certificate, Credentials, DEFAULT_ADDRESS, Transport, TransportBuilder};
15pub use url::Url;
16
17pub mod headers {
18    //! Header names, values and maps, re-exported from the `http` crate.
19    pub use http::header::*;
20}
21
22/// `url` without credentials, query or fragment, which can carry secrets.
23pub(crate) fn redacted(url: &Url) -> String {
24    let mut url = url.clone();
25    let _ = url.set_username("");
26    let _ = url.set_password(None);
27    url.set_query(None);
28    url.set_fragment(None);
29    url.to_string()
30}
31
32/// Copies `src` into `dst`. Each name in `src` replaces every earlier value of
33/// that name in `dst`, while repeated values of one name in `src` are all kept.
34pub(crate) fn merge_headers(dst: &mut headers::HeaderMap, src: headers::HeaderMap) {
35    let mut current = None;
36    for (name, value) in src {
37        match name {
38            Some(name) => {
39                dst.insert(&name, value);
40                current = Some(name);
41            }
42            // `HeaderMap::into_iter` yields a name before its further values.
43            None => {
44                if let Some(name) = &current {
45                    dst.append(name, value);
46                }
47            }
48        }
49    }
50}