add: allow fetch request from worker scope.

This commit is contained in:
Raymond Yeh 2020-11-06 00:15:39 +08:00 committed by Jacob Rothstein
parent 11368ed2fa
commit b03d176160
3 changed files with 82 additions and 47 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ dist/
npm-debug.log*
Cargo.lock
.DS_Store
.vscode/

View File

@ -1,32 +1,32 @@
[package]
name = "http-client"
version = "6.2.0"
license = "MIT OR Apache-2.0"
repository = "https://github.com/http-rs/http-client"
documentation = "https://docs.rs/http-client"
description = "Types and traits for http clients."
keywords = ["http", "service", "client", "futures", "async"]
categories = ["asynchronous", "web-programming", "web-programming::http-client", "web-programming::websocket"]
authors = [
"Yoshua Wuyts <yoshuawuyts@gmail.com>",
"dignifiedquire <me@dignifiedquire.com>",
"Jeremiah Senkpiel <fishrock123@rocketmail.com>"
"Yoshua Wuyts <yoshuawuyts@gmail.com>",
"dignifiedquire <me@dignifiedquire.com>",
"Jeremiah Senkpiel <fishrock123@rocketmail.com>",
]
readme = "README.md"
categories = ["asynchronous", "web-programming", "web-programming::http-client", "web-programming::websocket"]
description = "Types and traits for http clients."
documentation = "https://docs.rs/http-client"
edition = "2018"
keywords = ["http", "service", "client", "futures", "async"]
license = "MIT OR Apache-2.0"
name = "http-client"
readme = "README.md"
repository = "https://github.com/http-rs/http-client"
version = "6.2.0"
[package.metadata.docs.rs]
features = ["docs"]
rustdoc-args = ["--cfg", "feature=\"docs\""]
[features]
curl_client = ["isahc", "async-std"]
default = ["h1_client"]
docs = ["h1_client"]
h1_client = ["async-h1", "async-std", "async-native-tls"]
native_client = ["curl_client", "wasm_client"]
curl_client = ["isahc", "async-std"]
wasm_client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "futures"]
hyper_client = ["hyper", "hyper-tls", "http-types/hyperium_http", "futures-util"]
native_client = ["curl_client", "wasm_client"]
wasm_client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "futures"]
[dependencies]
async-trait = "0.1.37"
@ -34,46 +34,47 @@ http-types = "2.3.0"
log = "0.4.7"
# h1_client
async-h1 = { version = "2.0.0", optional = true }
async-std = { version = "1.6.0", default-features = false, optional = true }
async-native-tls = { version = "0.3.1", optional = true }
async-h1 = {version = "2.0.0", optional = true}
async-native-tls = {version = "0.3.1", optional = true}
async-std = {version = "1.6.0", default-features = false, optional = true}
# hyper_client
hyper = { version = "0.13.6", features = ["tcp"], optional = true }
hyper-tls = { version = "0.4.3", optional = true }
futures-util = { version = "0.3.5", optional = true }
futures-util = {version = "0.3.5", optional = true}
hyper = {version = "0.13.6", features = ["tcp"], optional = true}
hyper-tls = {version = "0.4.3", optional = true}
# curl_client
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
isahc = { version = "0.9", optional = true, default-features = false, features = ["http2"] }
isahc = {version = "0.9", optional = true, default-features = false, features = ["http2"]}
# wasm_client
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = { version = "0.3.25", optional = true }
wasm-bindgen = { version = "0.2.48", optional = true }
wasm-bindgen-futures = { version = "0.4.5", optional = true }
futures = { version = "0.3.1", optional = true }
futures = {version = "0.3.1", optional = true}
js-sys = {version = "0.3.25", optional = true}
wasm-bindgen = {version = "0.2.48", optional = true}
wasm-bindgen-futures = {version = "0.4.5", optional = true}
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.25"
optional = true
features = [
"AbortSignal",
"Headers",
"ObserverCallback",
"ReferrerPolicy",
"Request",
"RequestCache",
"RequestCredentials",
"RequestInit",
"RequestMode",
"RequestRedirect",
"Response",
"Window",
"AbortSignal",
"Headers",
"ObserverCallback",
"ReferrerPolicy",
"Request",
"RequestCache",
"RequestCredentials",
"RequestInit",
"RequestMode",
"RequestRedirect",
"Response",
"Window",
"WorkerGlobalScope",
]
optional = true
version = "0.3.25"
[dev-dependencies]
async-std = { version = "1.6.0", features = ["unstable", "attributes"] }
async-std = {version = "1.6.0", features = ["unstable", "attributes"]}
portpicker = "0.1.0"
tide = { version = "0.13.0" }
tokio = { version = "0.2.21", features = ["macros"] }
tide = {version = "0.13.0"}
tokio = {version = "0.2.21", features = ["macros"]}

View File

@ -75,9 +75,9 @@ impl Future for InnerFuture {
mod fetch {
use js_sys::{Array, ArrayBuffer, Reflect, Uint8Array};
use wasm_bindgen::JsCast;
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_futures::JsFuture;
use web_sys::{window, RequestInit};
use web_sys::{RequestInit, Window, WorkerGlobalScope};
use std::iter::{IntoIterator, Iterator};
use std::pin::Pin;
@ -86,6 +86,36 @@ mod fetch {
use crate::Error;
enum WindowOrWorker {
Window(Window),
Worker(WorkerGlobalScope),
}
impl WindowOrWorker {
fn new() -> Self {
#[wasm_bindgen]
extern "C" {
type Global;
#[wasm_bindgen(method, getter, js_name = Window)]
fn window(this: &Global) -> JsValue;
#[wasm_bindgen(method, getter, js_name = WorkerGlobalScope)]
fn worker(this: &Global) -> JsValue;
}
let global: Global = js_sys::global().unchecked_into();
if !global.window().is_undefined() {
Self::Window(global.unchecked_into())
} else if !global.worker().is_undefined() {
Self::Worker(global.unchecked_into())
} else {
panic!("Only supported in a browser or web worker");
}
}
}
/// Create a new fetch request.
/// An HTTP Fetch Request.
@ -152,8 +182,11 @@ mod fetch {
// TODO(yoshuawuyts): turn this into a `Future` impl on `Request` instead.
pub(crate) async fn send(self) -> Result<Response, Error> {
// Send the request.
let window = window().expect("A global window object could not be found");
let promise = window.fetch_with_request(&self.request);
let scope = WindowOrWorker::new();
let promise = match scope {
WindowOrWorker::Window(window) => window.fetch_with_request(&self.request),
WindowOrWorker::Worker(worker) => worker.fetch_with_request(&self.request),
};
let resp = JsFuture::from(promise)
.await
.map_err(|e| Error::from_str(StatusCode::BadRequest, format!("{:?}", e)))?;