From b8f969fed09bc7a22458205f8f6e7c91429c335e Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Fri, 4 Nov 2022 15:33:25 +0100 Subject: [PATCH] Gloo net fetch in worker (#253) * Enable gloo-net to use fetch in a worker * Fix(gloo-net): Add missing web-sys feature DedicatedWorkerGlobalScope * feat(gloo-net): Use WorkerGlobalScope to support usage in web extensions with manifest V3 Co-authored-by: Chris Joel <0xcda7a@gmail.com> --- crates/net/Cargo.toml | 1 + crates/net/src/error.rs | 3 +++ crates/net/src/http/mod.rs | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/net/Cargo.toml b/crates/net/Cargo.toml index 21c1dad6..b7841def 100644 --- a/crates/net/Cargo.toml +++ b/crates/net/Cargo.toml @@ -78,6 +78,7 @@ http = [ 'web-sys/ReadableStream', 'web-sys/Blob', 'web-sys/FormData', + 'web-sys/WorkerGlobalScope', ] # Enables the EventSource API eventsource = [ diff --git a/crates/net/src/error.rs b/crates/net/src/error.rs index cbb09ff6..fc06c36d 100644 --- a/crates/net/src/error.rs +++ b/crates/net/src/error.rs @@ -16,6 +16,9 @@ pub enum Error { #[from] serde_json::Error, ), + /// Error returned by this crate + #[error("{0}")] + GlooError(String), } #[cfg(any(feature = "http", feature = "websocket", feature = "eventsource"))] diff --git a/crates/net/src/http/mod.rs b/crates/net/src/http/mod.rs index 1c35f8c1..92ab4b3d 100644 --- a/crates/net/src/http/mod.rs +++ b/crates/net/src/http/mod.rs @@ -17,6 +17,7 @@ mod headers; mod query; use crate::{js_to_error, Error}; +use js_sys::Reflect; use js_sys::{ArrayBuffer, Uint8Array}; use std::fmt; use wasm_bindgen::prelude::*; @@ -252,7 +253,23 @@ impl Request { let request = web_sys::Request::new_with_str_and_init(&url, &self.options).map_err(js_to_error)?; - let promise = gloo_utils::window().fetch_with_request(&request); + let global = js_sys::global(); + let maybe_window = + Reflect::get(&global, &JsValue::from_str("Window")).map_err(js_to_error)?; + let promise = if !maybe_window.is_undefined() { + let window = global.dyn_into::().unwrap(); + window.fetch_with_request(&request) + } else { + let maybe_worker = Reflect::get(&global, &JsValue::from_str("WorkerGlobalScope")) + .map_err(js_to_error)?; + if !maybe_worker.is_undefined() { + let worker = global.dyn_into::().unwrap(); + worker.fetch_with_request(&request) + } else { + panic!("Unsupported JavaScript global context"); + } + }; + let response = JsFuture::from(promise).await.map_err(js_to_error)?; match response.dyn_into::() { Ok(response) => Ok(Response {