From 6ab2b9badc1f643b5bf45ffe0ad303f97761679e Mon Sep 17 00:00:00 2001 From: Matthias Wright Date: Tue, 23 Apr 2024 22:20:30 +0800 Subject: [PATCH] feat(js-poc): pass request info to js function --- core/handshake/src/transports/http/handler.rs | 1 - services/js-poc/examples/js-poc-client.rs | 1 + services/js-poc/src/lib.rs | 52 ++++++++++++++----- services/js-poc/src/runtime/mod.rs | 8 ++- services/js-poc/src/stream.rs | 4 ++ 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/core/handshake/src/transports/http/handler.rs b/core/handshake/src/transports/http/handler.rs index f80c439af..a17ac84f8 100644 --- a/core/handshake/src/transports/http/handler.rs +++ b/core/handshake/src/transports/http/handler.rs @@ -62,7 +62,6 @@ pub async fn handler( TransportDetail::HttpRequest { method, uri: extract_url(&path, uri), - // TODO header: headers .into_iter() .filter_map(|(name, val)| { diff --git a/services/js-poc/examples/js-poc-client.rs b/services/js-poc/examples/js-poc-client.rs index 3aba0f68f..79b2e5391 100644 --- a/services/js-poc/examples/js-poc-client.rs +++ b/services/js-poc/examples/js-poc-client.rs @@ -33,6 +33,7 @@ async fn main() -> anyhow::Result<()> { origin, uri, path: None, + headers: None, param, }) .expect("failed to encode request") diff --git a/services/js-poc/src/lib.rs b/services/js-poc/src/lib.rs index 15c3997e9..ab6b513f0 100644 --- a/services/js-poc/src/lib.rs +++ b/services/js-poc/src/lib.rs @@ -79,7 +79,8 @@ async fn handle_connection( let TransportDetail::HttpRequest { uri, .. } = &connection.header.transport_detail else { unreachable!() }; - let request = extract_request(uri, &body).context("Could not parse request")?; + let request = extract_request(uri, &body, &connection.header.transport_detail) + .context("Could not parse request")?; handle_request(&mut connection, &tx, request).await?; } else { while let Some(payload) = connection.read_payload().await { @@ -95,10 +96,13 @@ async fn handle_request( tx: &UnboundedSender, request: Request, ) -> anyhow::Result<()> { + let req_params = serde_json::to_value(&request)?; + let Request { origin, uri, path, + headers: _, param, } = request; @@ -184,7 +188,10 @@ async fn handle_request( tx.send(runtime.deno.v8_isolate().thread_safe_handle()) .context("Failed to send the IsolateHandle to main thread.")?; - let res = match runtime.exec(location, source, param).await { + let res = match runtime + .exec(location, source, param, Some(req_params)) + .await + { Ok(Some(res)) => res, Ok(None) => { connection @@ -266,7 +273,7 @@ async fn handle_request( Ok(()) } -fn extract_request(url: &Url, body: &[u8]) -> Option { +fn extract_request(url: &Url, body: &[u8], detail: &TransportDetail) -> Option { let mut segments = url.path_segments()?; let seg1 = segments.next()?; let seg2 = segments.next()?; @@ -305,10 +312,17 @@ fn extract_request(url: &Url, body: &[u8]) -> Option { Some(serde_json::from_slice::(body).ok()?) }; + let headers = if let TransportDetail::HttpRequest { header, .. } = &detail { + Some(header.clone()) + } else { + None + }; + Some(Request { origin, uri: seg2.to_string(), path: Some(path), + headers, param, }) } @@ -323,17 +337,19 @@ mod tests { serde_json::to_vec(&value).unwrap() } - #[test] - fn test_extract_request() { + #[tokio::test] + async fn test_extract_request() { assert_eq!( extract_request( &Url::parse("http://fleek/blake3/content-hash/").unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/".to_string()), + headers: None, param: None, }) ); @@ -341,12 +357,14 @@ mod tests { assert_eq!( extract_request( &Url::parse("http://fleek/blake3/content-hash/a").unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a".to_string()), + headers: None, param: None, }) ); @@ -354,12 +372,14 @@ mod tests { assert_eq!( extract_request( &Url::parse("http://fleek/blake3/content-hash/a/b").unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a/b".to_string()), + headers: None, param: None, }) ); @@ -367,12 +387,14 @@ mod tests { assert_eq!( extract_request( &Url::parse("http://fleek/blake3/content-hash/a/b?a=4").unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a/b?a=4".to_string()), + headers: None, param: None, }) ); @@ -380,12 +402,14 @@ mod tests { assert_eq!( extract_request( &Url::parse("http://fleek/blake3/content-hash/a/b?a=4#hello").unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a/b?a=4#hello".to_string()), + headers: None, param: None, }) ); @@ -396,12 +420,14 @@ mod tests { "http://fleek/blake3/content-hash/a/b?a=4¶m=%7B%22a%22%3A%204%7D#hello" ) .unwrap(), - &[] + &[], + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a/b?a=4¶m=%7B%22a%22%3A%204%7D#hello".to_string()), + headers: None, param: Some(json!({"a": 4})), }) ); @@ -412,12 +438,14 @@ mod tests { "http://fleek/blake3/content-hash/a/b?a=4¶m=%7B%22a%22%3A%204%7D#hello" ) .unwrap(), - &body(json!({"hello": 5})) + &body(json!({"hello": 5})), + &TransportDetail::Other, ), Some(Request { origin: Origin::Blake3, uri: "content-hash".to_string(), path: Some("/a/b?a=4¶m=%7B%22a%22%3A%204%7D#hello".to_string()), + headers: None, param: Some(json!({"hello": 5})), }) ); diff --git a/services/js-poc/src/runtime/mod.rs b/services/js-poc/src/runtime/mod.rs index 364729d51..1ae0f0cfc 100644 --- a/services/js-poc/src/runtime/mod.rs +++ b/services/js-poc/src/runtime/mod.rs @@ -152,6 +152,7 @@ impl Runtime { url: Url, source: String, param: Option, + req_params: Option, ) -> anyhow::Result>> { let id = self .deno @@ -184,10 +185,15 @@ impl Runtime { } else { v8::undefined(scope).into() }; + let req_params = if let Some(req_params) = req_params { + serde_v8::to_v8(scope, req_params)? + } else { + v8::undefined(scope).into() + }; let undefined = v8::undefined(scope); // call function and move response into a global ref - let Some(res) = main_fn.call(scope, undefined.into(), &[param]) else { + let Some(res) = main_fn.call(scope, undefined.into(), &[param, req_params]) else { return Ok(None); }; Ok(Some(Global::new(scope, res))) diff --git a/services/js-poc/src/stream.rs b/services/js-poc/src/stream.rs index 873f15403..e29da3210 100644 --- a/services/js-poc/src/stream.rs +++ b/services/js-poc/src/stream.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use fn_sdk::api::Origin as ApiOrigin; use serde::{Deserialize, Serialize}; @@ -12,6 +14,8 @@ pub struct Request { pub uri: String, /// Optional path to provide as the window location pub path: Option, + /// Headers from the http request + pub headers: Option>, /// Parameter to pass to the script's main function #[serde(skip_serializing_if = "Option::is_none")] pub param: Option,