refactor(cli): more options on Worker (#8724)

This commit is contained in:
Bartek Iwańczuk 2020-12-12 00:36:18 +01:00 committed by GitHub
parent 39c86df4e5
commit 31935c6b8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 137 additions and 59 deletions

View file

@ -4,6 +4,7 @@ use crate::colors;
use crate::http_cache::HttpCache;
use crate::http_util::create_http_client;
use crate::http_util::fetch_once;
use crate::http_util::get_user_agent;
use crate::http_util::FetchOnceResult;
use crate::media_type::MediaType;
use crate::permissions::Permissions;
@ -289,7 +290,7 @@ impl FileFetcher {
cache: FileCache::default(),
cache_setting,
http_cache,
http_client: create_http_client(maybe_ca_file)?,
http_client: create_http_client(get_user_agent(), maybe_ca_file)?,
})
}

View file

@ -27,14 +27,18 @@ use std::task::Context;
use std::task::Poll;
use tokio::io::AsyncRead;
pub fn get_user_agent() -> String {
format!("Deno/{}", version::deno())
}
/// Create new instance of async reqwest::Client. This client supports
/// proxies and doesn't follow redirects.
pub fn create_http_client(ca_file: Option<&str>) -> Result<Client, AnyError> {
pub fn create_http_client(
user_agent: String,
ca_file: Option<&str>,
) -> Result<Client, AnyError> {
let mut headers = HeaderMap::new();
headers.insert(
USER_AGENT,
format!("Deno/{}", version::deno()).parse().unwrap(),
);
headers.insert(USER_AGENT, user_agent.parse().unwrap());
let mut builder = Client::builder()
.redirect(Policy::none())
.default_headers(headers)
@ -230,13 +234,17 @@ impl AsyncRead for HttpBody {
mod tests {
use super::*;
fn create_test_client(ca_file: Option<&str>) -> Client {
create_http_client("test_client".to_string(), ca_file).unwrap()
}
#[tokio::test]
async fn test_fetch_string() {
let _http_server_guard = test_util::http_server();
// Relies on external http server. See target/debug/test_server
let url =
Url::parse("http://127.0.0.1:4545/cli/tests/fixture.json").unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
assert!(!body.is_empty());
@ -256,7 +264,7 @@ mod tests {
"http://127.0.0.1:4545/cli/tests/053_import_compression/gziped",
)
.unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
assert_eq!(String::from_utf8(body).unwrap(), "console.log('gzip')");
@ -275,7 +283,7 @@ mod tests {
async fn test_fetch_with_etag() {
let _http_server_guard = test_util::http_server();
let url = Url::parse("http://127.0.0.1:4545/etag_script.ts").unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client.clone(), &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
assert!(!body.is_empty());
@ -302,7 +310,7 @@ mod tests {
"http://127.0.0.1:4545/cli/tests/053_import_compression/brotli",
)
.unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
assert!(!body.is_empty());
@ -327,7 +335,7 @@ mod tests {
// Dns resolver substitutes `127.0.0.1` with `localhost`
let target_url =
Url::parse("http://localhost:4545/cli/tests/fixture.json").unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Redirect(url, _)) = result {
assert_eq!(url, target_url);
@ -381,12 +389,15 @@ mod tests {
let url =
Url::parse("https://localhost:5545/cli/tests/fixture.json").unwrap();
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
))
let client = create_http_client(
get_user_agent(),
Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
),
)
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -407,12 +418,15 @@ mod tests {
"https://localhost:5545/cli/tests/053_import_compression/gziped",
)
.unwrap();
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
))
let client = create_http_client(
get_user_agent(),
Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
),
)
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -432,12 +446,15 @@ mod tests {
async fn test_fetch_with_cafile_with_etag() {
let _http_server_guard = test_util::http_server();
let url = Url::parse("https://localhost:5545/etag_script.ts").unwrap();
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
))
let client = create_http_client(
get_user_agent(),
Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
),
)
.unwrap();
let result = fetch_once(client.clone(), &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -466,12 +483,15 @@ mod tests {
"https://localhost:5545/cli/tests/053_import_compression/brotli",
)
.unwrap();
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
))
let client = create_http_client(
get_user_agent(),
Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
),
)
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -493,7 +513,7 @@ mod tests {
let _g = test_util::http_server();
let url_str = "http://127.0.0.1:4545/bad_redirect";
let url = Url::parse(url_str).unwrap();
let client = create_http_client(None).unwrap();
let client = create_test_client(None);
let result = fetch_once(client, &url, None).await;
assert!(result.is_err());
let err = result.unwrap_err();

View file

@ -52,7 +52,7 @@ pub struct InspectorServer {
}
impl InspectorServer {
pub fn new(host: SocketAddr) -> Self {
pub fn new(host: SocketAddr, name: String) -> Self {
let (register_inspector_tx, register_inspector_rx) =
mpsc::unbounded::<InspectorInfo>();
@ -63,6 +63,7 @@ impl InspectorServer {
host,
register_inspector_rx,
shutdown_server_rx,
name,
))
});
@ -145,6 +146,7 @@ async fn server(
host: SocketAddr,
register_inspector_rx: UnboundedReceiver<InspectorInfo>,
shutdown_server_rx: oneshot::Receiver<()>,
name: String,
) {
// TODO: put the `inspector_map` in an `Rc<RefCell<_>>` instead. This is
// currently not possible because warp requires all filters to implement
@ -199,13 +201,13 @@ async fn server(
)
});
let json_version_route = warp::path!("json" / "version").map(|| {
warp::reply::json(&json!({
"Browser": format!("Deno/{}", crate::version::deno()),
"Protocol-Version": "1.3",
"V8-Version": deno_core::v8_version(),
}))
let json_version_response = json!({
"Browser": name,
"Protocol-Version": "1.3",
"V8-Version": deno_core::v8_version(),
});
let json_version_route = warp::path!("json" / "version")
.map(move || warp::reply::json(&json_version_response));
let inspector_map_ = inspector_map.clone();
let json_list_route = warp::path("json").map(move || {

View file

@ -121,6 +121,7 @@ fn create_web_worker_callback(
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_filepath: program_state.flags.ca_file.clone(),
user_agent: http_util::get_user_agent(),
seed: program_state.flags.seed,
module_loader,
create_web_worker_cb,
@ -128,6 +129,9 @@ fn create_web_worker_callback(
use_deno_namespace: args.use_deno_namespace,
attach_inspector,
maybe_inspector_server,
runtime_version: version::deno(),
ts_version: version::TYPESCRIPT.to_string(),
no_color: !colors::use_color(),
};
let mut worker = WebWorker::from_options(
@ -192,6 +196,7 @@ pub fn create_main_worker(
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_filepath: program_state.flags.ca_file.clone(),
user_agent: http_util::get_user_agent(),
seed: program_state.flags.seed,
js_error_create_fn: Some(js_error_create_fn),
create_web_worker_cb,
@ -199,6 +204,9 @@ pub fn create_main_worker(
maybe_inspector_server,
should_break_on_first_statement,
module_loader,
runtime_version: version::deno(),
ts_version: version::TYPESCRIPT.to_string(),
no_color: !colors::use_color(),
};
let mut worker = MainWorker::from_options(main_module, permissions, &options);

View file

@ -1,4 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::http_util;
use crate::permissions::Permissions;
use deno_fetch::reqwest;
@ -7,7 +8,8 @@ pub fn init(rt: &mut deno_core::JsRuntime, maybe_ca_file: Option<&str>) {
let op_state = rt.op_state();
let mut state = op_state.borrow_mut();
state.put::<reqwest::Client>({
crate::http_util::create_http_client(maybe_ca_file).unwrap()
http_util::create_http_client(http_util::get_user_agent(), maybe_ca_file)
.unwrap()
});
}
super::reg_json_async(rt, "op_fetch", deno_fetch::op_fetch::<Permissions>);

View file

@ -35,14 +35,21 @@ use webpki::DNSNameRef;
#[derive(Clone)]
struct WsCaFile(String);
#[derive(Clone)]
struct WsUserAgent(String);
pub fn init(rt: &mut deno_core::JsRuntime, maybe_ca_file: Option<&str>) {
pub fn init(
rt: &mut deno_core::JsRuntime,
maybe_ca_file: Option<&str>,
user_agent: String,
) {
{
let op_state = rt.op_state();
let mut state = op_state.borrow_mut();
if let Some(ca_file) = maybe_ca_file {
state.put::<WsCaFile>(WsCaFile(ca_file.to_string()));
}
state.put::<WsUserAgent>(WsUserAgent(user_agent));
}
super::reg_json_sync(rt, "op_ws_check_permission", op_ws_check_permission);
super::reg_json_async(rt, "op_ws_create", op_ws_create);
@ -103,11 +110,11 @@ pub async fn op_ws_create(
}
let maybe_ca_file = state.borrow().try_borrow::<WsCaFile>().cloned();
let user_agent = state.borrow().borrow::<WsUserAgent>().0.clone();
let uri: Uri = args.url.parse()?;
let mut request = Request::builder().method(Method::GET).uri(&uri);
request =
request.header("User-Agent", format!("Deno/{}", crate::version::deno()));
request = request.header("User-Agent", user_agent);
if !args.protocols.is_empty() {
request = request.header("Sec-WebSocket-Protocol", args.protocols);

View file

@ -5,6 +5,7 @@ use crate::file_fetcher::CacheSetting;
use crate::file_fetcher::FileFetcher;
use crate::flags;
use crate::http_cache;
use crate::http_util;
use crate::import_map::ImportMap;
use crate::inspector::InspectorServer;
use crate::lockfile::Lockfile;
@ -99,7 +100,10 @@ impl ProgramState {
let maybe_inspect_host = flags.inspect.or(flags.inspect_brk);
let maybe_inspector_server = match maybe_inspect_host {
Some(host) => Some(Arc::new(InspectorServer::new(host))),
Some(host) => Some(Arc::new(InspectorServer::new(
host,
http_util::get_user_agent(),
))),
None => None,
};

View file

@ -2,6 +2,7 @@ use crate::colors;
use crate::flags::Flags;
use crate::permissions::Permissions;
use crate::tokio_util;
use crate::version;
use crate::worker::MainWorker;
use crate::worker::WorkerOptions;
use deno_core::error::type_error;
@ -120,6 +121,7 @@ async fn run(source_code: String, args: Vec<String>) -> Result<(), AnyError> {
apply_source_maps: false,
args: flags.argv.clone(),
debug_flag: false,
user_agent: crate::http_util::get_user_agent(),
unstable: true,
ca_filepath: None,
seed: None,
@ -129,6 +131,9 @@ async fn run(source_code: String, args: Vec<String>) -> Result<(), AnyError> {
maybe_inspector_server: None,
should_break_on_first_statement: false,
module_loader,
runtime_version: version::deno(),
ts_version: version::TYPESCRIPT.to_string(),
no_color: !colors::use_color(),
};
let mut worker =
MainWorker::from_options(main_module.clone(), permissions, &options);

View file

@ -8,7 +8,6 @@ use crate::metrics::Metrics;
use crate::ops;
use crate::permissions::Permissions;
use crate::tokio_util::create_basic_runtime;
use crate::version;
use deno_core::error::AnyError;
use deno_core::futures::channel::mpsc;
use deno_core::futures::future::poll_fn;
@ -133,10 +132,12 @@ pub struct WebWorker {
}
pub struct WebWorkerOptions {
/// Sets `Deno.args` in JS runtime.
pub args: Vec<String>,
pub debug_flag: bool,
pub unstable: bool,
pub ca_filepath: Option<String>,
pub user_agent: String,
pub seed: Option<u64>,
pub module_loader: Rc<dyn ModuleLoader>,
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
@ -145,6 +146,12 @@ pub struct WebWorkerOptions {
pub attach_inspector: bool,
pub maybe_inspector_server: Option<Arc<InspectorServer>>,
pub apply_source_maps: bool,
/// Sets `Deno.version.deno` in JS runtime.
pub runtime_version: String,
/// Sets `Deno.version.typescript` in JS runtime.
pub ts_version: String,
/// Sets `Deno.noColor` in JS runtime.
pub no_color: bool,
}
impl WebWorker {
@ -222,7 +229,11 @@ impl WebWorker {
deno_web::op_domain_to_ascii,
);
ops::io::init(js_runtime);
ops::websocket::init(js_runtime, options.ca_filepath.as_deref());
ops::websocket::init(
js_runtime,
options.ca_filepath.as_deref(),
options.user_agent.clone(),
);
if options.use_deno_namespace {
ops::fs_events::init(js_runtime);
@ -260,12 +271,12 @@ impl WebWorker {
"args": options.args,
"applySourceMaps": options.apply_source_maps,
"debugFlag": options.debug_flag,
"denoVersion": version::deno(),
"noColor": !colors::use_color(),
"denoVersion": options.runtime_version,
"noColor": options.no_color,
"pid": std::process::id(),
"ppid": ops::runtime::ppid(),
"target": env!("TARGET"),
"tsVersion": version::TYPESCRIPT,
"tsVersion": options.ts_version,
"unstableFlag": options.unstable,
"v8Version": deno_core::v8_version(),
});
@ -466,6 +477,7 @@ mod tests {
debug_flag: false,
unstable: false,
ca_filepath: None,
user_agent: "x".to_string(),
seed: None,
module_loader,
create_web_worker_cb,
@ -473,6 +485,9 @@ mod tests {
use_deno_namespace: false,
attach_inspector: false,
maybe_inspector_server: None,
runtime_version: "x".to_string(),
ts_version: "x".to_string(),
no_color: true,
};
let mut worker = WebWorker::from_options(

View file

@ -1,6 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::colors;
use crate::inspector::DenoInspector;
use crate::inspector::InspectorServer;
use crate::inspector::InspectorSession;
@ -8,7 +7,6 @@ use crate::js;
use crate::metrics::Metrics;
use crate::ops;
use crate::permissions::Permissions;
use crate::version;
use deno_core::error::AnyError;
use deno_core::futures::future::poll_fn;
use deno_core::futures::future::FutureExt;
@ -42,10 +40,12 @@ pub struct MainWorker {
pub struct WorkerOptions {
pub apply_source_maps: bool,
/// Sets `Deno.args` in JS runtime.
pub args: Vec<String>,
pub debug_flag: bool,
pub unstable: bool,
pub ca_filepath: Option<String>,
pub user_agent: String,
pub seed: Option<u64>,
pub module_loader: Rc<dyn ModuleLoader>,
// Callback that will be invoked when creating new instance
@ -55,6 +55,12 @@ pub struct WorkerOptions {
pub attach_inspector: bool,
pub maybe_inspector_server: Option<Arc<InspectorServer>>,
pub should_break_on_first_statement: bool,
/// Sets `Deno.version.deno` in JS runtime.
pub runtime_version: String,
/// Sets `Deno.version.typescript` in JS runtime.
pub ts_version: String,
/// Sets `Deno.noColor` in JS runtime.
pub no_color: bool,
}
impl MainWorker {
@ -128,7 +134,11 @@ impl MainWorker {
ops::signal::init(js_runtime);
ops::tls::init(js_runtime);
ops::tty::init(js_runtime);
ops::websocket::init(js_runtime, options.ca_filepath.as_deref());
ops::websocket::init(
js_runtime,
options.ca_filepath.as_deref(),
options.user_agent.clone(),
);
}
{
let op_state = js_runtime.op_state();
@ -154,12 +164,12 @@ impl MainWorker {
"args": options.args,
"applySourceMaps": options.apply_source_maps,
"debugFlag": options.debug_flag,
"denoVersion": version::deno(),
"noColor": !colors::use_color(),
"denoVersion": options.runtime_version,
"noColor": options.no_color,
"pid": std::process::id(),
"ppid": ops::runtime::ppid(),
"target": env!("TARGET"),
"tsVersion": version::TYPESCRIPT,
"tsVersion": options.ts_version,
"unstableFlag": options.unstable,
"v8Version": deno_core::v8_version(),
});
@ -249,6 +259,7 @@ mod tests {
let options = WorkerOptions {
apply_source_maps: false,
user_agent: "x".to_string(),
args: vec![],
debug_flag: false,
unstable: false,
@ -260,6 +271,9 @@ mod tests {
maybe_inspector_server: None,
should_break_on_first_statement: false,
module_loader: Rc::new(deno_core::FsModuleLoader),
runtime_version: "x".to_string(),
ts_version: "x".to_string(),
no_color: true,
};
MainWorker::from_options(main_module, permissions, &options)