mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 15:51:23 +01:00
Log curl command line for all requests at trace
This commit is contained in:
parent
b0f33207fe
commit
5c4062742f
3 changed files with 103 additions and 19 deletions
|
|
@ -64,7 +64,7 @@ use ruma::{
|
||||||
};
|
};
|
||||||
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
|
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tracing::{debug, error, field, warn};
|
use tracing::{debug, error, field, trace, trace_span, warn};
|
||||||
|
|
||||||
use super::appservice_server;
|
use super::appservice_server;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -253,6 +253,14 @@ where
|
||||||
signature,
|
signature,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
// can be enabled selectively using `filter =
|
||||||
|
// grapevine[outgoing_request_curl]=trace` in config
|
||||||
|
trace_span!("outgoing_request_curl").in_scope(|| {
|
||||||
|
trace!(
|
||||||
|
cmd = utils::curlify(&http_request),
|
||||||
|
"curl command line for outgoing request"
|
||||||
|
);
|
||||||
|
});
|
||||||
let reqwest_request = reqwest::Request::try_from(http_request)?;
|
let reqwest_request = reqwest::Request::try_from(http_request)?;
|
||||||
|
|
||||||
let url = reqwest_request.url().clone();
|
let url = reqwest_request.url().clone();
|
||||||
|
|
|
||||||
52
src/main.rs
52
src/main.rs
|
|
@ -147,26 +147,42 @@ async fn run_server() -> Result<(), error::Serve> {
|
||||||
let middlewares = ServiceBuilder::new()
|
let middlewares = ServiceBuilder::new()
|
||||||
.sensitive_headers([header::AUTHORIZATION])
|
.sensitive_headers([header::AUTHORIZATION])
|
||||||
.layer(axum::middleware::from_fn(spawn_task))
|
.layer(axum::middleware::from_fn(spawn_task))
|
||||||
.layer(TraceLayer::new_for_http().make_span_with(
|
.layer(
|
||||||
|request: &http::Request<_>| {
|
TraceLayer::new_for_http()
|
||||||
let endpoint = if let Some(endpoint) =
|
.make_span_with(|request: &http::Request<_>| {
|
||||||
request.extensions().get::<MatchedPath>()
|
let endpoint = if let Some(endpoint) =
|
||||||
{
|
request.extensions().get::<MatchedPath>()
|
||||||
endpoint.as_str()
|
{
|
||||||
} else {
|
endpoint.as_str()
|
||||||
request.uri().path()
|
} else {
|
||||||
};
|
request.uri().path()
|
||||||
|
};
|
||||||
|
|
||||||
let method = request.method();
|
let method = request.method();
|
||||||
|
|
||||||
tracing::info_span!(
|
tracing::info_span!(
|
||||||
"http_request",
|
"http_request",
|
||||||
otel.name = format!("{method} {endpoint}"),
|
otel.name = format!("{method} {endpoint}"),
|
||||||
%method,
|
%method,
|
||||||
%endpoint,
|
%endpoint,
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
))
|
.on_request(
|
||||||
|
|request: &http::Request<_>, _span: &tracing::Span| {
|
||||||
|
// can be enabled selectively using `filter =
|
||||||
|
// grapevine[incoming_request_curl]=trace` in config
|
||||||
|
tracing::trace_span!("incoming_request_curl").in_scope(
|
||||||
|
|| {
|
||||||
|
tracing::trace!(
|
||||||
|
cmd = utils::curlify(request),
|
||||||
|
"curl command line for incoming request \
|
||||||
|
(guessed hostname)"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
.layer(axum::middleware::from_fn(unrecognized_method))
|
.layer(axum::middleware::from_fn(unrecognized_method))
|
||||||
.layer(
|
.layer(
|
||||||
CorsLayer::new()
|
CorsLayer::new()
|
||||||
|
|
|
||||||
60
src/utils.rs
60
src/utils.rs
|
|
@ -306,6 +306,66 @@ impl<'a> TryFrom<&'a MxcUri> for MxcData<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn curlify_args<T>(req: &http::Request<T>) -> Option<Vec<String>> {
|
||||||
|
let mut args =
|
||||||
|
vec!["curl".to_owned(), "-X".to_owned(), req.method().to_string()];
|
||||||
|
|
||||||
|
for (name, val) in req.headers() {
|
||||||
|
args.extend([
|
||||||
|
"-H".to_owned(),
|
||||||
|
format!("{name}: {}", val.to_str().ok()?),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fix_uri = || {
|
||||||
|
if req.uri().scheme().is_some() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if req.uri().authority().is_some() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut parts = req.uri().clone().into_parts();
|
||||||
|
|
||||||
|
parts.scheme = Some(http::uri::Scheme::HTTPS);
|
||||||
|
|
||||||
|
let host =
|
||||||
|
req.headers().get(http::header::HOST)?.to_str().ok()?.to_owned();
|
||||||
|
parts.authority =
|
||||||
|
Some(http::uri::Authority::from_maybe_shared(host).ok()?);
|
||||||
|
|
||||||
|
http::uri::Uri::from_parts(parts).ok()
|
||||||
|
};
|
||||||
|
|
||||||
|
let uri = if let Some(new_uri) = fix_uri() {
|
||||||
|
Cow::Owned(new_uri)
|
||||||
|
} else {
|
||||||
|
Cow::Borrowed(req.uri())
|
||||||
|
};
|
||||||
|
|
||||||
|
args.push(uri.to_string());
|
||||||
|
|
||||||
|
Some(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn curlify<T>(req: &http::Request<T>) -> Option<String> {
|
||||||
|
let args = curlify_args(req)?;
|
||||||
|
|
||||||
|
Some(
|
||||||
|
args.into_iter()
|
||||||
|
.map(|arg| {
|
||||||
|
if arg.chars().all(|c| {
|
||||||
|
c.is_alphanumeric() || ['-', '_', ':', '/'].contains(&c)
|
||||||
|
}) {
|
||||||
|
arg
|
||||||
|
} else {
|
||||||
|
format!("'{}'", arg.replace('\'', "\\'"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::utils::dbg_truncate_str;
|
use crate::utils::dbg_truncate_str;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue