Skip to content

Commit 045e74b

Browse files
orsibartlomieju
authored andcommitted
feat: Add Deno.dialTLS()
Co-authored-by: Bartek Iwańczuk <[email protected]>
1 parent 4ff04ad commit 045e74b

12 files changed

+206
-22
lines changed

Cargo.lock

Lines changed: 49 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ tokio-rustls = "0.10.0"
5656
tokio-threadpool = "0.1.15"
5757
url = "1.7.2"
5858
utime = "0.2.1"
59+
webpki = "0.21.0"
60+
webpki-roots = "0.17.0"
5961

6062
[target.'cfg(windows)'.dependencies]
6163
winapi = "0.3.8"

cli/ops/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod random;
2020
mod repl;
2121
mod resources;
2222
mod timers;
23+
mod tls;
2324
mod workers;
2425

2526
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
@@ -81,6 +82,7 @@ pub const OP_TRUNCATE: OpId = 54;
8182
pub const OP_MAKE_TEMP_DIR: OpId = 55;
8283
pub const OP_CWD: OpId = 56;
8384
pub const OP_FETCH_ASSET: OpId = 57;
85+
pub const OP_DIAL_TLS: OpId = 58;
8486

8587
pub fn dispatch(
8688
state: &ThreadSafeState,
@@ -300,6 +302,9 @@ pub fn dispatch(
300302
control,
301303
zero_copy,
302304
),
305+
OP_DIAL_TLS => {
306+
dispatch_json::dispatch(tls::op_dial_tls, state, control, zero_copy)
307+
}
303308
_ => panic!("bad op_id"),
304309
};
305310

cli/ops/tls.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
2+
use super::dispatch_json::{Deserialize, JsonOp, Value};
3+
use crate::resolve_addr::resolve_addr;
4+
use crate::resources;
5+
use crate::state::ThreadSafeState;
6+
use deno::*;
7+
use futures::Future;
8+
use std;
9+
use std::convert::From;
10+
use std::sync::Arc;
11+
use tokio;
12+
use tokio::net::TcpStream;
13+
use tokio_rustls::{rustls::ClientConfig, TlsConnector};
14+
use webpki;
15+
use webpki::DNSNameRef;
16+
use webpki_roots;
17+
18+
#[derive(Deserialize)]
19+
struct DialTLSArgs {
20+
hostname: String,
21+
port: u16,
22+
}
23+
24+
pub fn op_dial_tls(
25+
state: &ThreadSafeState,
26+
args: Value,
27+
_zero_copy: Option<PinnedBuf>,
28+
) -> Result<JsonOp, ErrBox> {
29+
let args: DialTLSArgs = serde_json::from_value(args)?;
30+
31+
// TODO(ry) Using format! is suboptimal here. Better would be if
32+
// state.check_net and resolve_addr() took hostname and port directly.
33+
let address = format!("{}:{}", args.hostname, args.port);
34+
35+
state.check_net(&address)?;
36+
37+
let mut domain = args.hostname;
38+
if domain.is_empty() {
39+
domain.push_str("localhost");
40+
}
41+
42+
let op = resolve_addr(&address).and_then(move |addr| {
43+
TcpStream::connect(&addr)
44+
.and_then(move |tcp_stream| {
45+
let local_addr = tcp_stream.local_addr()?;
46+
let remote_addr = tcp_stream.peer_addr()?;
47+
let mut config = ClientConfig::new();
48+
config
49+
.root_store
50+
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
51+
52+
let tls_connector = TlsConnector::from(Arc::new(config));
53+
Ok((tls_connector, tcp_stream, local_addr, remote_addr))
54+
})
55+
.map_err(ErrBox::from)
56+
.and_then(
57+
move |(tls_connector, tcp_stream, local_addr, remote_addr)| {
58+
let dnsname = DNSNameRef::try_from_ascii_str(&domain)
59+
.expect("Invalid DNS lookup");
60+
tls_connector
61+
.connect(dnsname, tcp_stream)
62+
.map_err(ErrBox::from)
63+
.and_then(move |tls_stream| {
64+
let tls_stream_resource = resources::add_tls_stream(tls_stream);
65+
futures::future::ok(json!({
66+
"rid": tls_stream_resource.rid,
67+
"localAddr": local_addr.to_string(),
68+
"remoteAddr": remote_addr.to_string(),
69+
}))
70+
})
71+
},
72+
)
73+
});
74+
75+
Ok(JsonOp::Async(Box::new(op)))
76+
}

0 commit comments

Comments
 (0)