summaryrefslogtreecommitdiff
path: root/op_crates/fetch/lib.rs
diff options
context:
space:
mode:
authorLuca Casonato <lucacasonato@yahoo.com>2021-04-10 23:38:15 +0200
committerGitHub <noreply@github.com>2021-04-10 23:38:15 +0200
commit3ab94983b4100d5ae3c1d99c8b6a580510cd83f5 (patch)
tree1849d6873ec09ff8812b23ca36db9077022cf2e9 /op_crates/fetch/lib.rs
parent8d55d8b6be8731d37ccf6a29127b3a91a8319d0b (diff)
feat: data URL support in fetch (#10054)
This commit adds data URL support in `fetch`. Tested via wpt.
Diffstat (limited to 'op_crates/fetch/lib.rs')
-rw-r--r--op_crates/fetch/lib.rs99
1 files changed, 62 insertions, 37 deletions
diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs
index 32a5a0140..b3e258e5e 100644
--- a/op_crates/fetch/lib.rs
+++ b/op_crates/fetch/lib.rs
@@ -2,6 +2,7 @@
#![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;
@@ -157,51 +158,75 @@ where
// Check scheme before asking for net permission
let scheme = url.scheme();
- if scheme != "http" && scheme != "https" {
- return Err(type_error(format!("scheme '{}' not supported", scheme)));
- }
-
- let permissions = state.borrow::<FP>();
- permissions.check_net_url(&url)?;
+ let (request_rid, request_body_rid) = match scheme {
+ "http" | "https" => {
+ let permissions = state.borrow::<FP>();
+ permissions.check_net_url(&url)?;
+
+ let mut request = client.request(method, url);
+
+ let request_body_rid = if args.has_body {
+ match data {
+ None => {
+ // If no body is passed, we return a writer for streaming the body.
+ let (tx, rx) = mpsc::channel::<std::io::Result<Vec<u8>>>(1);
+ request = request.body(Body::wrap_stream(ReceiverStream::new(rx)));
+
+ let request_body_rid =
+ state.resource_table.add(FetchRequestBodyResource {
+ body: AsyncRefCell::new(tx),
+ cancel: CancelHandle::default(),
+ });
+
+ Some(request_body_rid)
+ }
+ Some(data) => {
+ // If a body is passed, we use it, and don't return a body for streaming.
+ request = request.body(Vec::from(&*data));
+ None
+ }
+ }
+ } else {
+ None
+ };
- let mut request = client.request(method, url);
+ for (key, value) in args.headers {
+ let name = HeaderName::from_bytes(key.as_bytes()).unwrap();
+ let v = HeaderValue::from_str(&value).unwrap();
+ request = request.header(name, v);
+ }
- let request_body_rid = if args.has_body {
- match data {
- None => {
- // If no body is passed, we return a writer for streaming the body.
- let (tx, rx) = mpsc::channel::<std::io::Result<Vec<u8>>>(1);
- request = request.body(Body::wrap_stream(ReceiverStream::new(rx)));
+ let fut = request.send();
- let request_body_rid =
- state.resource_table.add(FetchRequestBodyResource {
- body: AsyncRefCell::new(tx),
- cancel: CancelHandle::default(),
- });
+ let request_rid = state
+ .resource_table
+ .add(FetchRequestResource(Box::pin(fut)));
- Some(request_body_rid)
- }
- Some(data) => {
- // If a body is passed, we use it, and don't return a body for streaming.
- request = request.body(Vec::from(&*data));
- None
- }
+ (request_rid, request_body_rid)
}
- } else {
- None
- };
+ "data" => {
+ let data_url = DataUrl::process(url.as_str())
+ .map_err(|e| type_error(format!("{:?}", e)))?;
- for (key, value) in args.headers {
- let name = HeaderName::from_bytes(key.as_bytes()).unwrap();
- let v = HeaderValue::from_str(&value).unwrap();
- request = request.header(name, v);
- }
+ let (body, _) = data_url
+ .decode_to_vec()
+ .map_err(|e| type_error(format!("{:?}", e)))?;
- let fut = request.send();
+ let response = http::Response::builder()
+ .status(http::StatusCode::OK)
+ .header(http::header::CONTENT_TYPE, data_url.mime_type().to_string())
+ .body(reqwest::Body::from(body))?;
- let request_rid = state
- .resource_table
- .add(FetchRequestResource(Box::pin(fut)));
+ 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))),
+ };
Ok(FetchReturn {
request_rid,