ordinary_utils/
headers.rs1use crate::{
6 HeadersDebug, LatencyDisplay, WrappedRedactedHashingAlg, X_FORWARDED_FOR, X_FORWARDED_HOST,
7 X_FORWARDED_PROTO, X_VIA, get_host, get_http_version_str, get_mapped_ip_for_addr,
8};
9use axum::extract::{ConnectInfo, Request};
10use axum::http::{HeaderMap, HeaderValue, header};
11use std::net::SocketAddr;
12use std::sync::Arc;
13use std::time::Instant;
14
15pub fn log_response(
16 status: u16,
17 log_headers: bool,
18 redacted_hash: &Arc<Option<WrappedRedactedHashingAlg>>,
19 start: Instant,
20 headers: &HeaderMap,
21) {
22 let hd = log_headers.then_some(HeadersDebug(headers, redacted_hash.clone()));
23
24 #[cfg(tracing_unstable)]
25 let headers = log_headers.then_some(tracing::field::valuable(&hd));
26 #[cfg(not(tracing_unstable))]
27 let headers = log_headers.then_some(tracing::field::debug(&hd));
28
29 let latency = LatencyDisplay(start.elapsed().as_nanos() as f64);
30
31 if status >= 500 {
32 tracing::error!(status, headers, %latency, "res");
33 } else if status >= 400 {
34 tracing::warn!(status, headers, %latency, "res");
35 } else {
36 tracing::info!(status, headers, %latency, "res");
37 }
38}
39
40pub fn get_request_headers_for_forward(
41 req: &Request,
42 forwarded_by: &str,
43 forwarded_proto: &str,
44 via_domain: &str,
45) -> HeaderMap {
46 let mut headers = req.headers().clone();
47
48 let req_version = get_http_version_str(req.version());
49
50 let via = if let Some(src_via) = headers.get(header::VIA)
51 && let Ok(src_via) = src_via.to_str()
52 {
53 format!("{src_via}, {req_version} {via_domain} (ordinaryd)")
54 } else {
55 format!("{req_version} {via_domain} (ordinaryd)")
56 };
57
58 if let Ok(via) = HeaderValue::from_str(&via) {
59 headers.insert(header::VIA, via);
60 }
61
62 let connect_info = req.extensions().get::<ConnectInfo<SocketAddr>>();
63
64 let mut forwarded = if let Some(src_forwarded) = headers.get(header::FORWARDED)
65 && let Ok(src_forwarded) = src_forwarded.to_str()
66 {
67 format!("{src_forwarded}, by={forwarded_by}")
68 } else {
69 format!("by={forwarded_by}")
70 };
71
72 if let Some(addr) = connect_info {
73 let ip = get_mapped_ip_for_addr(&addr.0);
74 let ip_str = ip.to_string();
75
76 if ip.is_ipv6() {
77 forwarded = format!("{forwarded};for=\"[{ip_str}]\"");
78 } else {
79 forwarded = format!("{forwarded};for={ip_str}");
80 }
81
82 let forwarded_for = if let Some(src_forwarded_for) = headers.get("x-forwarded-for")
83 && let Ok(src_forwarded_for) = src_forwarded_for.to_str()
84 {
85 format!("{src_forwarded_for}, {ip_str}")
86 } else {
87 ip_str
88 };
89
90 if let Ok(forwarded_for) = HeaderValue::from_str(&forwarded_for) {
91 headers.insert(X_FORWARDED_FOR, forwarded_for);
92 }
93 }
94
95 if let Some(host) = get_host(req.headers(), req.uri()) {
96 forwarded = format!("{forwarded};host={host}");
97
98 if let Ok(forwarded_host) = HeaderValue::from_str(host.as_str()) {
99 headers.insert(X_FORWARDED_HOST, forwarded_host);
100 }
101 }
102
103 forwarded = format!("{forwarded};proto={forwarded_proto}");
104
105 if let Ok(forwarded_proto) = HeaderValue::from_str(forwarded_proto) {
106 headers.insert(X_FORWARDED_PROTO, forwarded_proto);
107 }
108
109 if let Ok(forwarded) = HeaderValue::from_str(&forwarded) {
110 headers.insert(header::FORWARDED, forwarded);
111 }
112
113 headers.remove(X_VIA);
114 headers
115}