Skip to content

Commit 67ab6be

Browse files
authored
fix(ext/fetch): read file urls via vfs (#31814)
1 parent 466ab12 commit 67ab6be

File tree

4 files changed

+37
-53
lines changed

4 files changed

+37
-53
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/fetch/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ data-url.workspace = true
2020
deno_core.workspace = true
2121
deno_error.workspace = true
2222
deno_fs.workspace = true
23+
deno_io.workspace = true
2324
deno_path_util.workspace = true
2425
deno_permissions.workspace = true
2526
deno_tls.workspace = true
@@ -41,7 +42,6 @@ thiserror.workspace = true
4142
tokio.workspace = true
4243
tokio-rustls.workspace = true
4344
tokio-socks.workspace = true
44-
tokio-util = { workspace = true, features = ["io"] }
4545
tower.workspace = true
4646
tower-http.workspace = true
4747
tower-service.workspace = true

ext/fetch/fs_fetch_handler.rs

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,21 @@ use std::rc::Rc;
66
use deno_core::CancelFuture;
77
use deno_core::OpState;
88
use deno_core::futures::FutureExt;
9-
use deno_core::futures::TryFutureExt;
10-
use deno_core::futures::TryStreamExt;
119
use deno_core::url::Url;
12-
use deno_error::JsErrorBox;
10+
use deno_fs::FileSystemRc;
1311
use deno_fs::OpenOptions;
14-
use deno_fs::open_options_for_checked_path;
12+
use deno_io::fs::FileResource;
13+
use deno_permissions::CheckedPath;
1514
use deno_permissions::OpenAccessKind;
1615
use deno_permissions::PermissionsContainer;
17-
use http::StatusCode;
18-
use http_body_util::BodyExt;
19-
use tokio_util::io::ReaderStream;
16+
use http_body_util::combinators::BoxBody;
2017

2118
use crate::CancelHandle;
2219
use crate::CancelableResponseFuture;
2320
use crate::FetchHandler;
21+
use crate::ResourceToBodyAdapter;
2422

25-
/// An implementation which tries to read file URLs from the file system via
26-
/// tokio::fs.
23+
/// An implementation which tries to read file URLs via `deno_fs::FileSystem`.
2724
#[derive(Clone)]
2825
pub struct FsFetchHandler;
2926

@@ -34,52 +31,28 @@ impl FetchHandler for FsFetchHandler {
3431
url: &Url,
3532
) -> (CancelableResponseFuture, Option<Rc<CancelHandle>>) {
3633
let cancel_handle = CancelHandle::new_rc();
37-
let path = match url.to_file_path() {
38-
Ok(path) => path,
39-
Err(_) => {
40-
let fut = async move { Err::<_, _>(()) };
41-
return (
42-
fut
43-
.map_err(move |_| super::FetchError::NetworkError)
44-
.or_cancel(&cancel_handle)
45-
.boxed_local(),
46-
Some(cancel_handle),
47-
);
48-
}
49-
};
50-
let path_and_opts_result = {
51-
state
52-
.borrow::<PermissionsContainer>()
53-
.check_open(Cow::Owned(path), OpenAccessKind::Read, Some("fetch()"))
54-
.map(|path| {
55-
(
56-
open_options_for_checked_path(
57-
OpenOptions {
58-
read: true,
59-
..Default::default()
60-
},
61-
&path,
62-
),
63-
path.into_owned(),
64-
)
65-
})
34+
let Ok(path) = url.to_file_path() else {
35+
return (
36+
async move { Err(super::FetchError::NetworkError) }
37+
.or_cancel(&cancel_handle)
38+
.boxed_local(),
39+
Some(cancel_handle),
40+
);
6641
};
42+
let fs = state.borrow::<FileSystemRc>().clone();
43+
let path = state
44+
.borrow::<PermissionsContainer>()
45+
.check_open(Cow::Owned(path), OpenAccessKind::Read, Some("fetch()"))
46+
.map(CheckedPath::into_owned);
6747
let response_fut = async move {
68-
let (opts, path) = path_and_opts_result?;
69-
let file = tokio::fs::OpenOptions::from(opts)
70-
.open(path)
48+
let file = fs
49+
.open_async(path?, OpenOptions::read())
7150
.await
7251
.map_err(|_| super::FetchError::NetworkError)?;
73-
let stream = ReaderStream::new(file)
74-
.map_ok(hyper::body::Frame::data)
75-
.map_err(JsErrorBox::from_err);
76-
77-
let body = http_body_util::StreamBody::new(stream).boxed();
78-
let response = http::Response::builder()
79-
.status(StatusCode::OK)
80-
.body(body)
81-
.map_err(move |_| super::FetchError::NetworkError)?;
82-
Ok::<_, _>(response)
52+
let resource = Rc::new(FileResource::new(file, "".to_owned()));
53+
let body = BoxBody::new(ResourceToBodyAdapter::new(resource));
54+
let response = http::Response::new(body);
55+
Ok(response)
8356
}
8457
.or_cancel(&cancel_handle)
8558
.boxed_local();

tests/specs/compile/include/buffered_reads/main.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,14 @@
5555
}
5656
}
5757
}
58+
59+
// large amount of data via fetch
60+
{
61+
const res = await fetch(import.meta.resolve("./data/2.dat"));
62+
const bytes = await res.bytes();
63+
for (let i = 0; i < bytes.length; i++) {
64+
if (bytes[i] !== i % 256) {
65+
throw new Error("Unexpected data.");
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)