mirror of
https://github.com/denoland/deno.git
synced 2025-02-02 04:38:21 -05:00
fd62379eaf
- removes global `RESOURCE_TABLE` - resource tables are now created per `Worker` in `State` - renames `CliResource` to `StreamResource` and moves all logic related to it to `cli/ops/io.rs` - removes `cli/resources.rs` - adds `state` argument to `op_read` and `op_write` and consequently adds `stateful_minimal_op` to `State` - IMPORTANT NOTE: workers don't have access to process stdio - this is caused by fact that dropping worker would close stdout for process (because it's constructed from raw handle, which closes underlying file descriptor on drop)
81 lines
2.2 KiB
Rust
81 lines
2.2 KiB
Rust
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
|
use super::dispatch_json::{Deserialize, JsonOp, Value};
|
|
use super::io::StreamResource;
|
|
use crate::http_body::HttpBody;
|
|
use crate::http_util::get_client;
|
|
use crate::ops::json_op;
|
|
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;
|
|
|
|
pub fn init(i: &mut Isolate, s: &ThreadSafeState) {
|
|
i.register_op("fetch", s.core_op(json_op(s.stateful_op(op_fetch))));
|
|
}
|
|
|
|
#[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 state_ = state.clone();
|
|
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 = HttpBody::from(res.into_body());
|
|
let mut table = state_.lock_resource_table();
|
|
let rid = table.add("httpBody", Box::new(StreamResource::HttpBody(body)));
|
|
|
|
let json_res = json!({
|
|
"bodyRid": 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)))
|
|
}
|