diff --git a/src/api.rs b/src/api.rs index e307f58..2641ecf 100644 --- a/src/api.rs +++ b/src/api.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use axum::{ body::to_bytes, extract::{Path, Request, State}, - http::{HeaderMap, HeaderValue}, + http::{uri::PathAndQuery, HeaderMap, HeaderValue}, response::IntoResponse, }; use enclose::enc; @@ -73,19 +73,23 @@ pub async fn handler(State(state): State, request: Request) -> impl In // if not in cache, make the request to backend service let req_method = request.method().to_owned(); let req_headers = request.headers().to_owned(); - let req_uri = request.uri().to_owned(); + let req_uri = request + .uri() + .path_and_query() + .cloned() + .unwrap_or(PathAndQuery::from_static("")); debug!("response was not cached, requesting backend service"); let url_backend = state.config.to_backend_uri(&req_uri); debug!("Request URI retrieved: {req_uri}"); debug!("Request URL transmitted:{url_backend}"); - match state + let req = state .client .request(request.method().to_owned(), url_backend) .headers(request.headers().to_owned()) .body(to_bytes(request.into_body(), usize::MAX).await.unwrap()) .send() - .await - { + .await; + match req { Ok(mut rep) => { // first send Response and then cache so client wait as little as possible. // need to add Etag headers to response diff --git a/src/config.rs b/src/config.rs index e49fbbb..d27d0f4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,16 +3,17 @@ use std::{ time::Duration, }; -use axum::http::Uri; +use axum::http::uri::PathAndQuery; use reqwest::Url; use serde::{Deserialize, Serialize}; +use tracing::debug; /// configuration struct. /// Example: /// listen_port: 9834, /// endpoints: [("/api1", "127.0.0.1:3998")] /// request /api1/abc /// will do 127.0.0.1:3998/abc -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct Config { /// address and port to which Mnemosyne will listen for incoming requests. pub listen_address: SocketAddr, @@ -36,13 +37,17 @@ impl Default for Config { } impl Config { - pub fn to_backend_uri(&self, uri_request: &Uri) -> Url { + pub fn to_backend_uri(&self, uri_request: &PathAndQuery) -> Url { + //todo use regex to get the start of the line if let Some((endpoint, url)) = self .endpoints .iter() - .find(|b| uri_request.to_string().contains(&format!("^{}", b.0))) + .find(|b| uri_request.as_str().starts_with(&b.0)) { + debug!("endpoint detected: {endpoint}"); let new_uri = uri_request.to_string().replace(endpoint, ""); + debug!("url: {url}"); + debug!("new uri: {new_uri}"); Url::parse(&format!("{}{}", url, new_uri).replace("//", "/")) .expect("could not parse to Url") } else { @@ -53,7 +58,7 @@ impl Config { } } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct CacheConfig { /// cache expiration after last request pub expiration: Duration, diff --git a/src/index_cache.rs b/src/index_cache.rs index 625a02b..ad55357 100644 --- a/src/index_cache.rs +++ b/src/index_cache.rs @@ -1,14 +1,15 @@ use ahash::HashMap; use ahash::HashMapExt; use axum::body::Body; +use axum::http::uri::PathAndQuery; use axum::http::HeaderValue; -use axum::http::{HeaderMap, Request, Uri}; +use axum::http::{HeaderMap, Request}; use derive_more::{Deref, DerefMut}; use reqwest::Method; use uuid::Uuid; #[derive(Deref, DerefMut, Clone)] /// IndexCache will store entry for each combination of uri/method with a vec of uuid per HeaderMap. HeaderMap here are request headers that match the headers name in the Vary header value response. -pub struct IndexCache(pub HashMap<(axum::http::Method, Uri), Vec<(Uuid, HeaderMap)>>); +pub struct IndexCache(pub HashMap<(axum::http::Method, PathAndQuery), Vec<(Uuid, HeaderMap)>>); impl IndexCache { pub fn new() -> Self { @@ -18,7 +19,7 @@ impl IndexCache { &mut self, uuid: Uuid, req_method: Method, - req_uri: Uri, + req_uri: PathAndQuery, req_headers_match_vary: HeaderMap, ) { let key = (req_method, req_uri); @@ -37,9 +38,13 @@ impl IndexCache { /// Will return the uuid of the entry. pub fn request_to_uuid(&self, request: &Request) -> Option { let method = request.method().to_owned(); - let uri = request.uri().to_owned(); + let uri = request + .uri() + .path_and_query() + .cloned() + .unwrap_or(PathAndQuery::from_static("")); let headermap = request.headers(); - if let Some(uuids) = self.get(&(method, uri)) { + if let Some(uuids) = self.get(&(method, uri.clone())) { return uuids .iter() .find(|(_, headermap_object)| {