Skip to content

Commit b03d176

Browse files
extraymondjbr
authored andcommitted
add: allow fetch request from worker scope.
1 parent 11368ed commit b03d176

File tree

3 files changed

+81
-46
lines changed

3 files changed

+81
-46
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ dist/
55
npm-debug.log*
66
Cargo.lock
77
.DS_Store
8+
.vscode/

Cargo.toml

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,80 @@
11
[package]
2-
name = "http-client"
3-
version = "6.2.0"
4-
license = "MIT OR Apache-2.0"
5-
repository = "https://github.com/http-rs/http-client"
6-
documentation = "https://docs.rs/http-client"
7-
description = "Types and traits for http clients."
8-
keywords = ["http", "service", "client", "futures", "async"]
9-
categories = ["asynchronous", "web-programming", "web-programming::http-client", "web-programming::websocket"]
102
authors = [
11-
"Yoshua Wuyts <[email protected]>",
12-
"dignifiedquire <[email protected]>",
13-
"Jeremiah Senkpiel <[email protected]>"
3+
"Yoshua Wuyts <[email protected]>",
4+
"dignifiedquire <[email protected]>",
5+
"Jeremiah Senkpiel <[email protected]>",
146
]
15-
readme = "README.md"
7+
categories = ["asynchronous", "web-programming", "web-programming::http-client", "web-programming::websocket"]
8+
description = "Types and traits for http clients."
9+
documentation = "https://docs.rs/http-client"
1610
edition = "2018"
11+
keywords = ["http", "service", "client", "futures", "async"]
12+
license = "MIT OR Apache-2.0"
13+
name = "http-client"
14+
readme = "README.md"
15+
repository = "https://github.com/http-rs/http-client"
16+
version = "6.2.0"
1717

1818
[package.metadata.docs.rs]
1919
features = ["docs"]
2020
rustdoc-args = ["--cfg", "feature=\"docs\""]
2121

2222
[features]
23+
curl_client = ["isahc", "async-std"]
2324
default = ["h1_client"]
2425
docs = ["h1_client"]
2526
h1_client = ["async-h1", "async-std", "async-native-tls"]
27+
hyper_client = ["hyper", "hyper-tls", "http-types/hyperium_http", "futures-util"]
2628
native_client = ["curl_client", "wasm_client"]
27-
curl_client = ["isahc", "async-std"]
2829
wasm_client = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "futures"]
29-
hyper_client = ["hyper", "hyper-tls", "http-types/hyperium_http", "futures-util"]
3030

3131
[dependencies]
3232
async-trait = "0.1.37"
3333
http-types = "2.3.0"
3434
log = "0.4.7"
3535

3636
# h1_client
37-
async-h1 = { version = "2.0.0", optional = true }
38-
async-std = { version = "1.6.0", default-features = false, optional = true }
39-
async-native-tls = { version = "0.3.1", optional = true }
37+
async-h1 = {version = "2.0.0", optional = true}
38+
async-native-tls = {version = "0.3.1", optional = true}
39+
async-std = {version = "1.6.0", default-features = false, optional = true}
4040

4141
# hyper_client
42-
hyper = { version = "0.13.6", features = ["tcp"], optional = true }
43-
hyper-tls = { version = "0.4.3", optional = true }
44-
futures-util = { version = "0.3.5", optional = true }
42+
futures-util = {version = "0.3.5", optional = true}
43+
hyper = {version = "0.13.6", features = ["tcp"], optional = true}
44+
hyper-tls = {version = "0.4.3", optional = true}
4545

4646
# curl_client
4747
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
48-
isahc = { version = "0.9", optional = true, default-features = false, features = ["http2"] }
48+
isahc = {version = "0.9", optional = true, default-features = false, features = ["http2"]}
4949

5050
# wasm_client
5151
[target.'cfg(target_arch = "wasm32")'.dependencies]
52-
js-sys = { version = "0.3.25", optional = true }
53-
wasm-bindgen = { version = "0.2.48", optional = true }
54-
wasm-bindgen-futures = { version = "0.4.5", optional = true }
55-
futures = { version = "0.3.1", optional = true }
52+
futures = {version = "0.3.1", optional = true}
53+
js-sys = {version = "0.3.25", optional = true}
54+
wasm-bindgen = {version = "0.2.48", optional = true}
55+
wasm-bindgen-futures = {version = "0.4.5", optional = true}
5656

5757
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
58-
version = "0.3.25"
59-
optional = true
6058
features = [
61-
"AbortSignal",
62-
"Headers",
63-
"ObserverCallback",
64-
"ReferrerPolicy",
65-
"Request",
66-
"RequestCache",
67-
"RequestCredentials",
68-
"RequestInit",
69-
"RequestMode",
70-
"RequestRedirect",
71-
"Response",
72-
"Window",
59+
"AbortSignal",
60+
"Headers",
61+
"ObserverCallback",
62+
"ReferrerPolicy",
63+
"Request",
64+
"RequestCache",
65+
"RequestCredentials",
66+
"RequestInit",
67+
"RequestMode",
68+
"RequestRedirect",
69+
"Response",
70+
"Window",
71+
"WorkerGlobalScope",
7372
]
73+
optional = true
74+
version = "0.3.25"
7475

7576
[dev-dependencies]
76-
async-std = { version = "1.6.0", features = ["unstable", "attributes"] }
77+
async-std = {version = "1.6.0", features = ["unstable", "attributes"]}
7778
portpicker = "0.1.0"
78-
tide = { version = "0.13.0" }
79-
tokio = { version = "0.2.21", features = ["macros"] }
79+
tide = {version = "0.13.0"}
80+
tokio = {version = "0.2.21", features = ["macros"]}

src/wasm.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ impl Future for InnerFuture {
7575

7676
mod fetch {
7777
use js_sys::{Array, ArrayBuffer, Reflect, Uint8Array};
78-
use wasm_bindgen::JsCast;
78+
use wasm_bindgen::{prelude::*, JsCast};
7979
use wasm_bindgen_futures::JsFuture;
80-
use web_sys::{window, RequestInit};
80+
use web_sys::{RequestInit, Window, WorkerGlobalScope};
8181

8282
use std::iter::{IntoIterator, Iterator};
8383
use std::pin::Pin;
@@ -86,6 +86,36 @@ mod fetch {
8686

8787
use crate::Error;
8888

89+
enum WindowOrWorker {
90+
Window(Window),
91+
Worker(WorkerGlobalScope),
92+
}
93+
94+
impl WindowOrWorker {
95+
fn new() -> Self {
96+
#[wasm_bindgen]
97+
extern "C" {
98+
type Global;
99+
100+
#[wasm_bindgen(method, getter, js_name = Window)]
101+
fn window(this: &Global) -> JsValue;
102+
103+
#[wasm_bindgen(method, getter, js_name = WorkerGlobalScope)]
104+
fn worker(this: &Global) -> JsValue;
105+
}
106+
107+
let global: Global = js_sys::global().unchecked_into();
108+
109+
if !global.window().is_undefined() {
110+
Self::Window(global.unchecked_into())
111+
} else if !global.worker().is_undefined() {
112+
Self::Worker(global.unchecked_into())
113+
} else {
114+
panic!("Only supported in a browser or web worker");
115+
}
116+
}
117+
}
118+
89119
/// Create a new fetch request.
90120
91121
/// An HTTP Fetch Request.
@@ -152,8 +182,11 @@ mod fetch {
152182
// TODO(yoshuawuyts): turn this into a `Future` impl on `Request` instead.
153183
pub(crate) async fn send(self) -> Result<Response, Error> {
154184
// Send the request.
155-
let window = window().expect("A global window object could not be found");
156-
let promise = window.fetch_with_request(&self.request);
185+
let scope = WindowOrWorker::new();
186+
let promise = match scope {
187+
WindowOrWorker::Window(window) => window.fetch_with_request(&self.request),
188+
WindowOrWorker::Worker(worker) => worker.fetch_with_request(&self.request),
189+
};
157190
let resp = JsFuture::from(promise)
158191
.await
159192
.map_err(|e| Error::from_str(StatusCode::BadRequest, format!("{:?}", e)))?;

0 commit comments

Comments
 (0)