summaryrefslogtreecommitdiff
path: root/cli/ops/fetch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/ops/fetch.rs')
-rw-r--r--cli/ops/fetch.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs
new file mode 100644
index 000000000..f69065f1d
--- /dev/null
+++ b/cli/ops/fetch.rs
@@ -0,0 +1,73 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use super::dispatch_json::{Deserialize, JsonOp, Value};
+use crate::http_util::get_client;
+use crate::resources;
+use crate::state::ThreadSafeState;
+use deno::*;
+use http::header::HeaderName;
+use http::header::HeaderValue;
+use http::Method;
+use hyper;
+use hyper::rt::Future;
+use std;
+use std::convert::From;
+
+#[derive(Deserialize)]
+struct FetchArgs {
+ method: Option<String>,
+ url: String,
+ headers: Vec<(String, String)>,
+}
+
+pub fn op_fetch(
+ state: &ThreadSafeState,
+ args: Value,
+ data: Option<PinnedBuf>,
+) -> Result<JsonOp, ErrBox> {
+ let args: FetchArgs = serde_json::from_value(args)?;
+ let url = args.url;
+
+ let client = get_client();
+
+ let method = match args.method {
+ Some(method_str) => Method::from_bytes(method_str.as_bytes())?,
+ None => Method::GET,
+ };
+
+ let url_ = url::Url::parse(&url).map_err(ErrBox::from)?;
+ state.check_net_url(&url_)?;
+
+ let mut request = client.request(method, url_);
+
+ if let Some(buf) = data {
+ request = request.body(Vec::from(&*buf));
+ }
+
+ 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);
+ }
+ debug!("Before fetch {}", url);
+ let future = request.send().map_err(ErrBox::from).and_then(move |res| {
+ let status = res.status();
+ let mut res_headers = Vec::new();
+ for (key, val) in res.headers().iter() {
+ res_headers.push((key.to_string(), val.to_str().unwrap().to_owned()));
+ }
+
+ let body = res.into_body();
+ let body_resource = resources::add_reqwest_body(body);
+
+ let json_res = json!({
+ "bodyRid": body_resource.rid,
+ "status": status.as_u16(),
+ "statusText": status.canonical_reason().unwrap_or(""),
+ "headers": res_headers
+ });
+
+ futures::future::ok(json_res)
+ });
+
+ Ok(JsonOp::Async(Box::new(future)))
+}