summaryrefslogtreecommitdiff
path: root/cli/ops/fetch.rs
diff options
context:
space:
mode:
authorLuca Casonato <lucacasonato@yahoo.com>2020-08-05 20:44:03 +0200
committerGitHub <noreply@github.com>2020-08-05 20:44:03 +0200
commitce7808baf092e130ba1c5f073544072c5db958e7 (patch)
treecc8f9a167973aed549194c4ac5c8291a82c17cdf /cli/ops/fetch.rs
parent91ed614aa80f5a08669be3fe5031a95e6e75f194 (diff)
feat(cli): custom http client for fetch (#6918)
Diffstat (limited to 'cli/ops/fetch.rs')
-rw-r--r--cli/ops/fetch.rs60
1 files changed, 57 insertions, 3 deletions
diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs
index 869c7c5b8..539316260 100644
--- a/cli/ops/fetch.rs
+++ b/cli/ops/fetch.rs
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::{StreamResource, StreamResourceHolder};
-use crate::http_util::HttpBody;
+use crate::http_util::{create_http_client, HttpBody};
use crate::op_error::OpError;
use crate::state::State;
use deno_core::CoreIsolate;
@@ -11,17 +11,25 @@ use futures::future::FutureExt;
use http::header::HeaderName;
use http::header::HeaderValue;
use http::Method;
+use reqwest::Client;
use std::convert::From;
+use std::path::PathBuf;
pub fn init(i: &mut CoreIsolate, s: &State) {
i.register_op("op_fetch", s.stateful_json_op2(op_fetch));
+ i.register_op(
+ "op_create_http_client",
+ s.stateful_json_op2(op_create_http_client),
+ );
}
#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
struct FetchArgs {
method: Option<String>,
url: String,
headers: Vec<(String, String)>,
+ client_rid: Option<u32>,
}
pub fn op_fetch(
@@ -32,8 +40,17 @@ pub fn op_fetch(
) -> Result<JsonOp, OpError> {
let args: FetchArgs = serde_json::from_value(args)?;
let url = args.url;
-
- let client = &state.borrow().http_client;
+ let resource_table_ = isolate_state.resource_table.borrow();
+ let state_ = state.borrow();
+
+ let client = if let Some(rid) = args.client_rid {
+ let r = resource_table_
+ .get::<HttpClientResource>(rid)
+ .ok_or_else(OpError::bad_resource_id)?;
+ &r.client
+ } else {
+ &state_.http_client
+ };
let method = match args.method {
Some(method_str) => Method::from_bytes(method_str.as_bytes())
@@ -100,3 +117,40 @@ pub fn op_fetch(
Ok(JsonOp::Async(future.boxed_local()))
}
+
+struct HttpClientResource {
+ client: Client,
+}
+
+impl HttpClientResource {
+ fn new(client: Client) -> Self {
+ Self { client }
+ }
+}
+
+#[derive(Deserialize, Default, Debug)]
+#[serde(rename_all = "camelCase")]
+#[serde(default)]
+struct CreateHttpClientOptions {
+ ca_file: Option<String>,
+}
+
+fn op_create_http_client(
+ isolate_state: &mut CoreIsolateState,
+ state: &State,
+ args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result<JsonOp, OpError> {
+ let args: CreateHttpClientOptions = serde_json::from_value(args)?;
+ let mut resource_table = isolate_state.resource_table.borrow_mut();
+
+ if let Some(ca_file) = args.ca_file.clone() {
+ state.check_read(&PathBuf::from(ca_file))?;
+ }
+
+ let client = create_http_client(args.ca_file).unwrap();
+
+ let rid =
+ resource_table.add("httpClient", Box::new(HttpClientResource::new(client)));
+ Ok(JsonOp::Sync(json!(rid)))
+}