diff --git a/Cargo.toml b/Cargo.toml index 9638bd8..db3a9be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,9 @@ edition = "2018" [workspace] members = [ - "http-signature-normalization-http", "http-signature-normalization-actix", + "http-signature-normalization-http", + "http-signature-normalization-warp", ] [dependencies] diff --git a/http-signature-normalization-warp/Cargo.toml b/http-signature-normalization-warp/Cargo.toml new file mode 100644 index 0000000..02dd66f --- /dev/null +++ b/http-signature-normalization-warp/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "http-signature-normalization-warp" +version = "0.1.0" +authors = ["asonix "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +http = "0.2.0" +http-signature-normalization-http = { version = "0.2.0", path = "../http-signature-normalization-http" } +warp = { git = "https://github.com/seanmonstar/warp" } +futures = "0.3.1" diff --git a/http-signature-normalization-warp/src/lib.rs b/http-signature-normalization-warp/src/lib.rs new file mode 100644 index 0000000..92492ca --- /dev/null +++ b/http-signature-normalization-warp/src/lib.rs @@ -0,0 +1,40 @@ +use http::{header::HeaderMap, Method}; +pub use http_signature_normalization_http::{Config, verify::Unverified}; +use std::{future::Future, pin::Pin}; +use warp::{path::FullPath, Filter, Rejection}; + +pub fn verify( + config: Config, + verifier: impl Fn(Unverified) -> Pin> + Send>> + Clone + Send + Sync, +) -> impl Filter + Clone +where + T: Send, +{ + warp::any() + .map(move || config.clone()) + .and(warp::header::headers_cloned()) + .and(warp::method()) + .and(warp::path::full()) + .and(warp::query::raw()) + .and_then(move |config, headers, method, path, query| { + do_verify(config, headers, method, path, query, verifier.clone()) + }) +} + +async fn do_verify( + config: Config, + headers: HeaderMap, + method: Method, + path: FullPath, + query: String, + verifier: impl Fn(Unverified) -> Pin> + Send>>, +) -> Result { + let path_and_query = format!("{}?{}", path.as_str(), query).parse().unwrap(); + + match config.begin_verify(&method, Some(&path_and_query), headers) { + Ok(v) => verifier(v) + .await + .map_err(|_| warp::reject::not_found()), + Err(_) => Err(warp::reject::not_found()), + } +}