feat: basic tracing
This commit is contained in:
parent
48ccbc1099
commit
537484122d
@ -23,6 +23,7 @@ hyper = { version = "0.14.18", features = ["full"] }
|
|||||||
hyper-trust-dns = { version = "0.4.2", optional = true, default-features = false, features = ["rustls-webpki", "rustls-http1"] }
|
hyper-trust-dns = { version = "0.4.2", optional = true, default-features = false, features = ["rustls-webpki", "rustls-http1"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
tracing = "0.1.34"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.17.0", features = ["full"] }
|
tokio = { version = "1.17.0", features = ["full"] }
|
||||||
|
47
src/lib.rs
47
src/lib.rs
@ -96,6 +96,9 @@
|
|||||||
//! ```
|
//! ```
|
||||||
#![cfg_attr(all(not(stable), test), feature(test))]
|
#![cfg_attr(all(not(stable), test), feature(test))]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate tracing;
|
||||||
|
|
||||||
#[cfg(all(not(stable), test))]
|
#[cfg(all(not(stable), test))]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
@ -164,6 +167,8 @@ impl From<InvalidHeaderValue> for ProxyError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_hop_headers(headers: &mut HeaderMap) {
|
fn remove_hop_headers(headers: &mut HeaderMap) {
|
||||||
|
debug!("Removing hop headers");
|
||||||
|
|
||||||
for header in &*HOP_HEADERS {
|
for header in &*HOP_HEADERS {
|
||||||
headers.remove(header);
|
headers.remove(header);
|
||||||
}
|
}
|
||||||
@ -182,14 +187,22 @@ fn get_upgrade_type(headers: &HeaderMap) -> Option<String> {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
if let Some(upgrade_value) = headers.get(&*UPGRADE_HEADER) {
|
if let Some(upgrade_value) = headers.get(&*UPGRADE_HEADER) {
|
||||||
|
debug!(
|
||||||
|
"Found upgrade header with value: {}",
|
||||||
|
upgrade_value.to_str().unwrap().to_owned()
|
||||||
|
);
|
||||||
|
|
||||||
return Some(upgrade_value.to_str().unwrap().to_owned());
|
return Some(upgrade_value.to_str().unwrap().to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_connection_headers(headers: &mut HeaderMap) {
|
fn remove_connection_headers(headers: &mut HeaderMap) {
|
||||||
if headers.get(&*CONNECTION_HEADER).is_some() {
|
if headers.get(&*CONNECTION_HEADER).is_some() {
|
||||||
|
debug!("Removing connection headers");
|
||||||
|
|
||||||
let value = headers.get(&*CONNECTION_HEADER).cloned().unwrap();
|
let value = headers.get(&*CONNECTION_HEADER).cloned().unwrap();
|
||||||
|
|
||||||
for name in value.to_str().unwrap().split(',') {
|
for name in value.to_str().unwrap().split(',') {
|
||||||
@ -201,6 +214,8 @@ fn remove_connection_headers(headers: &mut HeaderMap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_proxied_response<B>(mut response: Response<B>) -> Response<B> {
|
fn create_proxied_response<B>(mut response: Response<B>) -> Response<B> {
|
||||||
|
info!("Creating proxied response");
|
||||||
|
|
||||||
remove_hop_headers(response.headers_mut());
|
remove_hop_headers(response.headers_mut());
|
||||||
remove_connection_headers(response.headers_mut());
|
remove_connection_headers(response.headers_mut());
|
||||||
|
|
||||||
@ -208,6 +223,8 @@ fn create_proxied_response<B>(mut response: Response<B>) -> Response<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn forward_uri<B>(forward_url: &str, req: &Request<B>) -> String {
|
fn forward_uri<B>(forward_url: &str, req: &Request<B>) -> String {
|
||||||
|
debug!("Building forward uri");
|
||||||
|
|
||||||
let split_url = forward_url.split('?').collect::<Vec<&str>>();
|
let split_url = forward_url.split('?').collect::<Vec<&str>>();
|
||||||
|
|
||||||
let mut base_url: &str = split_url.get(0).unwrap_or(&"");
|
let mut base_url: &str = split_url.get(0).unwrap_or(&"");
|
||||||
@ -228,18 +245,25 @@ fn forward_uri<B>(forward_url: &str, req: &Request<B>) -> String {
|
|||||||
+ forward_url_query.len()
|
+ forward_url_query.len()
|
||||||
+ req.uri().query().map(|e| e.len()).unwrap_or(0);
|
+ req.uri().query().map(|e| e.len()).unwrap_or(0);
|
||||||
|
|
||||||
|
debug!("Creating url with capacity to {}", total_length);
|
||||||
|
|
||||||
let mut url = String::with_capacity(total_length);
|
let mut url = String::with_capacity(total_length);
|
||||||
|
|
||||||
url.push_str(base_url);
|
url.push_str(base_url);
|
||||||
url.push_str(path2);
|
url.push_str(path2);
|
||||||
|
|
||||||
if !forward_url_query.is_empty() || req.uri().query().map(|e| !e.is_empty()).unwrap_or(false) {
|
if !forward_url_query.is_empty() || req.uri().query().map(|e| !e.is_empty()).unwrap_or(false) {
|
||||||
|
debug!("Adding query parts to url");
|
||||||
url.push('?');
|
url.push('?');
|
||||||
url.push_str(forward_url_query);
|
url.push_str(forward_url_query);
|
||||||
|
|
||||||
if forward_url_query.is_empty() {
|
if forward_url_query.is_empty() {
|
||||||
|
debug!("Using request query");
|
||||||
|
|
||||||
url.push_str(req.uri().query().unwrap_or(""));
|
url.push_str(req.uri().query().unwrap_or(""));
|
||||||
} else {
|
} else {
|
||||||
|
debug!("Merging request and forward_url query");
|
||||||
|
|
||||||
let request_query_items = req
|
let request_query_items = req
|
||||||
.uri()
|
.uri()
|
||||||
.query()
|
.query()
|
||||||
@ -278,6 +302,8 @@ fn forward_uri<B>(forward_url: &str, req: &Request<B>) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("Built forwarding url from request: {}", url);
|
||||||
|
|
||||||
url.parse().unwrap()
|
url.parse().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +312,8 @@ fn create_proxied_request<B>(
|
|||||||
forward_url: &str,
|
forward_url: &str,
|
||||||
mut request: Request<B>,
|
mut request: Request<B>,
|
||||||
) -> Result<Request<B>, ProxyError> {
|
) -> Result<Request<B>, ProxyError> {
|
||||||
|
info!("Creating proxied request");
|
||||||
|
|
||||||
let contains_te_trailers_value = request
|
let contains_te_trailers_value = request
|
||||||
.headers()
|
.headers()
|
||||||
.get(&*TE_HEADER)
|
.get(&*TE_HEADER)
|
||||||
@ -301,6 +329,8 @@ fn create_proxied_request<B>(
|
|||||||
|
|
||||||
let uri: hyper::Uri = forward_uri(forward_url, &request).parse()?;
|
let uri: hyper::Uri = forward_uri(forward_url, &request).parse()?;
|
||||||
|
|
||||||
|
debug!("Setting headers of proxied request");
|
||||||
|
|
||||||
request
|
request
|
||||||
.headers_mut()
|
.headers_mut()
|
||||||
.insert(HOST, HeaderValue::from_str(uri.host().unwrap())?);
|
.insert(HOST, HeaderValue::from_str(uri.host().unwrap())?);
|
||||||
@ -311,12 +341,16 @@ fn create_proxied_request<B>(
|
|||||||
remove_connection_headers(request.headers_mut());
|
remove_connection_headers(request.headers_mut());
|
||||||
|
|
||||||
if contains_te_trailers_value {
|
if contains_te_trailers_value {
|
||||||
|
debug!("Setting up trailer headers");
|
||||||
|
|
||||||
request
|
request
|
||||||
.headers_mut()
|
.headers_mut()
|
||||||
.insert(&*TE_HEADER, HeaderValue::from_static("trailers"));
|
.insert(&*TE_HEADER, HeaderValue::from_static("trailers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(value) = upgrade_type {
|
if let Some(value) = upgrade_type {
|
||||||
|
debug!("Repopulate upgrade headers");
|
||||||
|
|
||||||
request
|
request
|
||||||
.headers_mut()
|
.headers_mut()
|
||||||
.insert(&*UPGRADE_HEADER, value.parse().unwrap());
|
.insert(&*UPGRADE_HEADER, value.parse().unwrap());
|
||||||
@ -328,10 +362,12 @@ fn create_proxied_request<B>(
|
|||||||
// Add forwarding information in the headers
|
// Add forwarding information in the headers
|
||||||
match request.headers_mut().entry(&*X_FORWARDED_FOR) {
|
match request.headers_mut().entry(&*X_FORWARDED_FOR) {
|
||||||
hyper::header::Entry::Vacant(entry) => {
|
hyper::header::Entry::Vacant(entry) => {
|
||||||
|
debug!("X-Fowraded-for header was vacant");
|
||||||
entry.insert(client_ip.to_string().parse()?);
|
entry.insert(client_ip.to_string().parse()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
hyper::header::Entry::Occupied(entry) => {
|
hyper::header::Entry::Occupied(entry) => {
|
||||||
|
debug!("X-Fowraded-for header was occupied");
|
||||||
let client_ip_str = client_ip.to_string();
|
let client_ip_str = client_ip.to_string();
|
||||||
let mut addr =
|
let mut addr =
|
||||||
String::with_capacity(entry.get().as_bytes().len() + 2 + client_ip_str.len());
|
String::with_capacity(entry.get().as_bytes().len() + 2 + client_ip_str.len());
|
||||||
@ -343,6 +379,8 @@ fn create_proxied_request<B>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("Created proxied request");
|
||||||
|
|
||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,11 +405,20 @@ pub async fn call(
|
|||||||
forward_uri: &str,
|
forward_uri: &str,
|
||||||
request: Request<Body>,
|
request: Request<Body>,
|
||||||
) -> Result<Response<Body>, ProxyError> {
|
) -> Result<Response<Body>, ProxyError> {
|
||||||
|
info!(
|
||||||
|
"Received proxy call from {} to {}, client: {}",
|
||||||
|
request.uri().to_string(),
|
||||||
|
forward_uri,
|
||||||
|
client_ip
|
||||||
|
);
|
||||||
|
|
||||||
let proxied_request = create_proxied_request(client_ip, forward_uri, request)?;
|
let proxied_request = create_proxied_request(client_ip, forward_uri, request)?;
|
||||||
|
|
||||||
let client = build_client();
|
let client = build_client();
|
||||||
let response = client.request(proxied_request).await?;
|
let response = client.request(proxied_request).await?;
|
||||||
let proxied_response = create_proxied_response(response);
|
let proxied_response = create_proxied_response(response);
|
||||||
|
|
||||||
|
debug!("Responding to call with response");
|
||||||
Ok(proxied_response)
|
Ok(proxied_response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user