Skip to content

Commit

Permalink
Update code w.r.t. new Spiderfire version
Browse files Browse the repository at this point in the history
  • Loading branch information
Arshia001 committed Nov 22, 2023
1 parent b83456f commit fee76ad
Show file tree
Hide file tree
Showing 9 changed files with 376 additions and 417 deletions.
294 changes: 134 additions & 160 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ ion = { package = "ion", features = [
"macros",
], git = "https://github.com/wasmerio/spiderfire.git" }
ion-proc = { package = "ion-proc", git = "https://github.com/wasmerio/spiderfire.git" }
runtime = { package = "runtime", git = "https://github.com/wasmerio/spiderfire.git" }
runtime = { package = "runtime", git = "https://github.com/wasmerio/spiderfire.git", features = ["fetch"]}
modules = { package = "modules", git = "https://github.com/wasmerio/spiderfire.git" }
mozjs = { version = "0.14.1", git = "https://github.com/wasmerio/mozjs.git", branch = "wasi-gecko", features = [
"streams",
Expand Down
32 changes: 0 additions & 32 deletions src/ion_runner/base64.rs

This file was deleted.

16 changes: 10 additions & 6 deletions src/ion_runner/crypto/subtle.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ion::{function_spec, typedarray::ArrayBuffer, Context, Object};
use ion::{function_spec, Context, Object};
use mozjs_sys::jsapi::{JSFunctionSpec, JSObject};
use runtime::promise::future_to_promise;

use super::algorithm::{md5::Md5, sha::Sha, CryptoAlgorithm};

Expand Down Expand Up @@ -98,13 +99,16 @@ impl AlgorithmIdentifier {
}

#[js_fn]
async fn digest(
cx: &Context<'_>,
fn digest<'cx>(
cx: &'cx Context,
algorithm: AlgorithmIdentifier,
data: BufferSource,
) -> ion::Result<ArrayBuffer> {
let alg = algorithm.get_algorithm(cx)?;
alg.digest(algorithm.into_params(cx), data)
) -> Option<ion::Promise<'cx>> {
let cx2 = unsafe { Context::new_unchecked(cx.as_ptr()) };
future_to_promise(cx, async move {
let alg = algorithm.get_algorithm(&cx2)?;
alg.digest(algorithm.into_params(&cx2), data)
})
}

const METHODS: &[JSFunctionSpec] = &[function_spec!(digest, 2), JSFunctionSpec::ZERO];
Expand Down
2 changes: 1 addition & 1 deletion src/ion_runner/event_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ static METHODS: &[JSFunctionSpec] = &[
JSFunctionSpec::ZERO,
];

pub fn define<'cx: 'o, 'o>(cx: &'cx Context, global: &mut Object<'o>) -> bool {
pub fn define(cx: &Context, global: &mut Object) -> bool {
unsafe { global.define_methods(cx, METHODS) }
}
212 changes: 104 additions & 108 deletions src/ion_runner/fetch_event.rs
Original file line number Diff line number Diff line change
@@ -1,133 +1,129 @@
pub use class::FetchEvent;
use anyhow::anyhow;
use ion::string::byte::ByteString;
use ion::{class::Reflector, ClassDefinition, Context, Object, Promise, Value};
use mozjs::jsapi::{HandleValueArray, JSObject};
use mozjs::rooted;
use mozjs_sys::jsgc::Heap;
use mozjs_sys::jsval::ObjectValue;
use runtime::globals::{fetch::Headers, url::URL};

use super::request::ExecuteRequest;

#[js_class]
pub mod class {
use anyhow::anyhow;
use ion::{ClassDefinition, Context, Object, Promise, Value};
use mozjs::gc::Traceable;
use mozjs::jsapi::{HandleValueArray, JSObject};
use mozjs::rooted;
use mozjs_sys::jsapi::JSTracer;
use mozjs_sys::jsgc::Heap;
use mozjs_sys::jsval::ObjectValue;
use runtime::globals::{fetch::Headers, url::Url};
pub struct FetchEvent {
reflector: Reflector,
pub(crate) request: Box<Heap<*mut JSObject>>,
pub(crate) response: Option<Box<Heap<*mut JSObject>>>,
}

use super::super::request::ExecuteRequest;
impl FetchEvent {
pub fn try_new(
cx: &Context,
req: http::request::Parts,
body: Option<bytes::Bytes>,
) -> anyhow::Result<Self> {
let body_bytes = body.as_ref().map(|b| b.as_ref());
let body = match (&req.method, body_bytes) {
(&http::Method::GET, _) | (&http::Method::HEAD, _) | (_, Some(b"")) | (_, None) => None,
_ => body,
};

#[ion(into_value, no_constructor)]
pub struct FetchEvent {
pub(crate) request: Box<Heap<*mut JSObject>>,
pub(crate) response: Option<Box<Heap<*mut JSObject>>>,
}

impl FetchEvent {
#[ion(skip)]
pub fn try_new(
cx: &Context,
req: http::request::Parts,
body: Option<bytes::Bytes>,
) -> anyhow::Result<Self> {
let body_bytes = body.as_ref().map(|b| b.as_ref());
let body = match (&req.method, body_bytes) {
(&http::Method::GET, _) | (&http::Method::HEAD, _) | (_, Some(b"")) | (_, None) => {
None
}
_ => body,
};
let uri = format!("https://app.wasmer.internal{}", req.uri.to_string());

let uri = format!("https://app.wasmer.internal{}", req.uri.to_string());
let url_class = Url::class_info(cx);
let mut url = Object::new(cx);
let arg1 = Value::string(cx, uri.as_str());
let args_array = [arg1.get()];
let args = unsafe { HandleValueArray::from_rooted_slice(&args_array) };
rooted!(in(cx.as_ptr()) let fn_obj = ObjectValue(unsafe { mozjs::jsapi::JS_GetFunctionObject(URL::constructor_fn(cx)) }));
unsafe {
mozjs::jsapi::Construct1(
cx.as_ptr(),
fn_obj.handle().into(),
&args,
url.handle_mut().into(),
)
};

let mut url = Object::new(cx);
let arg1 = Value::string(cx, uri.as_str());
let args_array = [arg1.get()];
let args = unsafe { HandleValueArray::from_rooted_slice(&args_array) };
rooted!(in(cx.as_ptr()) let fn_obj = ObjectValue(unsafe { mozjs::jsapi::JS_GetFunctionObject(url_class.constructor) }));
unsafe {
mozjs::jsapi::Construct1(
cx.as_ptr(),
fn_obj.handle().into(),
&args,
url.handle_mut().into(),
let mut headers = Headers::default();
for h in &req.headers {
headers
.append(
ByteString::from(h.0.to_string().into())
.ok_or(anyhow!("Invalid characters in header name"))?,
ByteString::from(h.1.to_str().map(|x| x.to_string().into())?)
.ok_or(anyhow!("Invalid characters in header value"))?,
)
};
.map_err(|_| anyhow!("Failed to add header to Headers object"))?;
}

let mut headers = Headers::default();
for h in &req.headers {
headers
.append(h.0.to_string(), h.1.to_str().map(|x| x.to_string())?)
.map_err(|_| anyhow!("Failed to add header to Headers object"))?;
}
let request = Heap::boxed(ExecuteRequest::new_object(
cx,
Box::new(ExecuteRequest {
reflector: Default::default(),
url: Heap::boxed((*url).get()),
method: req.method.to_string(),
headers,
body: Some(super::request::Body(body)),
}),
));

let request = Heap::boxed(ExecuteRequest::new_object(
cx,
ExecuteRequest {
url: Heap::boxed((*url).get()),
method: req.method.to_string(),
headers,
body: Some(super::super::request::Body(body)),
},
));
Ok(Self {
reflector: Default::default(),
request,
response: None,
})
}
}

Ok(Self {
request,
response: None,
})
}
#[js_class]
impl FetchEvent {
#[ion(constructor)]
pub fn constructor() -> ion::Result<FetchEvent> {
Err(ion::Error::new(
"Cannot construct this class",
ion::ErrorKind::Type,
))
}

#[ion(get)]
pub fn get_request(&self) -> *mut JSObject {
self.request.get()
}
#[ion(get)]
pub fn get_request(&self) -> *mut JSObject {
self.request.get()
}

#[ion(name = "respondWith")]
pub fn respond_with(&mut self, cx: &Context, response: ion::Value) -> ion::Result<()> {
match self.response {
None => {
if response.handle().is_object() {
let obj = response.handle().to_object();
let rooted = cx.root_object(obj);
if Promise::is_promise(&rooted)
|| runtime::globals::fetch::Response::instance_of(
cx,
&rooted.into(),
None,
)
{
self.response = Some(Heap::boxed(obj));
Ok(())
} else {
Err(ion::Error::new(
"Value must be a promise or an instance of Response",
ion::ErrorKind::Type,
))
}
#[ion(name = "respondWith")]
pub fn respond_with(&mut self, cx: &Context, response: ion::Value) -> ion::Result<()> {
match self.response {
None => {
if response.handle().is_object() {
let obj = response.handle().to_object();
let rooted = cx.root_object(obj);
if Promise::is_promise(&rooted)
|| runtime::globals::fetch::Response::instance_of(cx, &rooted.into(), None)
{
self.response = Some(Heap::boxed(obj));
Ok(())
} else {
Err(ion::Error::new(
"Value must be a promise or an instance of Response",
ion::ErrorKind::Type,
))
}
} else {
Err(ion::Error::new(
"Value must be a promise or an instance of Response",
ion::ErrorKind::Type,
))
}
Some(_) => Err(ion::Error::new(
"Response was already provided once",
ion::ErrorKind::Normal,
)),
}
}

#[ion(name = "waitUntil")]
pub fn wait_until(&self, _promise: ion::Promise) {
// No need to do anything, the runtime will run the promise anyway
Some(_) => Err(ion::Error::new(
"Response was already provided once",
ion::ErrorKind::Normal,
)),
}
}

unsafe impl Traceable for FetchEvent {
unsafe fn trace(&self, trc: *mut JSTracer) {
self.request.trace(trc);
if let Some(response) = self.response.as_ref() {
response.trace(trc);
}
}
#[ion(name = "waitUntil")]
pub fn wait_until(&self, _promise: ion::Promise) {
// No need to do anything, the runtime will run the promise anyway
}
}
Loading

0 comments on commit fee76ad

Please sign in to comment.