summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Orsi <jonathon.orsi@gmail.com>2019-09-23 14:40:38 -0400
committerRyan Dahl <ry@tinyclouds.org>2019-09-23 15:12:42 -0400
commit045e74bb39d7743b774cfd2b889bc6ce1e1ad245 (patch)
tree93a8429860a40eabaee813e6f983f64aebd8afc7
parent4ff04ad96f27b7073e3478630ed249eedc76af2b (diff)
feat: Add Deno.dialTLS()
Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
-rw-r--r--Cargo.lock68
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/ops/mod.rs5
-rw-r--r--cli/ops/tls.rs76
-rw-r--r--cli/resources.rs13
-rw-r--r--js/deno.ts1
-rw-r--r--js/dispatch.ts2
-rw-r--r--js/lib.deno_runtime.d.ts11
-rw-r--r--js/net.ts3
-rw-r--r--js/tls.ts21
-rw-r--r--js/tls_test.ts25
-rw-r--r--js/unit_tests.ts1
12 files changed, 206 insertions, 22 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9fe95b1fa..83fd39b7e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -120,7 +120,7 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -188,7 +188,7 @@ dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -278,7 +278,7 @@ dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -286,7 +286,7 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"os_pipe 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -307,6 +307,8 @@ dependencies = [
"tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"utime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -354,7 +356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "either"
-version = "1.5.2"
+version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -514,7 +516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hyper"
-version = "0.12.34"
+version = "0.12.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -549,7 +551,7 @@ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -561,7 +563,7 @@ dependencies = [
name = "hyper_hello"
version = "0.0.1"
dependencies = [
- "hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -576,6 +578,16 @@ dependencies = [
]
[[package]]
+name = "idna"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "indexmap"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -836,6 +848,11 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "ppv-lite86"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -858,14 +875,14 @@ dependencies = [
[[package]]
name = "publicsuffix"
-version = "1.5.2"
+version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -916,7 +933,7 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1090,7 +1107,7 @@ dependencies = [
"flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1368,7 +1385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1437,7 +1454,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1707,6 +1724,16 @@ dependencies = [
]
[[package]]
+name = "url"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "utf8parse"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1963,7 +1990,7 @@ dependencies = [
"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
-"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
+"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)" = "79906e1ad1f7f8bc48864fcc6ffd58336fb5992e627bf61928099cb25fdf4314"
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
@@ -1982,9 +2009,10 @@ dependencies = [
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
-"checksum hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)" = "898a87371a3999b2f731b9af636cd76aa20de10e69c2daf3e71388326b619fe0"
+"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
"checksum hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "719d85c7df4a7f309a77d145340a063ea929dcb2e025bae46a80345cffec2952"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
+"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
@@ -2016,15 +2044,16 @@ dependencies = [
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
+"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
-"checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d"
+"checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
-"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
+"checksum rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59cea0d944b32347a1863e95942fd6ebdb486afb4f038119494f2860380c1d51"
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
@@ -2107,6 +2136,7 @@ dependencies = [
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
+"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
"checksum utime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "055058552ca15c566082fc61da433ae678f78986a6f16957e33162d1b218792a"
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index b9a9c1456..463c9fbc1 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -56,6 +56,8 @@ tokio-rustls = "0.10.0"
tokio-threadpool = "0.1.15"
url = "1.7.2"
utime = "0.2.1"
+webpki = "0.21.0"
+webpki-roots = "0.17.0"
[target.'cfg(windows)'.dependencies]
winapi = "0.3.8"
diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs
index 7a2e9c9f4..ea71fee9f 100644
--- a/cli/ops/mod.rs
+++ b/cli/ops/mod.rs
@@ -20,6 +20,7 @@ mod random;
mod repl;
mod resources;
mod timers;
+mod tls;
mod workers;
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
@@ -81,6 +82,7 @@ pub const OP_TRUNCATE: OpId = 54;
pub const OP_MAKE_TEMP_DIR: OpId = 55;
pub const OP_CWD: OpId = 56;
pub const OP_FETCH_ASSET: OpId = 57;
+pub const OP_DIAL_TLS: OpId = 58;
pub fn dispatch(
state: &ThreadSafeState,
@@ -300,6 +302,9 @@ pub fn dispatch(
control,
zero_copy,
),
+ OP_DIAL_TLS => {
+ dispatch_json::dispatch(tls::op_dial_tls, state, control, zero_copy)
+ }
_ => panic!("bad op_id"),
};
diff --git a/cli/ops/tls.rs b/cli/ops/tls.rs
new file mode 100644
index 000000000..2b1d94f2b
--- /dev/null
+++ b/cli/ops/tls.rs
@@ -0,0 +1,76 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use super::dispatch_json::{Deserialize, JsonOp, Value};
+use crate::resolve_addr::resolve_addr;
+use crate::resources;
+use crate::state::ThreadSafeState;
+use deno::*;
+use futures::Future;
+use std;
+use std::convert::From;
+use std::sync::Arc;
+use tokio;
+use tokio::net::TcpStream;
+use tokio_rustls::{rustls::ClientConfig, TlsConnector};
+use webpki;
+use webpki::DNSNameRef;
+use webpki_roots;
+
+#[derive(Deserialize)]
+struct DialTLSArgs {
+ hostname: String,
+ port: u16,
+}
+
+pub fn op_dial_tls(
+ state: &ThreadSafeState,
+ args: Value,
+ _zero_copy: Option<PinnedBuf>,
+) -> Result<JsonOp, ErrBox> {
+ let args: DialTLSArgs = serde_json::from_value(args)?;
+
+ // TODO(ry) Using format! is suboptimal here. Better would be if
+ // state.check_net and resolve_addr() took hostname and port directly.
+ let address = format!("{}:{}", args.hostname, args.port);
+
+ state.check_net(&address)?;
+
+ let mut domain = args.hostname;
+ if domain.is_empty() {
+ domain.push_str("localhost");
+ }
+
+ let op = resolve_addr(&address).and_then(move |addr| {
+ TcpStream::connect(&addr)
+ .and_then(move |tcp_stream| {
+ let local_addr = tcp_stream.local_addr()?;
+ let remote_addr = tcp_stream.peer_addr()?;
+ let mut config = ClientConfig::new();
+ config
+ .root_store
+ .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
+
+ let tls_connector = TlsConnector::from(Arc::new(config));
+ Ok((tls_connector, tcp_stream, local_addr, remote_addr))
+ })
+ .map_err(ErrBox::from)
+ .and_then(
+ move |(tls_connector, tcp_stream, local_addr, remote_addr)| {
+ let dnsname = DNSNameRef::try_from_ascii_str(&domain)
+ .expect("Invalid DNS lookup");
+ tls_connector
+ .connect(dnsname, tcp_stream)
+ .map_err(ErrBox::from)
+ .and_then(move |tls_stream| {
+ let tls_stream_resource = resources::add_tls_stream(tls_stream);
+ futures::future::ok(json!({
+ "rid": tls_stream_resource.rid,
+ "localAddr": local_addr.to_string(),
+ "remoteAddr": remote_addr.to_string(),
+ }))
+ })
+ },
+ )
+ });
+
+ Ok(JsonOp::Async(Box::new(op)))
+}
diff --git a/cli/resources.rs b/cli/resources.rs
index 3bce51afb..0fdb0e182 100644
--- a/cli/resources.rs
+++ b/cli/resources.rs
@@ -36,6 +36,7 @@ use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;
use tokio::sync::mpsc;
use tokio_process;
+use tokio_rustls::client::TlsStream;
pub type ResourceId = u32; // Sometimes referred to RID.
@@ -89,6 +90,7 @@ enum Repr {
// See: https://github.com/tokio-rs/tokio/issues/846
TcpListener(tokio::net::TcpListener, Option<futures::task::Task>),
TcpStream(tokio::net::TcpStream),
+ TlsStream(Box<TlsStream<TcpStream>>),
HttpBody(HttpBody),
Repl(Arc<Mutex<Repl>>),
// Enum size is bounded by the largest variant.
@@ -134,6 +136,7 @@ fn inspect_repr(repr: &Repr) -> String {
Repr::FsFile(_) => "fsFile",
Repr::TcpListener(_, _) => "tcpListener",
Repr::TcpStream(_) => "tcpStream",
+ Repr::TlsStream(_) => "tlsStream",
Repr::HttpBody(_) => "httpBody",
Repr::Repl(_) => "repl",
Repr::Child(_) => "child",
@@ -249,6 +252,7 @@ impl DenoAsyncRead for Resource {
Repr::FsFile(ref mut f) => f.poll_read(buf),
Repr::Stdin(ref mut f) => f.poll_read(buf),
Repr::TcpStream(ref mut f) => f.poll_read(buf),
+ Repr::TlsStream(ref mut f) => f.poll_read(buf),
Repr::HttpBody(ref mut f) => f.poll_read(buf),
Repr::ChildStdout(ref mut f) => f.poll_read(buf),
Repr::ChildStderr(ref mut f) => f.poll_read(buf),
@@ -289,6 +293,7 @@ impl DenoAsyncWrite for Resource {
Repr::Stdout(ref mut f) => f.poll_write(buf),
Repr::Stderr(ref mut f) => f.poll_write(buf),
Repr::TcpStream(ref mut f) => f.poll_write(buf),
+ Repr::TlsStream(ref mut f) => f.poll_write(buf),
Repr::ChildStdin(ref mut f) => f.poll_write(buf),
_ => {
return Err(bad_resource());
@@ -332,6 +337,14 @@ pub fn add_tcp_stream(stream: tokio::net::TcpStream) -> Resource {
Resource { rid }
}
+pub fn add_tls_stream(stream: TlsStream<TcpStream>) -> Resource {
+ let rid = new_rid();
+ let mut tg = RESOURCE_TABLE.lock().unwrap();
+ let r = tg.insert(rid, Repr::TlsStream(Box::new(stream)));
+ assert!(r.is_none());
+ Resource { rid }
+}
+
pub fn add_reqwest_body(body: ReqwestDecoder) -> Resource {
let rid = new_rid();
let mut tg = RESOURCE_TABLE.lock().unwrap();
diff --git a/js/deno.ts b/js/deno.ts
index 4efa641d3..916b7471a 100644
--- a/js/deno.ts
+++ b/js/deno.ts
@@ -75,6 +75,7 @@ export {
export { truncateSync, truncate } from "./truncate.ts";
export { FileInfo } from "./file_info.ts";
export { connect, dial, listen, Listener, Conn } from "./net.ts";
+export { dialTLS } from "./tls.ts";
export { metrics, Metrics } from "./metrics.ts";
export { resources } from "./resources.ts";
export {
diff --git a/js/dispatch.ts b/js/dispatch.ts
index a15da69f4..b5116d68a 100644
--- a/js/dispatch.ts
+++ b/js/dispatch.ts
@@ -60,6 +60,7 @@ export const OP_TRUNCATE = 54;
export const OP_MAKE_TEMP_DIR = 55;
export const OP_CWD = 56;
export const OP_FETCH_ASSET = 57;
+export const OP_DIAL_TLS = 58;
export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
switch (opId) {
@@ -97,6 +98,7 @@ export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
case OP_READ_LINK:
case OP_TRUNCATE:
case OP_MAKE_TEMP_DIR:
+ case OP_DIAL_TLS:
json.asyncMsgFromRust(opId, ui8);
break;
default:
diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts
index fc4e6508f..36e49c9c2 100644
--- a/js/lib.deno_runtime.d.ts
+++ b/js/lib.deno_runtime.d.ts
@@ -999,8 +999,17 @@ declare namespace Deno {
*/
export function dial(options: DialOptions): Promise<Conn>;
- // @url js/metrics.d.ts
+ export interface DialTLSOptions {
+ port: number;
+ hostname?: string;
+ }
+ /**
+ * dialTLS establishes a secure connection over TLS (transport layer security).
+ */
+ export function dialTLS(options: DialTLSOptions): Promise<Conn>;
+
+ // @url js/metrics.d.ts
export interface Metrics {
opsDispatched: number;
opsCompleted: number;
diff --git a/js/net.ts b/js/net.ts
index 28c8cf8e0..4da6da38e 100644
--- a/js/net.ts
+++ b/js/net.ts
@@ -44,7 +44,7 @@ function shutdown(rid: number, how: ShutdownMode): void {
sendSync(dispatch.OP_SHUTDOWN, { rid, how });
}
-class ConnImpl implements Conn {
+export class ConnImpl implements Conn {
constructor(
readonly rid: number,
readonly remoteAddr: string,
@@ -187,7 +187,6 @@ const dialDefaults = { hostname: "127.0.0.1", transport: "tcp" };
export async function dial(options: DialOptions): Promise<Conn> {
options = Object.assign(dialDefaults, options);
const res = await sendAsync(dispatch.OP_DIAL, options);
- // TODO(bartlomieju): add remoteAddr and localAddr on Rust side
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
}
diff --git a/js/tls.ts b/js/tls.ts
new file mode 100644
index 000000000..ec24b458b
--- /dev/null
+++ b/js/tls.ts
@@ -0,0 +1,21 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import { sendAsync } from "./dispatch_json.ts";
+import * as dispatch from "./dispatch.ts";
+import { Conn, ConnImpl } from "./net.ts";
+
+// TODO(ry) There are many configuration options to add...
+// https://docs.rs/rustls/0.16.0/rustls/struct.ClientConfig.html
+interface DialTLSOptions {
+ port: number;
+ hostname?: string;
+}
+const dialTLSDefaults = { hostname: "127.0.0.1", transport: "tcp" };
+
+/**
+ * dialTLS establishes a secure connection over TLS (transport layer security).
+ */
+export async function dialTLS(options: DialTLSOptions): Promise<Conn> {
+ options = Object.assign(dialTLSDefaults, options);
+ const res = await sendAsync(dispatch.OP_DIAL_TLS, options);
+ return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
+}
diff --git a/js/tls_test.ts b/js/tls_test.ts
new file mode 100644
index 000000000..25900f876
--- /dev/null
+++ b/js/tls_test.ts
@@ -0,0 +1,25 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import { test, testPerm, assert, assertEquals } from "./test_util.ts";
+
+// TODO(ry) The tests in this file use github.com:443, but it would be better to
+// not rely on an internet connection and rather use a localhost TLS server.
+
+test(async function dialTLSNoPerm(): Promise<void> {
+ let err;
+ try {
+ await Deno.dialTLS({ hostname: "github.com", port: 443 });
+ } catch (e) {
+ err = e;
+ }
+ assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
+ assertEquals(err.name, "PermissionDenied");
+});
+
+testPerm({ net: true }, async function dialTLSBasic(): Promise<void> {
+ const conn = await Deno.dialTLS({ hostname: "github.com", port: 443 });
+ assert(conn.rid > 0);
+ const body = new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n");
+ const writeResult = await conn.write(body);
+ assertEquals(body.length, writeResult);
+ conn.close();
+});
diff --git a/js/unit_tests.ts b/js/unit_tests.ts
index 711a092fd..2da67c40e 100644
--- a/js/unit_tests.ts
+++ b/js/unit_tests.ts
@@ -43,6 +43,7 @@ import "./stat_test.ts";
import "./symlink_test.ts";
import "./text_encoding_test.ts";
import "./timers_test.ts";
+import "./tls_test.ts";
import "./truncate_test.ts";
import "./url_test.ts";
import "./url_search_params_test.ts";