pattern search, stateful search info, clone & mutate

This commit is contained in:
2024-12-21 23:40:05 -06:00
parent 1b81adcc86
commit 042e2cf0d6
3 changed files with 244 additions and 6 deletions

132
Cargo.lock generated
View File

@@ -333,6 +333,16 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "etag"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b3d0661a2ccddc26cba0b834e9b717959ed6fdd76c7129ee159c170a875bf44"
dependencies = [
"str-buf",
"xxhash-rust",
]
[[package]]
name = "fastrand"
version = "2.3.0"
@@ -1325,7 +1335,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.2",
"system-configuration",
"tokio",
"tokio-native-tls",
@@ -1441,6 +1451,7 @@ dependencies = [
"salvo-jwt-auth",
"salvo-proxy",
"salvo_core",
"salvo_extra",
]
[[package]]
@@ -1523,11 +1534,12 @@ dependencies = [
"pin-project",
"rand",
"regex",
"rustls-pemfile",
"salvo_macros",
"serde",
"serde-xml-rs",
"serde_json",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tempfile",
"thiserror 2.0.9",
"tokio",
@@ -1536,6 +1548,28 @@ dependencies = [
"tracing",
]
[[package]]
name = "salvo_extra"
version = "0.74.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "647f414b9f7cefc341b3c445b65d1226f375e51e469199cfd8caf4996e681610"
dependencies = [
"base64 0.22.1",
"etag",
"futures-util",
"http-body-util",
"hyper",
"pin-project",
"salvo_core",
"serde",
"serde_json",
"tokio",
"tokio-tungstenite",
"tower",
"tracing",
"ulid",
]
[[package]]
name = "salvo_macros"
version = "0.74.3"
@@ -1743,6 +1777,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "str-buf"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceb97b7225c713c2fd4db0153cb6b3cab244eb37900c3f634ed4d43310d8c34"
[[package]]
name = "subtle"
version = "2.6.1"
@@ -1760,6 +1800,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.2"
@@ -1952,6 +1998,18 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9"
dependencies = [
"futures-util",
"log",
"tokio",
"tungstenite",
]
[[package]]
name = "tokio-util"
version = "0.7.13"
@@ -1982,6 +2040,29 @@ dependencies = [
"winnow",
]
[[package]]
name = "tower"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper 0.1.2",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
@@ -2051,12 +2132,37 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tungstenite"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
dependencies = [
"byteorder",
"bytes",
"log",
"rand",
"thiserror 1.0.69",
"utf-8",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ulid"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f903f293d11f31c0c29e4148f6dc0d033a7f80cebc0282bea147611667d289"
dependencies = [
"getrandom",
"rand",
"web-time",
]
[[package]]
name = "unicase"
version = "2.8.0"
@@ -2096,6 +2202,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf16_iter"
version = "1.0.5"
@@ -2231,6 +2343,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
@@ -2392,6 +2514,12 @@ version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432"
[[package]]
name = "xxhash-rust"
version = "0.8.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08fd76779ae1883bbf1e46c2c46a75a0c4e37c445e68a24b01479d438f26ae6"
[[package]]
name = "yoke"
version = "0.7.5"

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
salvo = "0.74.3"
salvo = { version = "0.74.3", features = ["affix-state", "logging"] }
tokio = { version = "1", features = ["macros"] }
tracing = "0.1"
tracing-subscriber = "0.3"
tracing-subscriber = "0.3"

View File

@@ -1,17 +1,127 @@
use salvo::http::HeaderValue;
use salvo::logging::Logger;
use salvo::prelude::*;
fn search(buf: &[u8], pattern: &[u8], start_index: usize) -> Option<usize> {
let mut i = start_index;
// If the buffer is empty, the pattern is too long
if pattern.len() > buf.len() {
return None;
}
// If the pattern is empty
if pattern.len() == 0 {
return None;
}
// If the starting index is too high
if start_index >= buf.len() {
return None;
}
while i < buf.len() {
for j in 0..pattern.len() {
// If the pattern is too long to fit in the buffer anymore
if i + j >= buf.len() {
return None;
}
// If the pattern stops matching
if buf[i + j] != pattern[j] {
break;
}
// If the pattern is found
if j == pattern.len() - 1 {
return Some(i);
}
}
i += 1;
}
None
}
#[handler]
async fn hello() -> &'static str {
"Hello World"
}
#[handler]
async fn download(depot: &mut Depot, req: &mut Request, res: &mut Response) {
let state = depot.obtain::<State>().unwrap();
let data = state.with_key(b"test"); // Clone the data
if let Err(e) = res.write_body(data) {
eprintln!("Error writing body: {}", e);
}
res.headers.insert(
"Content-Disposition",
HeaderValue::from_static("attachment; filename=demo"),
);
res.headers.insert(
"Content-Type",
HeaderValue::from_static("application/octet-stream"),
);
}
#[allow(dead_code)]
#[derive(Default, Clone, Debug)]
struct State {
data: Vec<u8>,
key_start: usize,
key_end: usize,
}
impl State {
fn with_key(&self, new_key: &[u8]) -> Vec<u8> {
let mut data = self.data.clone();
// Copy the key into the data
for i in 0..new_key.len() {
data[self.key_start + i] = new_key[i];
}
// If the new key is shorter than the old key, we just write over the remaining data
if new_key.len() < self.key_end - self.key_start {
for i in self.key_start + new_key.len()..self.key_end {
data[i] = b' ';
}
}
return data;
}
}
#[tokio::main]
async fn main() {
let port = std::env::var("PORT").unwrap_or_else(|_| "5800".to_string());
let addr = format!("0.0.0.0:{}", port);
tracing_subscriber::fmt().init();
let router = Router::new().get(hello);
let path = "./demo/target/release/demo";
let data = std::fs::read(&path).expect("Unable to read file");
let pattern = "a".repeat(1024);
let key_start = search(&data, pattern.as_bytes(), 0).unwrap();
let key_end = key_start + pattern.len();
let state = State {
data,
key_start: key_start,
key_end: key_end,
};
let router = Router::new()
.hoop(affix_state::inject(state))
.get(hello)
.push(Router::with_path("download").get(download));
let service = Service::new(router).hoop(Logger::new());
let acceptor = TcpListener::new(addr).bind().await;
Server::new(acceptor).serve(router).await;
Server::new(acceptor).serve(service).await;
}