diff options
author | Luca Casonato <lucacasonato@yahoo.com> | 2021-04-11 14:09:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-11 14:09:10 +0200 |
commit | e7f18d64686e2b94fe9ecba8106ca2ff5bdfe7f3 (patch) | |
tree | 4faeba935b1cd64e627b4dd7ba44e6d6b0c84be2 /op_crates | |
parent | f5a9474952f459a5095e0aae68e0984fdd84b210 (diff) |
feat: blob URL support in fetch (#10120)
This commit adds blob URL support in `fetch`. Tested via WPT. This is
the first op_crate to have a rust dependency on a different op_crate.
Diffstat (limited to 'op_crates')
-rw-r--r-- | op_crates/fetch/Cargo.toml | 1 | ||||
-rw-r--r-- | op_crates/fetch/lib.rs | 31 | ||||
-rw-r--r-- | op_crates/file/lib.rs | 5 |
3 files changed, 34 insertions, 3 deletions
diff --git a/op_crates/fetch/Cargo.toml b/op_crates/fetch/Cargo.toml index b61a1ffa3..1a2baa314 100644 --- a/op_crates/fetch/Cargo.toml +++ b/op_crates/fetch/Cargo.toml @@ -17,6 +17,7 @@ path = "lib.rs" bytes = "1.0.1" data-url = "0.1.0" deno_core = { version = "0.83.0", path = "../../core" } +deno_file = { version = "0.1.0", path = "../file" } http = "0.2.3" reqwest = { version = "0.11.2", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli"] } serde = { version = "1.0.125", features = ["derive"] } diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs index b3e258e5e..69c0c46ad 100644 --- a/op_crates/fetch/lib.rs +++ b/op_crates/fetch/lib.rs @@ -2,7 +2,6 @@ #![deny(warnings)] -use data_url::DataUrl; use deno_core::error::bad_resource_id; use deno_core::error::generic_error; use deno_core::error::null_opbuf; @@ -23,6 +22,8 @@ use deno_core::Resource; use deno_core::ResourceId; use deno_core::ZeroCopyBuf; +use data_url::DataUrl; +use deno_file::BlobUrlStore; use reqwest::header::HeaderMap; use reqwest::header::HeaderName; use reqwest::header::HeaderValue; @@ -225,6 +226,34 @@ where (request_rid, None) } + "blob" => { + let blob_url_storage = + state.try_borrow::<BlobUrlStore>().ok_or_else(|| { + type_error("Blob URLs are not supported in this context.") + })?; + + let blob = blob_url_storage + .get(url)? + .ok_or_else(|| type_error("Blob for the given URL not found."))?; + + if method != "GET" { + return Err(type_error("Blob URL fetch only supports GET method.")); + } + + let response = http::Response::builder() + .status(http::StatusCode::OK) + .header(http::header::CONTENT_LENGTH, blob.data.len()) + .header(http::header::CONTENT_TYPE, blob.media_type) + .body(reqwest::Body::from(blob.data))?; + + let fut = async move { Ok(Response::from(response)) }; + + let request_rid = state + .resource_table + .add(FetchRequestResource(Box::pin(fut))); + + (request_rid, None) + } _ => return Err(type_error(format!("scheme '{}' not supported", scheme))), }; diff --git a/op_crates/file/lib.rs b/op_crates/file/lib.rs index e8c2cde1d..ea519046f 100644 --- a/op_crates/file/lib.rs +++ b/op_crates/file/lib.rs @@ -24,9 +24,10 @@ pub struct Location(pub Url); pub struct BlobUrlStore(Arc<Mutex<HashMap<Url, Blob>>>); impl BlobUrlStore { - pub fn get(&self, url: &ModuleSpecifier) -> Result<Option<Blob>, AnyError> { + pub fn get(&self, mut url: Url) -> Result<Option<Blob>, AnyError> { let blob_store = self.0.lock().unwrap(); - Ok(blob_store.get(url).cloned()) + url.set_fragment(None); + Ok(blob_store.get(&url).cloned()) } pub fn insert(&self, blob: Blob, maybe_location: Option<Url>) -> Url { |