Skip to content

Commit

Permalink
fix: use path and query instead of url to check endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyrix126 committed Jul 8, 2024
1 parent 0dc4bf4 commit 3ba714b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 15 deletions.
14 changes: 9 additions & 5 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -73,19 +73,23 @@ pub async fn handler(State(state): State<AppState>, 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
Expand Down
15 changes: 10 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
15 changes: 10 additions & 5 deletions src/index_cache.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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);
Expand All @@ -37,9 +38,13 @@ impl IndexCache {
/// Will return the uuid of the entry.
pub fn request_to_uuid(&self, request: &Request<Body>) -> Option<Uuid> {
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)| {
Expand Down

0 comments on commit 3ba714b

Please sign in to comment.