From 1492d68e25d244794562491d72cbad642a23ee86 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 3 Nov 2025 02:03:32 +0000 Subject: [PATCH] Additional tracing of request body. Optimize router request parse types. Signed-off-by: Jason Volk --- src/api/router/args.rs | 16 +++++----------- src/api/router/auth/appservice.rs | 2 +- src/api/router/request.rs | 16 +++++++++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/api/router/args.rs b/src/api/router/args.rs index e227f79d..11e25e19 100644 --- a/src/api/router/args.rs +++ b/src/api/router/args.rs @@ -6,7 +6,7 @@ use ruma::{ CanonicalJsonObject, CanonicalJsonValue, DeviceId, OwnedDeviceId, OwnedServerName, OwnedUserId, ServerName, UserId, api::IncomingRequest, }; -use tuwunel_core::{Error, Result, debug, debug_warn, err, trace, utils::string::EMPTY}; +use tuwunel_core::{Error, Result, debug_warn, err, trace, utils::string::EMPTY}; use tuwunel_service::{Services, appservice::RegistrationInfo}; use super::{auth, auth::Auth, request, request::Request}; @@ -95,6 +95,7 @@ where ) -> Result { let mut request = request::from(services, request).await?; let mut json_body = serde_json::from_slice::(&request.body).ok(); + trace!(?request); // while very unusual and really shouldn't be recommended, Synapse accepts POST // requests with a completely empty body. very old clients, libraries, and some @@ -104,13 +105,13 @@ where && request.parts.method == http::Method::POST && !request.parts.uri.path().contains("/media/") { - trace!("json_body from_request: {:?}", json_body.clone()); debug_warn!( "received a POST request with an empty body, defaulting/assuming to {{}} like \ Synapse does" ); json_body = Some(CanonicalJsonValue::Object(CanonicalJsonObject::new())); } + let auth = auth::auth(services, &mut request, json_body.as_ref(), &T::METADATA).await?; Ok(Self { body: make_body::(services, &mut request, json_body.as_mut(), &auth)?, @@ -147,16 +148,9 @@ fn into_http_request(request: &Request, body: Bytes) -> hyper::Request { .headers_mut() .expect("mutable http headers") = request.parts.headers.clone(); - let http_request = http_request - .body(body) - .expect("http request body"); - - let headers = http_request.headers(); - let method = http_request.method(); - let uri = http_request.uri(); - debug!("{method:?} {uri:?} {headers:?}"); - http_request + .body(body) + .expect("http request body") } #[allow(clippy::needless_pass_by_value)] diff --git a/src/api/router/auth/appservice.rs b/src/api/router/auth/appservice.rs index 14132d1f..9fc4ae09 100644 --- a/src/api/router/auth/appservice.rs +++ b/src/api/router/auth/appservice.rs @@ -19,7 +19,7 @@ pub(super) async fn auth_appservice( let Ok(user_id) = request .query .user_id - .clone() + .as_deref() .map_or_else(user_id_default, OwnedUserId::parse) else { return Err!(Request(InvalidUsername("Username is invalid."))); diff --git a/src/api/router/request.rs b/src/api/router/request.rs index 5df1c625..1e5b783b 100644 --- a/src/api/router/request.rs +++ b/src/api/router/request.rs @@ -4,22 +4,28 @@ use axum::{RequestExt, RequestPartsExt, extract::Path}; use bytes::Bytes; use http::request::Parts; use serde::Deserialize; -use tuwunel_core::{Result, err}; +use tuwunel_core::{Result, err, smallstr::SmallString, smallvec::SmallVec}; use tuwunel_service::Services; -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] pub(super) struct QueryParams { pub(super) access_token: Option, - pub(super) user_id: Option, + pub(super) user_id: Option, } +pub(super) type UserId = SmallString<[u8; 48]>; + +#[derive(Debug)] pub(super) struct Request { - pub(super) path: Path>, + pub(super) path: Path, pub(super) query: QueryParams, pub(super) body: Bytes, pub(super) parts: Parts, } +pub(super) type PathParams = SmallVec<[PathParam; 8]>; +pub(super) type PathParam = SmallString<[u8; 32]>; + pub(super) async fn from( services: &Services, request: hyper::Request, @@ -27,7 +33,7 @@ pub(super) async fn from( let limited = request.with_limited_body(); let (mut parts, body) = limited.into_parts(); - let path: Path> = parts.extract().await?; + let path: Path = parts.extract().await?; let query = parts.uri.query().unwrap_or_default(); let query = serde_html_form::from_str(query) .map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?;