Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ harness = false
name = "nuget_cache"
harness = false

[[example]]
name = "deviceatlas"
harness = false

[dependencies]
hyper = { version = "1.2", features = ["full"] }
hyper-tls = { version = "0.6.0" }
Expand All @@ -53,6 +57,8 @@ futures-core = "0.3.30"
prometheus = "0.13"
serde-inline-default = "0.2.3"
enum_dispatch = "0.3.13"
foyer = "0.17"
postcard = "1.1.3"

[dev-dependencies]
tonic = "0.11"
Expand Down
28 changes: 28 additions & 0 deletions examples/deviceatlas/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
listening_port: 8080
prometheus_port: 8081
heathcheck_port: 8082
minimum_log_level: info

middlewares:
- log:
level: info
value: 'Cache status: $cache_status, Forward target: $forward_target'
- add_response_header:
name: 'X-Cache-Status'
value: '$cache_status'
- use_cache:
cache_name: files
when:
status_code_is: 200
- forward_request:
scheme: https
target_host: deviceatlas.com

caches:
- hybrid:
name: files
path: /tmp/cacheus/deviceatlas
ttl_seconds: 10
hash_path: false
hash_query: true
hash_body: false
17 changes: 17 additions & 0 deletions examples/deviceatlas/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use cacheus::{self, CacheusServer};
use futures::join;
use log::info;
use tokio::signal;

#[tokio::main]
async fn main()
{
let cacheus_fut = CacheusServer::start_from_config_file("examples/deviceatlas/config.yaml");

join!(cacheus_fut);

// Wait for SIGTERM or SIGINT
signal::ctrl_c().await.expect("failed to listen for ctrl_c");

info!("Shutting down Cacheus server...");
}
2 changes: 0 additions & 2 deletions examples/download/config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
listening_port: 3001
prometheus_port: 8081
https: false
http2: false
minimum_log_level: debug

middlewares:
Expand Down
4 changes: 1 addition & 3 deletions examples/hello/config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
default_target_host: 127.0.0.1:3002
listening_port: 3001
https: false
http2: false
listening_port: 3001
3 changes: 1 addition & 2 deletions examples/hello_grpc/config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
listening_port: 3001
https: false
http2: true
http2_only: true
2 changes: 0 additions & 2 deletions examples/nuget_cache/config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
listening_port: 4002
prometheus_port: 4004
https: true
http2: false
minimum_log_level: 'debug'

middlewares:
Expand Down
68 changes: 67 additions & 1 deletion src/buffered_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use futures::Future;
use hyper::body::{Body, Frame};
use hyper::HeaderMap;
use pin_project_lite::pin_project;
use serde::{Deserialize, Serialize};

pin_project! {
/// Future that resolves into a [`Collected`].
Expand Down Expand Up @@ -56,6 +57,71 @@ pub struct BufferedBody
trailers: Option<HeaderMap>,
}

impl BufferedBody {
pub fn to_bytes(&self) -> Vec<u8> {
let mut v = Vec::new();

// Serialize bufs length + data
let data = self.bufs.as_ref();
let len = data.len() as u64;
v.extend_from_slice(&len.to_le_bytes());
v.extend_from_slice(data);

// Serialize trailers as optional key/value map
if let Some(t) = &self.trailers {
v.push(1); // present flag
let map: HashMap<String, Vec<String>> = t
.iter()
.map(|(k, v)| (k.to_string(), v.to_str().map(|s| vec![s.to_string()]).unwrap_or_default()))
.collect();
let mut buffer = Vec::new();
let encoded = postcard::to_slice(&map, &mut buffer).unwrap();
v.extend_from_slice(&(encoded.len() as u64).to_le_bytes());
v.extend_from_slice(&encoded);
} else {
v.push(0); // not present
}

v
}

pub fn from_bytes(bytes: &[u8]) -> Self {
use std::convert::TryInto;
let mut pos = 0;

// bufs
let len = u64::from_le_bytes(bytes[pos..pos + 8].try_into().unwrap()) as usize;
pos += 8;
let buf = BytesMut::from(&bytes[pos..pos + len]);
pos += len;

// trailers
let has_trailers = bytes[pos] == 1;
pos += 1;

let trailers = if has_trailers {
let map_len = u64::from_le_bytes(bytes[pos..pos + 8].try_into().unwrap()) as usize;
pos += 8;
let map_bytes = &bytes[pos..pos + map_len];
let map: HashMap<String, Vec<String>> = postcard::from_bytes(map_bytes).unwrap();
let mut hm = HeaderMap::new();
for (k, vs) in map {
for v in vs {
hm.append(
k.parse::<hyper::header::HeaderName>().unwrap(),
v.parse::<hyper::header::HeaderValue>().unwrap(),
);
}
}
Some(hm)
} else {
None
};

BufferedBody { bufs: buf, trailers }
}
}

impl BufferedBody
{
pub fn replace_strings(&mut self, find: &String, replacement: &String) -> usize
Expand Down Expand Up @@ -114,7 +180,7 @@ impl BufferedBody
}
}

pub fn from_bytes(b: &[u8]) -> BufferedBody
pub fn from_body(b: &[u8]) -> BufferedBody
{
let mut bufs = BytesMut::new();
bufs.extend(b);
Expand Down
Loading