summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorSean McArthur <sean@seanmonstar.com>2024-07-12 15:51:37 -0700
committerGitHub <noreply@github.com>2024-07-13 00:51:37 +0200
commitf6fd6619e708a515831f707438368d81b0c9aa56 (patch)
tree9c65c76613330a22c5a88c017752a9aa7e0951ac /runtime
parent2fca4f11fe22a5d49326b6bf5b3ef039403eb0df (diff)
refactor(fetch): reimplement fetch with hyper instead of reqwest (#24237)
This commit re-implements `ext/fetch` and all dependent crates using `hyper` and `hyper-util`, instead of `reqwest`. The reasoning is that we want to have greater control and access to low level `hyper` APIs when implementing `fetch` API as well as `node:http` module. --------- Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
Diffstat (limited to 'runtime')
-rw-r--r--runtime/errors.rs47
-rw-r--r--runtime/ops/web_worker/sync_fetch.rs26
2 files changed, 38 insertions, 35 deletions
diff --git a/runtime/errors.rs b/runtime/errors.rs
index 7f2e49250..694402773 100644
--- a/runtime/errors.rs
+++ b/runtime/errors.rs
@@ -13,7 +13,6 @@ use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::url;
use deno_core::ModuleResolutionError;
-use deno_fetch::reqwest;
use std::env;
use std::error::Error;
use std::io;
@@ -101,27 +100,6 @@ fn get_regex_error_class(error: &regex::Error) -> &'static str {
}
}
-fn get_request_error_class(error: &reqwest::Error) -> &'static str {
- error
- .source()
- .and_then(|inner_err| {
- (inner_err
- .downcast_ref::<io::Error>()
- .map(get_io_error_class))
- .or_else(|| {
- inner_err
- .downcast_ref::<serde_json::error::Error>()
- .map(get_serde_json_error_class)
- })
- .or_else(|| {
- inner_err
- .downcast_ref::<url::ParseError>()
- .map(get_url_parse_error_class)
- })
- })
- .unwrap_or("Http")
-}
-
fn get_serde_json_error_class(
error: &serde_json::error::Error,
) -> &'static str {
@@ -142,7 +120,17 @@ fn get_url_parse_error_class(_error: &url::ParseError) -> &'static str {
"URIError"
}
-fn get_hyper_error_class(_error: &hyper_v014::Error) -> &'static str {
+fn get_hyper_error_class(_error: &hyper::Error) -> &'static str {
+ "Http"
+}
+
+fn get_hyper_util_error_class(
+ _error: &hyper_util::client::legacy::Error,
+) -> &'static str {
+ "Http"
+}
+
+fn get_hyper_v014_error_class(_error: &hyper_v014::Error) -> &'static str {
"Http"
}
@@ -175,13 +163,18 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
e.downcast_ref::<dlopen2::Error>()
.map(get_dlopen_error_class)
})
+ .or_else(|| e.downcast_ref::<hyper::Error>().map(get_hyper_error_class))
+ .or_else(|| {
+ e.downcast_ref::<hyper_util::client::legacy::Error>()
+ .map(get_hyper_util_error_class)
+ })
.or_else(|| {
e.downcast_ref::<hyper_v014::Error>()
- .map(get_hyper_error_class)
+ .map(get_hyper_v014_error_class)
})
.or_else(|| {
e.downcast_ref::<Arc<hyper_v014::Error>>()
- .map(|e| get_hyper_error_class(e))
+ .map(|e| get_hyper_v014_error_class(e))
})
.or_else(|| {
e.downcast_ref::<deno_core::Canceled>().map(|e| {
@@ -202,10 +195,6 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
e.downcast_ref::<notify::Error>()
.map(get_notify_error_class)
})
- .or_else(|| {
- e.downcast_ref::<reqwest::Error>()
- .map(get_request_error_class)
- })
.or_else(|| e.downcast_ref::<regex::Error>().map(get_regex_error_class))
.or_else(|| {
e.downcast_ref::<serde_json::error::Error>()
diff --git a/runtime/ops/web_worker/sync_fetch.rs b/runtime/ops/web_worker/sync_fetch.rs
index 37286ca62..cdb151a86 100644
--- a/runtime/ops/web_worker/sync_fetch.rs
+++ b/runtime/ops/web_worker/sync_fetch.rs
@@ -13,6 +13,7 @@ use deno_core::OpState;
use deno_fetch::data_url::DataUrl;
use deno_web::BlobStore;
use deno_websocket::DomExceptionNetworkError;
+use http_body_util::BodyExt;
use hyper::body::Bytes;
use serde::Deserialize;
use serde::Serialize;
@@ -78,10 +79,23 @@ pub fn op_worker_sync_fetch(
let (body, mime_type, res_url) = match script_url.scheme() {
"http" | "https" => {
- let resp =
- client.get(script_url).send().await?.error_for_status()?;
-
- let res_url = resp.url().to_string();
+ let mut req = http::Request::new(
+ http_body_util::Empty::new()
+ .map_err(|never| match never {})
+ .boxed(),
+ );
+ *req.uri_mut() = script_url.as_str().parse()?;
+
+ let resp = client.send(req).await?;
+
+ if resp.status().is_client_error()
+ || resp.status().is_server_error()
+ {
+ return Err(type_error(format!(
+ "http status error: {}",
+ resp.status()
+ )));
+ }
// TODO(andreubotella) Properly run fetch's "extract a MIME type".
let mime_type = resp
@@ -93,9 +107,9 @@ pub fn op_worker_sync_fetch(
// Always check the MIME type with HTTP(S).
loose_mime_checks = false;
- let body = resp.bytes().await?;
+ let body = resp.collect().await?.to_bytes();
- (body, mime_type, res_url)
+ (body, mime_type, script)
}
"data" => {
let data_url = DataUrl::process(&script)