1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

feat(runtime/http): server side websocket support (#10359)

Co-authored-by: Nayeem Rahman <nayeemrmn99@gmail.com>
Co-authored-by: Luca Casonato <hello@lcas.dev>
This commit is contained in:
Leo K 2021-07-08 13:33:01 +02:00 committed by GitHub
parent 215f6f2c9e
commit 5e092b19fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 579 additions and 217 deletions

302
Cargo.lock generated
View file

@ -26,11 +26,11 @@ checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.7.2" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f200cbb1e856866d9eade941cf3aa0c5d7dd36f74311c4273b494f4ef036957" checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
dependencies = [ dependencies = [
"getrandom 0.2.2", "getrandom 0.2.3",
"once_cell", "once_cell",
"version_check", "version_check",
] ]
@ -100,7 +100,7 @@ checksum = "f93f52ce8fac3d0e6720a92b0576d737c01b1b5db4dd786e962e5925f00bf755"
dependencies = [ dependencies = [
"darling", "darling",
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
@ -122,9 +122,9 @@ dependencies = [
[[package]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a26cb53174ddd320edfff199a853f93d571f48eeb4dde75e67a9a3dbb7b7e5e" checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625"
dependencies = [ dependencies = [
"async-stream-impl", "async-stream-impl",
"futures-core", "futures-core",
@ -132,11 +132,11 @@ dependencies = [
[[package]] [[package]]
name = "async-stream-impl" name = "async-stream-impl"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db134ba52475c060f3329a8ef0f8786d6b872ed01515d4b79c162e5798da1340" checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -147,7 +147,7 @@ version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -170,7 +170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cbf586c80ada5e5ccdecae80d3ef0854f224e2dd74435f8d87e6831b8d0a38" checksum = "42cbf586c80ada5e5ccdecae80d3ef0854f224e2dd74435f8d87e6831b8d0a38"
dependencies = [ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -270,9 +270,9 @@ checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.6.1" version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -288,9 +288,9 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.67" version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
dependencies = [ dependencies = [
"jobserver", "jobserver",
] ]
@ -341,6 +341,17 @@ dependencies = [
"vec_map", "vec_map",
] ]
[[package]]
name = "clipboard-win"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4ea1881992efc993e4dc50a324cdbd03216e41bdc8385720ff47efc9bd2ca8"
dependencies = [
"error-code",
"str-buf",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "cocoa-foundation" name = "cocoa-foundation"
version = "0.1.0" version = "0.1.0"
@ -408,9 +419,9 @@ dependencies = [
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.1.4" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -445,11 +456,10 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.4" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [ dependencies = [
"autocfg 1.0.1",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"lazy_static", "lazy_static",
] ]
@ -483,7 +493,7 @@ checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"strsim 0.9.3", "strsim 0.9.3",
"syn 1.0.65", "syn 1.0.65",
@ -721,12 +731,15 @@ dependencies = [
name = "deno_net" name = "deno_net"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.13.0",
"bytes", "bytes",
"deno_core", "deno_core",
"deno_websocket",
"http", "http",
"hyper", "hyper",
"lazy_static", "lazy_static",
"log", "log",
"ring",
"rustls", "rustls",
"serde", "serde",
"tokio", "tokio",
@ -842,6 +855,7 @@ version = "0.15.1"
dependencies = [ dependencies = [
"deno_core", "deno_core",
"http", "http",
"hyper",
"serde", "serde",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
@ -867,7 +881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320" checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -1009,7 +1023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -1021,16 +1035,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b940da354ae81ef0926c5eaa428207b8f4f091d3956c891dfbd124162bed99" checksum = "78b940da354ae81ef0926c5eaa428207b8f4f091d3956c891dfbd124162bed99"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
] ]
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.8.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [ dependencies = [
"atty", "atty",
"humantime", "humantime",
@ -1071,6 +1085,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "error-code"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff"
dependencies = [
"libc",
"str-buf",
]
[[package]] [[package]]
name = "exec" name = "exec"
version = "0.3.1" version = "0.3.1"
@ -1113,6 +1137,16 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "fd-lock"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0010f02effd88c702318c5dde0463206be67495d0b4d906ba7c0a8f166cc7f06"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "filetime" name = "filetime"
version = "0.2.14" version = "0.2.14"
@ -1181,36 +1215,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0951635027ca477be98f8774abd6f0345233439d63f307e47101acb40c7cc63d" checksum = "0951635027ca477be98f8774abd6f0345233439d63f307e47101acb40c7cc63d"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
] ]
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "fsevent"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97f347202c95c98805c216f9e1df210e8ebaec9fdb2365700a43c10797a35e63"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]] [[package]]
name = "fsevent-sys" name = "fsevent-sys"
version = "3.1.0" version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6f5e6817058771c10f0eb0f05ddf1e35844266f972004fe8e4b21fda295bd5" checksum = "5c0e564d24da983c053beff1bb7178e237501206840a3e6bf4e267b9e8ae734a"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -1281,7 +1295,7 @@ checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
dependencies = [ dependencies = [
"autocfg 1.0.1", "autocfg 1.0.1",
"proc-macro-hack", "proc-macro-hack",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -1367,9 +1381,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
@ -1552,9 +1566,9 @@ dependencies = [
[[package]] [[package]]
name = "gpu-alloc" name = "gpu-alloc"
version = "0.4.5" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76088804bb65a6f3b880bea9306fdaeffb25ebb453105fafa691282ee9fdba" checksum = "cbc1b6ca374e81862526786d9cb42357ce03706ed1b8761730caafd02ab91f3a"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"gpu-alloc-types", "gpu-alloc-types",
@ -1623,7 +1637,7 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [ dependencies = [
"ahash 0.7.2", "ahash 0.7.4",
] ]
[[package]] [[package]]
@ -1637,18 +1651,18 @@ dependencies = [
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.18" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -1694,9 +1708,9 @@ checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9" checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
[[package]] [[package]]
name = "humantime" name = "humantime"
@ -1706,9 +1720,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.9" version = "0.14.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" checksum = "7728a72c4c7d72665fde02204bcbd93b247721025b222ef78606f14513e0fd03"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -1768,12 +1782,12 @@ checksum = "1f7280c75fb2e2fc47080ec80ccc481376923acb04501957fc38f935c3de5088"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.6.2" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [ dependencies = [
"autocfg 1.0.1", "autocfg 1.0.1",
"hashbrown 0.9.1", "hashbrown 0.11.2",
"serde", "serde",
] ]
@ -1835,9 +1849,9 @@ dependencies = [
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.3.0" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
[[package]] [[package]]
name = "is-macro" name = "is-macro"
@ -1847,7 +1861,7 @@ checksum = "a322dd16d960e322c3d92f541b4c1a4f0a2e81e1fdeee430d8cecc8b72e8015f"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -1939,9 +1953,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.94" version = "0.2.97"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -2006,9 +2020,9 @@ dependencies = [
[[package]] [[package]]
name = "lsp-types" name = "lsp-types"
version = "0.89.0" version = "0.89.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07731ecd4ee0654728359a5b95e2a254c857876c04b85225496a35d60345daa7" checksum = "852e0dedfd52cc32325598b2631e0eba31b7b708959676a9f837042f276b09a2"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"serde", "serde",
@ -2049,7 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca1d48da0e4a6100b4afd52fae99f36d47964a209624021280ad9ffdd410e83d" checksum = "ca1d48da0e4a6100b4afd52fae99f36d47964a209624021280ad9ffdd410e83d"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -2113,9 +2127,9 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.7.11" version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@ -2180,14 +2194,13 @@ dependencies = [
[[package]] [[package]]
name = "notify" name = "notify"
version = "5.0.0-pre.8" version = "5.0.0-pre.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bbbcd078f1f00ddb7a9abe70b96e91229b44b0b3afdec610f8e5137f8f014b" checksum = "51f18203a26893ca1d3526cf58084025d5639f91c44f8b70ab3b724f60e819a0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"crossbeam-channel", "crossbeam-channel",
"filetime", "filetime",
"fsevent",
"fsevent-sys", "fsevent-sys",
"inotify", "inotify",
"libc", "libc",
@ -2308,9 +2321,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.7.2" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -2428,7 +2441,7 @@ dependencies = [
"phf_generator", "phf_generator",
"phf_shared", "phf_shared",
"proc-macro-hack", "proc-macro-hack",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -2457,16 +2470,16 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@ -2486,7 +2499,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004" checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -2510,7 +2523,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [ dependencies = [
"proc-macro-error-attr", "proc-macro-error-attr",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
"version_check", "version_check",
@ -2522,7 +2535,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"version_check", "version_check",
] ]
@ -2550,18 +2563,18 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.26" version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [ dependencies = [
"unicode-xid 0.2.2", "unicode-xid 0.2.2",
] ]
[[package]] [[package]]
name = "profiling" name = "profiling"
version = "1.0.1" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3a66d5e88679f2720126c11ee29da07a08f094eac52306b066edd7d393752d6" checksum = "87dfd5592a8eed7e74f56ad7b125f8234763b805c30f0c7c95c486920026a6ec"
[[package]] [[package]]
name = "pty" name = "pty"
@ -2605,7 +2618,7 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
] ]
[[package]] [[package]]
@ -2645,9 +2658,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha 0.3.0", "rand_chacha 0.3.1",
"rand_core 0.6.2", "rand_core 0.6.3",
"rand_hc 0.3.0", "rand_hc 0.3.1",
] ]
[[package]] [[package]]
@ -2662,12 +2675,12 @@ dependencies = [
[[package]] [[package]]
name = "rand_chacha" name = "rand_chacha"
version = "0.3.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core 0.6.2", "rand_core 0.6.3",
] ]
[[package]] [[package]]
@ -2681,11 +2694,11 @@ dependencies = [
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.2" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [ dependencies = [
"getrandom 0.2.2", "getrandom 0.2.3",
] ]
[[package]] [[package]]
@ -2699,11 +2712,11 @@ dependencies = [
[[package]] [[package]]
name = "rand_hc" name = "rand_hc"
version = "0.3.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [ dependencies = [
"rand_core 0.6.2", "rand_core 0.6.3",
] ]
[[package]] [[package]]
@ -2732,9 +2745,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.8" version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@ -2780,9 +2793,9 @@ checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.3" version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22"
dependencies = [ dependencies = [
"async-compression", "async-compression",
"base64 0.13.0", "base64 0.13.0",
@ -2938,13 +2951,14 @@ dependencies = [
[[package]] [[package]]
name = "rustyline" name = "rustyline"
version = "8.0.0" version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e1b597fcd1eeb1d6b25b493538e5aa19629eb08932184b85fef931ba87e893" checksum = "fbd4eaf7a7738f76c98e4f0395253ae853be3eb018f7b0bb57fe1b6c17e31874"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"fs2", "clipboard-win",
"fd-lock",
"libc", "libc",
"log", "log",
"memchr", "memchr",
@ -3044,7 +3058,7 @@ version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -3067,7 +3081,7 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -3128,9 +3142,9 @@ checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.3.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -3256,6 +3270,12 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "str-buf"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
[[package]] [[package]]
name = "string_cache" name = "string_cache"
version = "0.8.1" version = "0.8.1"
@ -3277,7 +3297,7 @@ checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97"
dependencies = [ dependencies = [
"phf_generator", "phf_generator",
"phf_shared", "phf_shared",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
] ]
@ -3288,7 +3308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f584cc881e9e5f1fd6bf827b0444aa94c30d8fe6378cf241071b5f5700b2871f" checksum = "f584cc881e9e5f1fd6bf827b0444aa94c30d8fe6378cf241071b5f5700b2871f"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
@ -3328,7 +3348,7 @@ version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a893fda61ad72583351e97313439b9cdd200ffb6b2ae75f363e03a39df935086" checksum = "a893fda61ad72583351e97313439b9cdd200ffb6b2ae75f363e03a39df935086"
dependencies = [ dependencies = [
"ahash 0.7.2", "ahash 0.7.4",
"anyhow", "anyhow",
"crc", "crc",
"fxhash", "fxhash",
@ -3412,7 +3432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51af418026cb4ea588e2b15fa206c44e09a3184b718e12a0919729c7c3ad20d3" checksum = "51af418026cb4ea588e2b15fa206c44e09a3184b718e12a0919729c7c3ad20d3"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
@ -3649,7 +3669,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c8f200a2eaed938e7c1a685faaa66e6d42fa9e17da5f62572d3cbc335898f5e" checksum = "8c8f200a2eaed938e7c1a685faaa66e6d42fa9e17da5f62572d3cbc335898f5e"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -3661,7 +3681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08ed2e930f5a1a4071fe62c90fd3a296f6030e5d94bfe13993244423caf59a78" checksum = "08ed2e930f5a1a4071fe62c90fd3a296f6030e5d94bfe13993244423caf59a78"
dependencies = [ dependencies = [
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -3684,7 +3704,7 @@ checksum = "e3b2825fee79f10d0166e8e650e79c7a862fb991db275743083f07555d7641f0"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"pmutil", "pmutil",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"swc_macros_common", "swc_macros_common",
"syn 1.0.65", "syn 1.0.65",
@ -3707,7 +3727,7 @@ version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"unicode-xid 0.2.2", "unicode-xid 0.2.2",
] ]
@ -3718,7 +3738,7 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
"unicode-xid 0.2.2", "unicode-xid 0.2.2",
@ -3795,20 +3815,20 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.24" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.24" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -3880,7 +3900,7 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
] ]
@ -4127,9 +4147,9 @@ dependencies = [
[[package]] [[package]]
name = "twoway" name = "twoway"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc" checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47"
dependencies = [ dependencies = [
"memchr", "memchr",
"unchecked-index", "unchecked-index",
@ -4173,9 +4193,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.17" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [ dependencies = [
"tinyvec", "tinyvec",
] ]
@ -4241,15 +4261,15 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [ dependencies = [
"getrandom 0.2.2", "getrandom 0.2.3",
"serde", "serde",
] ]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.12" version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "vec_map" name = "vec_map"
@ -4317,7 +4337,7 @@ dependencies = [
"bumpalo", "bumpalo",
"lazy_static", "lazy_static",
"log", "log",
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
"wasm-bindgen-shared", "wasm-bindgen-shared",
@ -4351,7 +4371,7 @@ version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
"wasm-bindgen-backend", "wasm-bindgen-backend",
@ -4544,7 +4564,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16"
dependencies = [ dependencies = [
"proc-macro2 1.0.26", "proc-macro2 1.0.27",
"quote 1.0.9", "quote 1.0.9",
"syn 1.0.65", "syn 1.0.65",
"synstructure", "synstructure",

View file

@ -9,6 +9,7 @@ import {
assertThrowsAsync, assertThrowsAsync,
deferred, deferred,
delay, delay,
fail,
unitTest, unitTest,
} from "./test_util.ts"; } from "./test_util.ts";
@ -631,3 +632,33 @@ unitTest(
await promise; await promise;
}, },
); );
unitTest({ perms: { net: true } }, async function httpServerWebSocket() {
const promise = (async () => {
const listener = Deno.listen({ port: 4501 });
for await (const conn of listener) {
const httpConn = Deno.serveHttp(conn);
const { request, respondWith } = (await httpConn.nextRequest())!;
const {
response,
websocket,
} = await Deno.upgradeWebSocket(request);
websocket.onerror = () => fail();
websocket.onmessage = (m) => {
websocket.send(m.data);
websocket.close();
};
await respondWith(response);
break;
}
})();
const def = deferred();
const ws = new WebSocket("ws://localhost:4501");
ws.onmessage = (m) => assertEquals(m.data, "foo");
ws.onerror = () => fail();
ws.onclose = () => def.resolve();
ws.onopen = () => ws.send("foo");
await def;
await promise;
});

View file

@ -437,6 +437,7 @@
window.__bootstrap.fetch ??= {}; window.__bootstrap.fetch ??= {};
window.__bootstrap.fetch.Response = Response; window.__bootstrap.fetch.Response = Response;
window.__bootstrap.fetch.newInnerResponse = newInnerResponse;
window.__bootstrap.fetch.toInnerResponse = toInnerResponse; window.__bootstrap.fetch.toInnerResponse = toInnerResponse;
window.__bootstrap.fetch.fromInnerResponse = fromInnerResponse; window.__bootstrap.fetch.fromInnerResponse = fromInnerResponse;
window.__bootstrap.fetch.redirectStatus = redirectStatus; window.__bootstrap.fetch.redirectStatus = redirectStatus;

View file

@ -2,21 +2,34 @@
"use strict"; "use strict";
((window) => { ((window) => {
const webidl = window.__bootstrap.webidl;
const { InnerBody } = window.__bootstrap.fetchBody; const { InnerBody } = window.__bootstrap.fetchBody;
const { Response, fromInnerRequest, toInnerResponse, newInnerRequest } = const { setEventTargetData } = window.__bootstrap.eventTarget;
window.__bootstrap.fetch; const {
Response,
fromInnerRequest,
toInnerResponse,
newInnerRequest,
newInnerResponse,
fromInnerResponse,
} = window.__bootstrap.fetch;
const core = window.Deno.core; const core = window.Deno.core;
const { BadResource, Interrupted } = core; const { BadResource, Interrupted } = core;
const { ReadableStream } = window.__bootstrap.streams; const { ReadableStream } = window.__bootstrap.streams;
const abortSignal = window.__bootstrap.abortSignal; const abortSignal = window.__bootstrap.abortSignal;
const { WebSocket, _rid, _readyState, _eventLoop, _protocol } =
window.__bootstrap.webSocket;
const { const {
Symbol, ArrayPrototypeIncludes,
Uint8Array, ArrayPrototypePush,
Promise, Promise,
StringPrototypeIncludes, StringPrototypeIncludes,
StringPrototypeSplit,
Symbol,
SymbolAsyncIterator, SymbolAsyncIterator,
TypeError,
TypedArrayPrototypeSubarray, TypedArrayPrototypeSubarray,
TypeError,
Uint8Array,
} = window.__bootstrap.primordials; } = window.__bootstrap.primordials;
function serveHttp(conn) { function serveHttp(conn) {
@ -65,7 +78,7 @@
if (nextRequest === null) return null; if (nextRequest === null) return null;
const [ const [
requestBodyRid, requestRid,
responseSenderRid, responseSenderRid,
method, method,
headersList, headersList,
@ -74,8 +87,8 @@
/** @type {ReadableStream<Uint8Array> | undefined} */ /** @type {ReadableStream<Uint8Array> | undefined} */
let body = null; let body = null;
if (typeof requestBodyRid === "number") { if (typeof requestRid === "number") {
body = createRequestBodyStream(requestBodyRid); body = createRequestBodyStream(requestRid);
} }
const innerRequest = newInnerRequest( const innerRequest = newInnerRequest(
@ -87,7 +100,11 @@
const signal = abortSignal.newSignal(); const signal = abortSignal.newSignal();
const request = fromInnerRequest(innerRequest, signal, "immutable"); const request = fromInnerRequest(innerRequest, signal, "immutable");
const respondWith = createRespondWith(this, responseSenderRid); const respondWith = createRespondWith(
this,
responseSenderRid,
requestRid,
);
return { request, respondWith }; return { request, respondWith };
} }
@ -118,7 +135,7 @@
); );
} }
function createRespondWith(httpConn, responseSenderRid) { function createRespondWith(httpConn, responseSenderRid, requestRid) {
return async function respondWith(resp) { return async function respondWith(resp) {
if (resp instanceof Promise) { if (resp instanceof Promise) {
resp = await resp; resp = await resp;
@ -222,10 +239,51 @@
} catch { /* pass */ } } catch { /* pass */ }
} }
} }
const ws = resp[_ws];
if (ws) {
if (typeof requestRid !== "number") {
throw new TypeError(
"This request can not be upgraded to a websocket connection.",
);
}
const wsRid = await core.opAsync(
"op_http_upgrade_websocket",
requestRid,
);
ws[_rid] = wsRid;
ws[_protocol] = resp.headers.get("sec-websocket-protocol");
if (ws[_readyState] === WebSocket.CLOSING) {
await core.opAsync("op_ws_close", { rid: wsRid });
ws[_readyState] = WebSocket.CLOSED;
const errEvent = new ErrorEvent("error");
ws.dispatchEvent(errEvent);
const event = new CloseEvent("close");
ws.dispatchEvent(event);
try {
core.close(wsRid);
} catch (err) {
// Ignore error if the socket has already been closed.
if (!(err instanceof Deno.errors.BadResource)) throw err;
}
} else {
ws[_readyState] = WebSocket.OPEN;
const event = new Event("open");
ws.dispatchEvent(event);
ws[_eventLoop]();
}
}
}; };
} }
function createRequestBodyStream(requestBodyRid) { function createRequestBodyStream(requestRid) {
return new ReadableStream({ return new ReadableStream({
type: "bytes", type: "bytes",
async pull(controller) { async pull(controller) {
@ -234,7 +292,7 @@
// stream. // stream.
const chunk = new Uint8Array(16 * 1024 + 256); const chunk = new Uint8Array(16 * 1024 + 256);
const read = await readRequest( const read = await readRequest(
requestBodyRid, requestRid,
chunk, chunk,
); );
if (read > 0) { if (read > 0) {
@ -243,23 +301,79 @@
} else { } else {
// We have reached the end of the body, so we close the stream. // We have reached the end of the body, so we close the stream.
controller.close(); controller.close();
core.close(requestBodyRid); core.close(requestRid);
} }
} catch (err) { } catch (err) {
// There was an error while reading a chunk of the body, so we // There was an error while reading a chunk of the body, so we
// error. // error.
controller.error(err); controller.error(err);
controller.close(); controller.close();
core.close(requestBodyRid); core.close(requestRid);
} }
}, },
cancel() { cancel() {
core.close(requestBodyRid); core.close(requestRid);
}, },
}); });
} }
const _ws = Symbol("[[associated_ws]]");
function upgradeWebSocket(request, options = {}) {
if (request.headers.get("upgrade") !== "websocket") {
throw new TypeError(
"Invalid Header: 'upgrade' header must be 'websocket'",
);
}
if (request.headers.get("connection") !== "Upgrade") {
throw new TypeError(
"Invalid Header: 'connection' header must be 'Upgrade'",
);
}
const websocketKey = request.headers.get("sec-websocket-key");
if (websocketKey === null) {
throw new TypeError(
"Invalid Header: 'sec-websocket-key' header must be set",
);
}
const accept = core.opSync("op_http_websocket_accept_header", websocketKey);
const r = newInnerResponse(101);
r.headerList = [
["upgrade", "websocket"],
["connection", "Upgrade"],
["sec-websocket-accept", accept],
];
const protocolsStr = request.headers.get("sec-websocket-protocol") || "";
const protocols = StringPrototypeSplit(protocolsStr, ", ");
if (protocols && options.protocol) {
if (ArrayPrototypeIncludes(protocols, options.protocol)) {
ArrayPrototypePush(r.headerList, [
"sec-websocket-protocol",
options.protocol,
]);
} else {
throw new TypeError(
`Protocol '${options.protocol}' not in the request's protocol list (non negotiable)`,
);
}
}
const response = fromInnerResponse(r, "immutable");
const websocket = webidl.createBranded(WebSocket);
setEventTargetData(websocket);
response[_ws] = websocket;
return { response, websocket };
}
window.__bootstrap.http = { window.__bootstrap.http = {
serveHttp, serveHttp,
upgradeWebSocket,
}; };
})(this); })(this);

View file

@ -15,12 +15,15 @@ path = "lib.rs"
[dependencies] [dependencies]
deno_core = { version = "0.92.0", path = "../../core" } deno_core = { version = "0.92.0", path = "../../core" }
deno_websocket = { version = "0.15.0", path = "../websocket" }
base64 = "0.13.0"
bytes = "1" bytes = "1"
log = "0.4.14" log = "0.4.14"
lazy_static = "1.4.0" lazy_static = "1.4.0"
http = "0.2.3" http = "0.2.3"
hyper = { version = "0.14.9", features = ["server", "stream", "http1", "http2", "runtime"] } hyper = { version = "0.14.9", features = ["server", "stream", "http1", "http2", "runtime"] }
ring = "0.16.20"
rustls = "0.19.0" rustls = "0.19.0"
serde = { version = "1.0.125", features = ["derive"] } serde = { version = "1.0.125", features = ["derive"] }
tokio = { version = "1.8.0", features = ["full"] } tokio = { version = "1.8.0", features = ["full"] }

View file

@ -259,4 +259,18 @@ declare namespace Deno {
* then the underlying HttpConn resource is closed automatically. * then the underlying HttpConn resource is closed automatically.
*/ */
export function serveHttp(conn: Conn): HttpConn; export function serveHttp(conn: Conn): HttpConn;
export interface WebSocketUpgrade {
response: Response;
websocket: WebSocket;
}
export interface UpgradeWebSocketOptions {
protocol?: string;
}
export function upgradeWebSocket(
request: Request,
options?: UpgradeWebSocketOptions,
): WebSocketUpgrade;
} }

View file

@ -2,7 +2,6 @@
use crate::io::TcpStreamResource; use crate::io::TcpStreamResource;
use crate::io::TlsStreamResource; use crate::io::TlsStreamResource;
use crate::ops_tls::TlsStream;
use deno_core::error::bad_resource_id; use deno_core::error::bad_resource_id;
use deno_core::error::null_opbuf; use deno_core::error::null_opbuf;
use deno_core::error::type_error; use deno_core::error::type_error;
@ -25,7 +24,6 @@ use deno_core::ResourceId;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
use hyper::body::HttpBody; use hyper::body::HttpBody;
use hyper::http; use hyper::http;
use hyper::server::conn::Connection;
use hyper::server::conn::Http; use hyper::server::conn::Http;
use hyper::service::Service as HyperService; use hyper::service::Service as HyperService;
use hyper::Body; use hyper::Body;
@ -42,7 +40,6 @@ use std::rc::Rc;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
use tokio::net::TcpStream;
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tokio_util::io::StreamReader; use tokio_util::io::StreamReader;
@ -54,6 +51,14 @@ pub fn init() -> Vec<OpPair> {
("op_http_response", op_async(op_http_response)), ("op_http_response", op_async(op_http_response)),
("op_http_response_write", op_async(op_http_response_write)), ("op_http_response_write", op_async(op_http_response_write)),
("op_http_response_close", op_async(op_http_response_close)), ("op_http_response_close", op_async(op_http_response_close)),
(
"op_http_websocket_accept_header",
op_sync(op_http_websocket_accept_header),
),
(
"op_http_upgrade_websocket",
op_async(op_http_upgrade_websocket),
),
] ]
} }
@ -97,13 +102,15 @@ impl HyperService<Request<Body>> for Service {
} }
} }
enum ConnType { type ConnFuture = Pin<Box<dyn Future<Output = hyper::Result<()>>>>;
Tcp(Rc<RefCell<Connection<TcpStream, Service, LocalExecutor>>>),
Tls(Rc<RefCell<Connection<TlsStream, Service, LocalExecutor>>>), struct Conn {
scheme: &'static str,
conn: Rc<RefCell<ConnFuture>>,
} }
struct ConnResource { struct ConnResource {
hyper_connection: ConnType, hyper_connection: Conn,
deno_service: Service, deno_service: Service,
addr: SocketAddr, addr: SocketAddr,
cancel: CancelHandle, cancel: CancelHandle,
@ -112,11 +119,12 @@ struct ConnResource {
impl ConnResource { impl ConnResource {
// TODO(ry) impl Future for ConnResource? // TODO(ry) impl Future for ConnResource?
fn poll(&self, cx: &mut Context<'_>) -> Poll<Result<(), AnyError>> { fn poll(&self, cx: &mut Context<'_>) -> Poll<Result<(), AnyError>> {
match &self.hyper_connection { self
ConnType::Tcp(c) => c.borrow_mut().poll_unpin(cx), .hyper_connection
ConnType::Tls(c) => c.borrow_mut().poll_unpin(cx), .conn
} .borrow_mut()
.map_err(AnyError::from) .poll_unpin(cx)
.map_err(AnyError::from)
} }
} }
@ -134,7 +142,7 @@ impl Resource for ConnResource {
#[derive(Serialize)] #[derive(Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct NextRequestResponse( struct NextRequestResponse(
// request_body_rid: // request_rid:
Option<ResourceId>, Option<ResourceId>,
// response_sender_rid: // response_sender_rid:
ResourceId, ResourceId,
@ -207,12 +215,7 @@ async fn op_http_request_next(
} }
let url = { let url = {
let scheme = { let scheme = &conn_resource.hyper_connection.scheme;
match conn_resource.hyper_connection {
ConnType::Tcp(_) => "http",
ConnType::Tls(_) => "https",
}
};
let host: Cow<str> = if let Some(host) = req.uri().host() { let host: Cow<str> = if let Some(host) = req.uri().host() {
Cow::Borrowed(host) Cow::Borrowed(host)
} else if let Some(host) = req.headers().get("HOST") { } else if let Some(host) = req.headers().get("HOST") {
@ -224,24 +227,35 @@ async fn op_http_request_next(
format!("{}://{}{}", scheme, host, path) format!("{}://{}{}", scheme, host, path)
}; };
let is_websocket_request = req
.headers()
.get(hyper::header::CONNECTION)
.and_then(|v| {
v.to_str().ok().map(|s| "Upgrade".eq_ignore_ascii_case(s))
})
.unwrap_or(false)
&& req
.headers()
.get(hyper::header::UPGRADE)
.and_then(|v| {
v.to_str().ok().map(|s| "websocket".eq_ignore_ascii_case(s))
})
.unwrap_or(false);
let has_body = if let Some(exact_size) = req.size_hint().exact() { let has_body = if let Some(exact_size) = req.size_hint().exact() {
exact_size > 0 exact_size > 0
} else { } else {
true true
}; };
let maybe_request_body_rid = if has_body { let maybe_request_rid = if is_websocket_request || has_body {
let stream: BytesStream = Box::pin(req.into_body().map(|r| {
r.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
}));
let stream_reader = StreamReader::new(stream);
let mut state = state.borrow_mut(); let mut state = state.borrow_mut();
let request_body_rid = state.resource_table.add(RequestBodyResource { let request_rid = state.resource_table.add(RequestResource {
conn_rid, conn_rid,
reader: AsyncRefCell::new(stream_reader), inner: AsyncRefCell::new(RequestOrStreamReader::Request(Some(req))),
cancel: CancelHandle::default(), cancel: CancelHandle::default(),
}); });
Some(request_body_rid) Some(request_rid)
} else { } else {
None None
}; };
@ -254,7 +268,7 @@ async fn op_http_request_next(
}); });
Poll::Ready(Ok(Some(NextRequestResponse( Poll::Ready(Ok(Some(NextRequestResponse(
maybe_request_body_rid, maybe_request_rid,
response_sender_rid, response_sender_rid,
method, method,
headers, headers,
@ -303,9 +317,14 @@ fn op_http_start(
let addr = tcp_stream.local_addr()?; let addr = tcp_stream.local_addr()?;
let hyper_connection = Http::new() let hyper_connection = Http::new()
.with_executor(LocalExecutor) .with_executor(LocalExecutor)
.serve_connection(tcp_stream, deno_service.clone()); .serve_connection(tcp_stream, deno_service.clone())
.with_upgrades();
let conn = Pin::new(Box::new(hyper_connection));
let conn_resource = ConnResource { let conn_resource = ConnResource {
hyper_connection: ConnType::Tcp(Rc::new(RefCell::new(hyper_connection))), hyper_connection: Conn {
conn: Rc::new(RefCell::new(conn)),
scheme: "http",
},
deno_service, deno_service,
addr, addr,
cancel: CancelHandle::default(), cancel: CancelHandle::default(),
@ -326,9 +345,14 @@ fn op_http_start(
let hyper_connection = Http::new() let hyper_connection = Http::new()
.with_executor(LocalExecutor) .with_executor(LocalExecutor)
.serve_connection(tls_stream, deno_service.clone()); .serve_connection(tls_stream, deno_service.clone())
.with_upgrades();
let conn = Pin::new(Box::new(hyper_connection));
let conn_resource = ConnResource { let conn_resource = ConnResource {
hyper_connection: ConnType::Tls(Rc::new(RefCell::new(hyper_connection))), hyper_connection: Conn {
conn: Rc::new(RefCell::new(conn)),
scheme: "https",
},
deno_service, deno_service,
addr, addr,
cancel: CancelHandle::default(), cancel: CancelHandle::default(),
@ -367,10 +391,12 @@ async fn op_http_response(
.ok() .ok()
.expect("multiple op_http_respond ongoing"); .expect("multiple op_http_respond ongoing");
let conn_rid = response_sender.conn_rid;
let conn_resource = state let conn_resource = state
.borrow() .borrow()
.resource_table .resource_table
.get::<ConnResource>(response_sender.conn_rid) .get::<ConnResource>(conn_rid)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let mut builder = Response::builder().status(status); let mut builder = Response::builder().status(status);
@ -393,7 +419,7 @@ async fn op_http_response(
let response_body_rid = let response_body_rid =
state.borrow_mut().resource_table.add(ResponseBodyResource { state.borrow_mut().resource_table.add(ResponseBodyResource {
body: AsyncRefCell::new(sender), body: AsyncRefCell::new(sender),
conn_rid: response_sender.conn_rid, conn_rid,
}); });
Some(response_body_rid) Some(response_body_rid)
@ -407,7 +433,10 @@ async fn op_http_response(
} }
poll_fn(|cx| match conn_resource.poll(cx) { poll_fn(|cx| match conn_resource.poll(cx) {
Poll::Ready(x) => Poll::Ready(x), Poll::Ready(x) => {
state.borrow_mut().resource_table.close(conn_rid);
Poll::Ready(x)
}
Poll::Pending => Poll::Ready(Ok(())), Poll::Pending => Poll::Ready(Ok(())),
}) })
.await?; .await?;
@ -455,7 +484,7 @@ async fn op_http_request_read(
let resource = state let resource = state
.borrow() .borrow()
.resource_table .resource_table
.get::<RequestBodyResource>(rid as u32) .get::<RequestResource>(rid as u32)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let conn_resource = state let conn_resource = state
@ -464,8 +493,26 @@ async fn op_http_request_read(
.get::<ConnResource>(resource.conn_rid) .get::<ConnResource>(resource.conn_rid)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let mut reader = RcRef::map(&resource, |r| &r.reader).borrow_mut().await; let mut inner = RcRef::map(resource.clone(), |r| &r.inner)
.borrow_mut()
.await;
if let RequestOrStreamReader::Request(req) = &mut *inner {
let req = req.take().unwrap();
let stream: BytesStream = Box::pin(req.into_body().map(|r| {
r.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
}));
let reader = StreamReader::new(stream);
*inner = RequestOrStreamReader::StreamReader(reader);
};
let reader = match &mut *inner {
RequestOrStreamReader::StreamReader(reader) => reader,
_ => unreachable!(),
};
let cancel = RcRef::map(resource, |r| &r.cancel); let cancel = RcRef::map(resource, |r| &r.cancel);
let mut read_fut = reader.read(&mut data).try_or_cancel(cancel).boxed_local(); let mut read_fut = reader.read(&mut data).try_or_cancel(cancel).boxed_local();
poll_fn(|cx| { poll_fn(|cx| {
@ -521,18 +568,77 @@ async fn op_http_response_write(
Ok(()) Ok(())
} }
fn op_http_websocket_accept_header(
_: &mut OpState,
key: String,
_: (),
) -> Result<String, AnyError> {
let digest = ring::digest::digest(
&ring::digest::SHA1_FOR_LEGACY_USE_ONLY,
format!("{}258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key).as_bytes(),
);
Ok(base64::encode(digest))
}
async fn op_http_upgrade_websocket(
state: Rc<RefCell<OpState>>,
rid: ResourceId,
_: (),
) -> Result<ResourceId, AnyError> {
let req_resource = state
.borrow_mut()
.resource_table
.take::<RequestResource>(rid)
.ok_or_else(bad_resource_id)?;
let mut inner = RcRef::map(&req_resource, |r| &r.inner).borrow_mut().await;
if let RequestOrStreamReader::Request(req) = inner.as_mut() {
let upgraded = hyper::upgrade::on(req.as_mut().unwrap()).await?;
let stream =
deno_websocket::tokio_tungstenite::WebSocketStream::from_raw_socket(
upgraded,
deno_websocket::tokio_tungstenite::tungstenite::protocol::Role::Server,
None,
)
.await;
let (ws_tx, ws_rx) = stream.split();
let rid =
state
.borrow_mut()
.resource_table
.add(deno_websocket::WsStreamResource {
stream: deno_websocket::WebSocketStreamType::Server {
rx: AsyncRefCell::new(ws_rx),
tx: AsyncRefCell::new(ws_tx),
},
cancel: Default::default(),
});
Ok(rid)
} else {
Err(bad_resource_id())
}
}
type BytesStream = type BytesStream =
Pin<Box<dyn Stream<Item = std::io::Result<bytes::Bytes>> + Unpin>>; Pin<Box<dyn Stream<Item = std::io::Result<bytes::Bytes>> + Unpin>>;
struct RequestBodyResource { enum RequestOrStreamReader {
Request(Option<Request<hyper::Body>>),
StreamReader(StreamReader<BytesStream, bytes::Bytes>),
}
struct RequestResource {
conn_rid: ResourceId, conn_rid: ResourceId,
reader: AsyncRefCell<StreamReader<BytesStream, bytes::Bytes>>, inner: AsyncRefCell<RequestOrStreamReader>,
cancel: CancelHandle, cancel: CancelHandle,
} }
impl Resource for RequestBodyResource { impl Resource for RequestResource {
fn name(&self) -> Cow<str> { fn name(&self) -> Cow<str> {
"requestBody".into() "request".into()
} }
fn close(self: Rc<Self>) { fn close(self: Rc<Self>) {

View file

@ -124,6 +124,7 @@
const _protocol = Symbol("[[protocol]]"); const _protocol = Symbol("[[protocol]]");
const _binaryType = Symbol("[[binaryType]]"); const _binaryType = Symbol("[[binaryType]]");
const _bufferedAmount = Symbol("[[bufferedAmount]]"); const _bufferedAmount = Symbol("[[bufferedAmount]]");
const _eventLoop = Symbol("[[eventLoop]]");
class WebSocket extends EventTarget { class WebSocket extends EventTarget {
[_rid]; [_rid];
@ -294,7 +295,7 @@
const event = new Event("open"); const event = new Event("open");
this.dispatchEvent(event); this.dispatchEvent(event);
this.#eventLoop(); this[_eventLoop]();
} }
}, },
(err) => { (err) => {
@ -427,7 +428,7 @@
} }
} }
async #eventLoop() { async [_eventLoop]() {
while (this[_readyState] === OPEN) { while (this[_readyState] === OPEN) {
const { kind, value } = await core.opAsync( const { kind, value } = await core.opAsync(
"op_ws_next_event", "op_ws_next_event",
@ -518,5 +519,11 @@
webidl.configurePrototype(WebSocket); webidl.configurePrototype(WebSocket);
window.__bootstrap.webSocket = { WebSocket }; window.__bootstrap.webSocket = {
WebSocket,
_rid,
_readyState,
_eventLoop,
_protocol,
};
})(this); })(this);

View file

@ -20,5 +20,6 @@ serde = { version = "1.0.125", features = ["derive"] }
tokio = { version = "1.8.0", features = ["full"] } tokio = { version = "1.8.0", features = ["full"] }
tokio-rustls = "0.22.0" tokio-rustls = "0.22.0"
tokio-tungstenite = { version = "0.14.0", features = ["rustls-tls"] } tokio-tungstenite = { version = "0.14.0", features = ["rustls-tls"] }
hyper = { version = "0.14.9" }
webpki = "0.21.4" webpki = "0.21.4"
webpki-roots = "0.21.1" webpki-roots = "0.21.1"

View file

@ -64,13 +64,81 @@ impl WebSocketPermissions for NoWebSocketPermissions {
} }
type WsStream = WebSocketStream<MaybeTlsStream<TcpStream>>; type WsStream = WebSocketStream<MaybeTlsStream<TcpStream>>;
struct WsStreamResource { pub enum WebSocketStreamType {
tx: AsyncRefCell<SplitSink<WsStream, Message>>, Client {
rx: AsyncRefCell<SplitStream<WsStream>>, tx: AsyncRefCell<SplitSink<WsStream, Message>>,
rx: AsyncRefCell<SplitStream<WsStream>>,
},
Server {
tx: AsyncRefCell<
SplitSink<WebSocketStream<hyper::upgrade::Upgraded>, Message>,
>,
rx: AsyncRefCell<SplitStream<WebSocketStream<hyper::upgrade::Upgraded>>>,
},
}
pub struct WsStreamResource {
pub stream: WebSocketStreamType,
// When a `WsStreamResource` resource is closed, all pending 'read' ops are // When a `WsStreamResource` resource is closed, all pending 'read' ops are
// canceled, while 'write' ops are allowed to complete. Therefore only // canceled, while 'write' ops are allowed to complete. Therefore only
// 'read' futures are attached to this cancel handle. // 'read' futures are attached to this cancel handle.
cancel: CancelHandle, pub cancel: CancelHandle,
}
impl WsStreamResource {
async fn send(self: &Rc<Self>, message: Message) -> Result<(), AnyError> {
match self.stream {
WebSocketStreamType::Client { .. } => {
let mut tx = RcRef::map(self, |r| match &r.stream {
WebSocketStreamType::Client { tx, .. } => tx,
WebSocketStreamType::Server { .. } => unreachable!(),
})
.borrow_mut()
.await;
tx.send(message).await?;
}
WebSocketStreamType::Server { .. } => {
let mut tx = RcRef::map(self, |r| match &r.stream {
WebSocketStreamType::Client { .. } => unreachable!(),
WebSocketStreamType::Server { tx, .. } => tx,
})
.borrow_mut()
.await;
tx.send(message).await?;
}
}
Ok(())
}
async fn next_message(
self: &Rc<Self>,
cancel: RcRef<CancelHandle>,
) -> Result<
Option<Result<Message, tokio_tungstenite::tungstenite::Error>>,
AnyError,
> {
match &self.stream {
WebSocketStreamType::Client { .. } => {
let mut rx = RcRef::map(self, |r| match &r.stream {
WebSocketStreamType::Client { rx, .. } => rx,
WebSocketStreamType::Server { .. } => unreachable!(),
})
.borrow_mut()
.await;
rx.next().or_cancel(cancel).await.map_err(AnyError::from)
}
WebSocketStreamType::Server { .. } => {
let mut rx = RcRef::map(self, |r| match &r.stream {
WebSocketStreamType::Client { .. } => unreachable!(),
WebSocketStreamType::Server { rx, .. } => rx,
})
.borrow_mut()
.await;
rx.next().or_cancel(cancel).await.map_err(AnyError::from)
}
}
}
} }
impl Resource for WsStreamResource { impl Resource for WsStreamResource {
@ -79,8 +147,6 @@ impl Resource for WsStreamResource {
} }
} }
impl WsStreamResource {}
// This op is needed because creating a WS instance in JavaScript is a sync // This op is needed because creating a WS instance in JavaScript is a sync
// operation and should throw error when permissions are not fulfilled, // operation and should throw error when permissions are not fulfilled,
// but actual op that connects WS is async. // but actual op that connects WS is async.
@ -184,8 +250,10 @@ where
let (ws_tx, ws_rx) = stream.split(); let (ws_tx, ws_rx) = stream.split();
let resource = WsStreamResource { let resource = WsStreamResource {
rx: AsyncRefCell::new(ws_rx), stream: WebSocketStreamType::Client {
tx: AsyncRefCell::new(ws_tx), rx: AsyncRefCell::new(ws_rx),
tx: AsyncRefCell::new(ws_tx),
},
cancel: Default::default(), cancel: Default::default(),
}; };
let mut state = state.borrow_mut(); let mut state = state.borrow_mut();
@ -227,15 +295,13 @@ pub async fn op_ws_send(
"pong" => Message::Pong(vec![]), "pong" => Message::Pong(vec![]),
_ => unreachable!(), _ => unreachable!(),
}; };
let rid = args.rid;
let resource = state let resource = state
.borrow_mut() .borrow_mut()
.resource_table .resource_table
.get::<WsStreamResource>(rid) .get::<WsStreamResource>(args.rid)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let mut tx = RcRef::map(&resource, |r| &r.tx).borrow_mut().await; resource.send(msg).await?;
tx.send(msg).await?;
Ok(()) Ok(())
} }
@ -266,8 +332,7 @@ pub async fn op_ws_close(
.resource_table .resource_table
.get::<WsStreamResource>(rid) .get::<WsStreamResource>(rid)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let mut tx = RcRef::map(&resource, |r| &r.tx).borrow_mut().await; resource.send(msg).await?;
tx.send(msg).await?;
Ok(()) Ok(())
} }
@ -294,9 +359,8 @@ pub async fn op_ws_next_event(
.get::<WsStreamResource>(rid) .get::<WsStreamResource>(rid)
.ok_or_else(bad_resource_id)?; .ok_or_else(bad_resource_id)?;
let mut rx = RcRef::map(&resource, |r| &r.rx).borrow_mut().await; let cancel = RcRef::map(&resource, |r| &r.cancel);
let cancel = RcRef::map(resource, |r| &r.cancel); let val = resource.next_message(cancel).await?;
let val = rx.next().or_cancel(cancel).await?;
let res = match val { let res = match val {
Some(Ok(Message::Text(text))) => NextEventResponse::String(text), Some(Ok(Message::Text(text))) => NextEventResponse::String(text),
Some(Ok(Message::Binary(data))) => NextEventResponse::Binary(data.into()), Some(Ok(Message::Binary(data))) => NextEventResponse::Binary(data.into()),

View file

@ -128,6 +128,7 @@
serveHttp: __bootstrap.http.serveHttp, serveHttp: __bootstrap.http.serveHttp,
startTls: __bootstrap.tls.startTls, startTls: __bootstrap.tls.startTls,
umask: __bootstrap.fs.umask, umask: __bootstrap.fs.umask,
upgradeWebSocket: __bootstrap.http.upgradeWebSocket,
futime: __bootstrap.fs.futime, futime: __bootstrap.fs.futime,
futimeSync: __bootstrap.fs.futimeSync, futimeSync: __bootstrap.fs.futimeSync,
utime: __bootstrap.fs.utime, utime: __bootstrap.fs.utime,