diff options
author | Yosi Pramajaya <yosi.pramajaya@gmail.com> | 2020-12-24 20:11:32 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-24 14:11:32 +0100 |
commit | b15539587e7cf6b67c2ae7d4dc39901634bf6bd5 (patch) | |
tree | 7629bd4263553534f5305f288dc2e9ae192ffea2 | |
parent | a4d557126e49108db4c0dc42561ae032d2418b04 (diff) |
refactor(test_util): replace "warp" with "hyper" (#8846)
This commit rewrites "test_server" to use "hyper"
instead of "warp" in an effort to reduce number of
dependencies.
-rw-r--r-- | Cargo.lock | 374 | ||||
-rw-r--r-- | cli/tests/websocket_test.ts | 4 | ||||
-rw-r--r-- | test_util/Cargo.toml | 4 | ||||
-rw-r--r-- | test_util/src/lib.rs | 847 |
4 files changed, 599 insertions, 630 deletions
diff --git a/Cargo.lock b/Cargo.lock index 1ffadabe9..0f8f99773 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,12 +146,6 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" @@ -176,32 +170,11 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.3", -] - -[[package]] -name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "generic-array", ] [[package]] @@ -226,16 +199,6 @@ dependencies = [ ] [[package]] -name = "buf_redux" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] - -[[package]] name = "build_const" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -248,12 +211,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -323,15 +280,6 @@ dependencies = [ [[package]] name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "cloudabi" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" @@ -399,7 +347,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.1", + "autocfg", "cfg-if 0.1.10", "lazy_static", ] @@ -531,7 +479,7 @@ name = "deno_crypto" version = "0.8.0" dependencies = [ "deno_core", - "rand 0.7.3", + "rand", ] [[package]] @@ -642,20 +590,11 @@ dependencies = [ [[package]] name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.3", -] - -[[package]] -name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -797,12 +736,6 @@ dependencies = [ ] [[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] name = "filetime" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -880,12 +813,6 @@ dependencies = [ ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1023,15 +950,6 @@ checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" [[package]] name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" @@ -1077,31 +995,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7" [[package]] -name = "headers" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f" -dependencies = [ - "base64 0.12.3", - "bitflags", - "bytes 0.5.6", - "headers-core", - "http", - "mime", - "sha-1 0.8.2", - "time", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1230,7 +1123,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" dependencies = [ - "autocfg 1.0.1", + "autocfg", "hashbrown", ] @@ -1481,7 +1374,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" dependencies = [ "adler", - "autocfg 1.0.1", + "autocfg", ] [[package]] @@ -1574,24 +1467,6 @@ dependencies = [ ] [[package]] -name = "multipart" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8209c33c951f07387a8497841122fc6f712165e3f9bda3e6be4645b58188f676" -dependencies = [ - "buf_redux", - "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand 0.6.5", - "safemem", - "tempfile", - "twoway", -] - -[[package]] name = "net2" version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1666,7 +1541,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.1", + "autocfg", "num-integer", "num-traits", "serde", @@ -1678,7 +1553,7 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ - "autocfg 1.0.1", + "autocfg", "num-traits", ] @@ -1688,7 +1563,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ - "autocfg 1.0.1", + "autocfg", ] [[package]] @@ -1709,12 +1584,6 @@ checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" [[package]] name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" @@ -1765,7 +1634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ "cfg-if 0.1.10", - "cloudabi 0.1.0", + "cloudabi", "instant", "libc", "redox_syscall", @@ -1807,7 +1676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared", - "rand 0.7.3", + "rand", ] [[package]] @@ -2010,45 +1879,16 @@ checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" [[package]] name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.7", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg 0.1.2", - "rand_xorshift", - "winapi 0.3.9", -] - -[[package]] -name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", + "rand_chacha", + "rand_core", + "rand_hc", + "rand_pcg", ] [[package]] @@ -2058,26 +1898,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", + "rand_core", ] [[package]] name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" @@ -2087,64 +1912,11 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi 0.0.3", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", + "rand_core", ] [[package]] @@ -2153,25 +1925,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", + "rand_core", ] [[package]] @@ -2343,12 +2097,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2457,27 +2205,15 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha-1" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" dependencies = [ - "block-buffer 0.9.0", + "block-buffer", "cfg-if 0.1.10", "cpuid-bool", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest", + "opaque-debug", ] [[package]] @@ -2924,7 +2660,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if 0.1.10", "libc", - "rand 0.7.3", + "rand", "redox_syscall", "remove_dir_all", "winapi 0.3.9", @@ -2954,13 +2690,15 @@ version = "0.1.0" dependencies = [ "bytes 0.5.6", "futures", + "hyper", "lazy_static", "os_pipe", "pty", "regex", "tempfile", "tokio 0.2.22", - "warp", + "tokio-rustls", + "tokio-tungstenite", ] [[package]] @@ -3048,7 +2786,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a12a3eb39ee2c231be64487f1fcbe726c8f2514876a55480a5ab8559fc374252" dependencies = [ - "autocfg 1.0.1", + "autocfg", "bytes 0.6.0", "futures-core", "lazy_static", @@ -3192,16 +2930,6 @@ dependencies = [ ] [[package]] -name = "tracing-futures" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" -dependencies = [ - "pin-project 0.4.23", - "tracing", -] - -[[package]] name = "try-lock" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3220,22 +2948,13 @@ dependencies = [ "httparse", "input_buffer", "log", - "rand 0.7.3", - "sha-1 0.9.1", + "rand", + "sha-1", "url", "utf-8", ] [[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr", -] - -[[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3311,12 +3030,6 @@ dependencies = [ ] [[package]] -name = "urlencoding" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9232eb53352b4442e40d7900465dfc534e8cb2dc8f18656fcb2ac16112b5593" - -[[package]] name = "utf-8" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3334,7 +3047,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" dependencies = [ - "rand 0.7.3", + "rand", ] [[package]] @@ -3371,35 +3084,6 @@ dependencies = [ ] [[package]] -name = "warp" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41be6df54c97904af01aa23e613d4521eed7ab23537cede692d4058f6449407" -dependencies = [ - "bytes 0.5.6", - "futures", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "multipart", - "pin-project 0.4.23", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio 0.2.22", - "tokio-rustls", - "tokio-tungstenite", - "tower-service", - "tracing", - "tracing-futures", - "urlencoding", -] - -[[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/cli/tests/websocket_test.ts b/cli/tests/websocket_test.ts index 51876dc59..a220b37ea 100644 --- a/cli/tests/websocket_test.ts +++ b/cli/tests/websocket_test.ts @@ -159,7 +159,9 @@ Deno.test("websocket error", async () => { ws.onopen = () => fail(); ws.onerror = (err): void => { assert(err instanceof ErrorEvent); - assertEquals(err.message, "InvalidData: received corrupt message"); + + // Error message got changed because we don't use warp in test_util + assertEquals(err.message, "UnexpectedEof: tls handshake eof"); promise1.resolve(); }; await promise1; diff --git a/test_util/Cargo.toml b/test_util/Cargo.toml index fefe7f3d8..6eee12ebc 100644 --- a/test_util/Cargo.toml +++ b/test_util/Cargo.toml @@ -19,7 +19,9 @@ lazy_static = "1.4.0" os_pipe = "0.9.2" regex = "1.3.9" tempfile = "3.1.0" -warp = { version = "0.2.5", features = ["tls"] } +hyper = "0.13" +tokio-tungstenite = "0.11" +tokio-rustls = "0.14" [target.'cfg(unix)'.dependencies] pty = "0.2.2" diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs index 8a47eb139..dbb184fed 100644 --- a/test_util/src/lib.rs +++ b/test_util/src/lib.rs @@ -5,32 +5,47 @@ #[macro_use] extern crate lazy_static; -use futures::future::{self, FutureExt}; +use futures::FutureExt; +use futures::Stream; +use futures::StreamExt; +use futures::TryStreamExt; +use hyper::header::HeaderValue; +use hyper::service::make_service_fn; +use hyper::service::service_fn; +use hyper::Body; +use hyper::Request; +use hyper::Response; +use hyper::Server; +use hyper::StatusCode; use os_pipe::pipe; #[cfg(unix)] pub use pty; use regex::Regex; use std::collections::HashMap; use std::env; +use std::io; use std::io::Read; use std::io::Write; use std::mem::replace; +use std::net::SocketAddr; use std::path::PathBuf; +use std::pin::Pin; use std::process::Child; use std::process::Command; use std::process::Output; use std::process::Stdio; +use std::result::Result; +use std::sync::Arc; use std::sync::Mutex; use std::sync::MutexGuard; +use std::task::Context; +use std::task::Poll; use tempfile::TempDir; -use warp::http::HeaderValue; -use warp::http::Response; -use warp::http::StatusCode; -use warp::http::Uri; -use warp::hyper::Body; -use warp::reply::with_header; -use warp::reply::Reply; -use warp::Filter; +use tokio::net::TcpListener; +use tokio::net::TcpStream; +use tokio_rustls::rustls; +use tokio_rustls::TlsAcceptor; +use tokio_tungstenite::accept_async; const PORT: u16 = 4545; const REDIRECT_PORT: u16 = 4546; @@ -117,132 +132,225 @@ pub fn test_server_path() -> PathBuf { /// Benchmark server that just serves "hello world" responses. async fn hyper_hello(port: u16) { println!("hyper hello"); - let route = warp::any().map(|| "Hello World!"); - warp::serve(route).bind(([127, 0, 0, 1], port)).await; + let addr = SocketAddr::from(([127, 0, 0, 1], port)); + let hello_svc = make_service_fn(|_| async move { + Ok::<_, hyper::error::Error>(service_fn( + move |_: Request<Body>| async move { + Ok::<_, hyper::error::Error>(Response::new(Body::from("Hello World!"))) + }, + )) + }); + + let server = Server::bind(&addr).serve(hello_svc); + if let Err(e) = server.await { + eprintln!("server error: {}", e); + } } -#[tokio::main] -pub async fn run_all_servers() { - if let Some(port) = env::args().nth(1) { - return hyper_hello(port.parse::<u16>().unwrap()).await; +fn redirect_resp(url: String) -> Response<Body> { + let mut redirect_resp = Response::new(Body::empty()); + *redirect_resp.status_mut() = StatusCode::MOVED_PERMANENTLY; + redirect_resp.headers_mut().insert( + hyper::header::LOCATION, + HeaderValue::from_str(&url[..]).unwrap(), + ); + + redirect_resp +} + +async fn redirect(req: Request<Body>) -> hyper::Result<Response<Body>> { + let p = req.uri().path(); + assert_eq!(&p[0..1], "/"); + let url = format!("http://localhost:{}{}", PORT, p); + + Ok(redirect_resp(url)) +} + +async fn double_redirects(req: Request<Body>) -> hyper::Result<Response<Body>> { + let p = req.uri().path(); + assert_eq!(&p[0..1], "/"); + let url = format!("http://localhost:{}{}", REDIRECT_PORT, p); + + Ok(redirect_resp(url)) +} + +async fn inf_redirects(req: Request<Body>) -> hyper::Result<Response<Body>> { + let p = req.uri().path(); + assert_eq!(&p[0..1], "/"); + let url = format!("http://localhost:{}{}", INF_REDIRECTS_PORT, p); + + Ok(redirect_resp(url)) +} + +async fn another_redirect(req: Request<Body>) -> hyper::Result<Response<Body>> { + let p = req.uri().path(); + assert_eq!(&p[0..1], "/"); + let url = format!("http://localhost:{}/cli/tests/subdir{}", PORT, p); + + Ok(redirect_resp(url)) +} + +async fn run_ws_server(addr: &SocketAddr) { + let mut listener = TcpListener::bind(addr).await.unwrap(); + while let Ok((stream, _addr)) = listener.accept().await { + tokio::spawn(async move { + let ws_stream_fut = accept_async(stream); + + let ws_stream = ws_stream_fut.await; + if let Ok(ws_stream) = ws_stream { + let (tx, rx) = ws_stream.split(); + rx.forward(tx) + .map(|result| { + if let Err(e) = result { + println!("websocket server error: {:?}", e); + } + }) + .await; + } + }); } +} - let routes = warp::path::full().map(|path: warp::path::FullPath| { - let p = path.as_str(); - assert_eq!(&p[0..1], "/"); - let url = format!("http://localhost:{}{}", PORT, p); - let u = url.parse::<Uri>().unwrap(); - warp::redirect(u) - }); - let redirect_server_fut = - warp::serve(routes).bind(([127, 0, 0, 1], REDIRECT_PORT)); - - let websocket_route = warp::ws().map(|ws: warp::ws::Ws| { - ws.on_upgrade(|websocket| { - use futures::stream::StreamExt; - let (tx, rx) = websocket.split(); - rx.forward(tx).map(|result| { - if let Err(e) = result { - println!("websocket server error: {:?}", e); - } - }) - }) - }); - let ws_server_fut = - warp::serve(websocket_route).bind(([127, 0, 0, 1], WS_PORT)); - let wss_server_fut = warp::serve(websocket_route) - .tls() - .cert_path("std/http/testdata/tls/localhost.crt") - .key_path("std/http/testdata/tls/localhost.key") - .bind(([127, 0, 0, 1], WSS_PORT)); - - let routes = warp::path::full().map(|path: warp::path::FullPath| { - let p = path.as_str(); - assert_eq!(&p[0..1], "/"); - let url = format!("http://localhost:{}/cli/tests/subdir{}", PORT, p); - let u = url.parse::<Uri>().unwrap(); - warp::redirect(u) - }); - let another_redirect_server_fut = - warp::serve(routes).bind(([127, 0, 0, 1], ANOTHER_REDIRECT_PORT)); - - let routes = warp::path::full().map(|path: warp::path::FullPath| { - let p = path.as_str(); - assert_eq!(&p[0..1], "/"); - let url = format!("http://localhost:{}{}", REDIRECT_PORT, p); - let u = url.parse::<Uri>().unwrap(); - warp::redirect(u) - }); - let double_redirect_server_fut = - warp::serve(routes).bind(([127, 0, 0, 1], DOUBLE_REDIRECTS_PORT)); - - let routes = warp::path::full().map(|path: warp::path::FullPath| { - let p = path.as_str(); - assert_eq!(&p[0..1], "/"); - let url = format!("http://localhost:{}{}", INF_REDIRECTS_PORT, p); - let u = url.parse::<Uri>().unwrap(); - warp::redirect(u) - }); - let inf_redirect_server_fut = - warp::serve(routes).bind(([127, 0, 0, 1], INF_REDIRECTS_PORT)); - - // redirect server that redirect to absolute paths under same host - // redirects /REDIRECT/file_name to /file_name - let routes = warp::path("REDIRECT") - .and(warp::path::peek()) - .map(|path: warp::path::Peek| { - let p = path.as_str(); - let url = format!("/{}", p); - let u = url.parse::<Uri>().unwrap(); - warp::redirect(u) - }) - .or( - warp::path!("a" / "b" / "c") - .and(warp::header::<String>("x-location")) - .map(|token: String| { - let uri: Uri = token.parse().unwrap(); - warp::redirect(uri) - }), - ) - .or( - warp::any() - .and(warp::path::peek()) - .and(warp::fs::dir(root_path())) - .map(custom_headers), - ); - let absolute_redirect_server_fut = - warp::serve(routes).bind(([127, 0, 0, 1], REDIRECT_ABSOLUTE_PORT)); - - let echo_server = warp::path("echo_server") - .and(warp::post()) - .and(warp::body::bytes()) - .and(warp::header::optional::<String>("x-status")) - .and(warp::header::optional::<String>("content-type")) - .and(warp::header::optional::<String>("user-agent")) - .map( - |bytes: bytes::Bytes, - status: Option<String>, - content_type: Option<String>, - user_agent: Option<String>| - -> Box<dyn Reply> { - let mut res = Response::new(Body::from(bytes)); - if let Some(v) = status { - *res.status_mut() = StatusCode::from_bytes(v.as_bytes()).unwrap(); - } - let h = res.headers_mut(); - if let Some(v) = content_type { - h.insert("content-type", HeaderValue::from_str(&v).unwrap()); +async fn get_tls_config( + cert: &str, + key: &str, +) -> io::Result<Arc<rustls::ServerConfig>> { + let mut cert_path = root_path(); + let mut key_path = root_path(); + cert_path.push(cert); + key_path.push(key); + + let cert_file = std::fs::File::open(cert_path)?; + let key_file = std::fs::File::open(key_path)?; + + let mut cert_reader = io::BufReader::new(cert_file); + let cert = rustls::internal::pemfile::certs(&mut cert_reader) + .expect("Cannot load certificate"); + let mut key_reader = io::BufReader::new(key_file); + let key = { + let pkcs8_key = + rustls::internal::pemfile::pkcs8_private_keys(&mut key_reader) + .expect("Cannot load key file"); + let rsa_key = rustls::internal::pemfile::rsa_private_keys(&mut key_reader) + .expect("Cannot load key file"); + if !pkcs8_key.is_empty() { + Some(pkcs8_key[0].clone()) + } else if !rsa_key.is_empty() { + Some(rsa_key[0].clone()) + } else { + None + } + }; + + match key { + Some(key) => { + let mut config = rustls::ServerConfig::new(rustls::NoClientAuth::new()); + config + .set_single_cert(cert, key) + .map_err(|e| { + eprintln!("Error setting cert: {:?}", e); + }) + .unwrap(); + + return Ok(Arc::new(config)); + } + None => { + return Err(io::Error::new(io::ErrorKind::Other, "Cannot find key")); + } + } +} + +async fn run_wss_server(addr: &SocketAddr) { + let cert_file = "std/http/testdata/tls/localhost.crt"; + let key_file = "std/http/testdata/tls/localhost.key"; + + let tls_config = get_tls_config(cert_file, key_file).await.unwrap(); + let tls_acceptor = TlsAcceptor::from(tls_config); + let mut listener = TcpListener::bind(addr).await.unwrap(); + + while let Ok((stream, _addr)) = listener.accept().await { + let acceptor = tls_acceptor.clone(); + tokio::spawn(async move { + match acceptor.accept(stream).await { + Ok(tls_stream) => { + let ws_stream_fut = accept_async(tls_stream); + let ws_stream = ws_stream_fut.await; + if let Ok(ws_stream) = ws_stream { + let (tx, rx) = ws_stream.split(); + rx.forward(tx) + .map(|result| { + if let Err(e) = result { + println!("Websocket server error: {:?}", e); + } + }) + .await; + } } - if let Some(v) = user_agent { - h.insert("user-agent", HeaderValue::from_str(&v).unwrap()); + Err(e) => { + eprintln!("TLS accept error: {:?}", e); } - Box::new(res) - }, - ); - let echo_multipart_file = warp::path("echo_multipart_file") - .and(warp::post()) - .and(warp::body::bytes()) - .map(|bytes: bytes::Bytes| -> Box<dyn Reply> { + } + }); + } +} + +async fn absolute_redirect( + req: Request<Body>, +) -> hyper::Result<Response<Body>> { + let path = req.uri().path(); + + if path.starts_with("/REDIRECT") { + let url = &req.uri().path()[9..]; + println!("URL: {:?}", url); + let redirect = redirect_resp(url.to_string()); + return Ok(redirect); + } + + if path.starts_with("/a/b/c") { + if let Some(x_loc) = req.headers().get("x-location") { + let loc = x_loc.to_str().unwrap(); + return Ok(redirect_resp(loc.to_string())); + } + } + + let mut file_path = root_path(); + file_path.push(&req.uri().path()[1..]); + if file_path.is_dir() || !file_path.exists() { + let mut not_found_resp = Response::new(Body::empty()); + *not_found_resp.status_mut() = StatusCode::NOT_FOUND; + return Ok(not_found_resp); + } + + let file = tokio::fs::read(file_path).await.unwrap(); + let file_resp = custom_headers(req.uri().path(), file); + return Ok(file_resp); +} + +async fn main_server(req: Request<Body>) -> hyper::Result<Response<Body>> { + return match (req.method(), req.uri().path()) { + (&hyper::Method::POST, "/echo_server") => { + let (parts, body) = req.into_parts(); + let mut response = Response::new(body); + + if let Some(status) = parts.headers.get("x-status") { + *response.status_mut() = + StatusCode::from_bytes(status.as_bytes()).unwrap(); + } + if let Some(content_type) = parts.headers.get("content-type") { + response + .headers_mut() + .insert("content-type", content_type.clone()); + } + if let Some(user_agent) = parts.headers.get("user-agent") { + response + .headers_mut() + .insert("user-agent", user_agent.clone()); + } + Ok(response) + } + (&hyper::Method::POST, "/echo_multipart_file") => { + let body = req.into_body(); + let bytes = &hyper::body::to_bytes(body).await.unwrap()[0..]; let start = b"--boundary\t \r\n\ Content-Disposition: form-data; name=\"field_1\"\r\n\ \r\n\ @@ -253,236 +361,383 @@ pub async fn run_all_servers() { Content-Type: application/octet-stream\r\n\ \r\n"; let end = b"\r\n--boundary--\r\n"; - let b = [start as &[u8], &bytes, end].concat(); + let b = [start as &[u8], bytes, end].concat(); - let mut res = Response::new(Body::from(b)); - let h = res.headers_mut(); - h.insert( + let mut response = Response::new(Body::from(b)); + response.headers_mut().insert( "content-type", HeaderValue::from_static("multipart/form-data;boundary=boundary"), ); - Box::new(res) - }); - let multipart_form_data = - warp::path("multipart_form_data.txt").map(|| -> Box<dyn Reply> { + Ok(response) + } + (_, "/multipart_form_data.txt") => { let b = "Preamble\r\n\ - --boundary\t \r\n\ - Content-Disposition: form-data; name=\"field_1\"\r\n\ - \r\n\ - value_1 \r\n\ - \r\n--boundary\r\n\ - Content-Disposition: form-data; name=\"field_2\";\ - filename=\"file.js\"\r\n\ - Content-Type: text/javascript\r\n\ - \r\n\ - console.log(\"Hi\")\ - \r\n--boundary--\r\n\ - Epilogue"; + --boundary\t \r\n\ + Content-Disposition: form-data; name=\"field_1\"\r\n\ + \r\n\ + value_1 \r\n\ + \r\n--boundary\r\n\ + Content-Disposition: form-data; name=\"field_2\";\ + filename=\"file.js\"\r\n\ + Content-Type: text/javascript\r\n\ + \r\n\ + console.log(\"Hi\")\ + \r\n--boundary--\r\n\ + Epilogue"; let mut res = Response::new(Body::from(b)); res.headers_mut().insert( "content-type", HeaderValue::from_static("multipart/form-data;boundary=boundary"), ); - Box::new(res) - }); - let bad_redirect = warp::path("bad_redirect").map(|| -> Box<dyn Reply> { - let mut res = Response::new(Body::empty()); - *res.status_mut() = StatusCode::FOUND; - Box::new(res) - }); - let non_ascii_redirect = - warp::path("non_ascii_redirect").map(|| -> Box<dyn Reply> { + Ok(res) + } + (_, "/bad_redirect") => { + let mut res = Response::new(Body::empty()); + *res.status_mut() = StatusCode::FOUND; + Ok(res) + } + (_, "/non_ascii_redirect") => { let mut res = Response::new(Body::empty()); *res.status_mut() = StatusCode::MOVED_PERMANENTLY; res.headers_mut().insert( "location", HeaderValue::from_bytes(b"/redirect\xae").unwrap(), ); - Box::new(res) - }); + Ok(res) + } + (_, "/etag_script.ts") => { + let if_none_match = req.headers().get("if-none-match"); + if if_none_match == Some(&HeaderValue::from_static("33a64df551425fcc55e")) + { + let mut resp = Response::new(Body::empty()); + *resp.status_mut() = StatusCode::NOT_MODIFIED; + resp.headers_mut().insert( + "Content-type", + HeaderValue::from_static("application/typescript"), + ); + resp + .headers_mut() + .insert("ETag", HeaderValue::from_static("33a64df551425fcc55e")); - let etag_script = warp::path!("etag_script.ts") - .and(warp::header::optional::<String>("if-none-match")) - .map(|if_none_match| -> Box<dyn Reply> { - if if_none_match == Some("33a64df551425fcc55e".to_string()) { - let r = - warp::reply::with_status(warp::reply(), StatusCode::NOT_MODIFIED); - let r = with_header(r, "Content-type", "application/typescript"); - let r = with_header(r, "ETag", "33a64df551425fcc55e"); - Box::new(r) + Ok(resp) } else { - let mut res = Response::new(Body::from("console.log('etag')")); - let h = res.headers_mut(); - h.insert( + let mut resp = Response::new(Body::from("console.log('etag')")); + resp.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - h.insert("ETag", HeaderValue::from_static("33a64df551425fcc55e")); - Box::new(res) + resp + .headers_mut() + .insert("ETag", HeaderValue::from_static("33a64df551425fcc55e")); + Ok(resp) } - }); - let xtypescripttypes = warp::path!("xTypeScriptTypes.js") - .map(|| { + } + (_, "/xTypeScriptTypes.js") => { let mut res = Response::new(Body::from("export const foo = 'foo';")); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/javascript"), ); - h.insert( + res.headers_mut().insert( "X-TypeScript-Types", HeaderValue::from_static("./xTypeScriptTypes.d.ts"), ); - res - }) - .or(warp::path!("xTypeScriptTypes.d.ts").map(|| { + Ok(res) + } + (_, "/xTypeScriptTypes.d.ts") => { let mut res = Response::new(Body::from("export const foo: 'foo';")); res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("type_directives_redirect.js").map(|| { + Ok(res) + } + (_, "/type_directives_redirect.js") => { let mut res = Response::new(Body::from("export const foo = 'foo';")); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/javascript"), ); - h.insert( + res.headers_mut().insert( "X-TypeScript-Types", HeaderValue::from_static( "http://localhost:4547/xTypeScriptTypesRedirect.d.ts", ), ); - res - })) - .or(warp::path!("type_headers_deno_types.foo.js").map(|| { - let mut res = Response::new(Body::from("export function foo(text) { console.log(text); }")); - let h = res.headers_mut(); - h.insert( + Ok(res) + } + (_, "/type_headers_deno_types.foo.js") => { + let mut res = Response::new(Body::from( + "export function foo(text) { console.log(text); }", + )); + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/javascript"), ); - h.insert( + res.headers_mut().insert( "X-TypeScript-Types", HeaderValue::from_static( "http://localhost:4545/type_headers_deno_types.d.ts", ), ); - res - })) - .or(warp::path!("type_headers_deno_types.d.ts").map(|| { - let mut res = Response::new(Body::from("export function foo(text: number): void;")); - let h = res.headers_mut(); - h.insert( + Ok(res) + } + (_, "/type_headers_deno_types.d.ts") => { + let mut res = + Response::new(Body::from("export function foo(text: number): void;")); + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("type_headers_deno_types.foo.d.ts").map(|| { - let mut res = Response::new(Body::from("export function foo(text: string): void;")); - let h = res.headers_mut(); - h.insert( + Ok(res) + } + (_, "/type_headers_deno_types.foo.d.ts") => { + let mut res = + Response::new(Body::from("export function foo(text: string): void;")); + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("cli"/"tests"/"subdir"/"xTypeScriptTypesRedirect.d.ts").map(|| { + Ok(res) + } + (_, "/cli/tests/subdir/xTypeScriptTypesRedirect.d.ts") => { let mut res = Response::new(Body::from( "import './xTypeScriptTypesRedirected.d.ts';", )); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("cli"/"tests"/"subdir"/"xTypeScriptTypesRedirected.d.ts").map(|| { + Ok(res) + } + (_, "/cli/tests/subdir/xTypeScriptTypesRedirected.d.ts") => { let mut res = Response::new(Body::from("export const foo: 'foo';")); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("referenceTypes.js").map(|| { + Ok(res) + } + (_, "/referenceTypes.js") => { let mut res = Response::new(Body::from("/// <reference types=\"./xTypeScriptTypes.d.ts\" />\r\nexport const foo = \"foo\";\r\n")); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/javascript"), ); - res - })) - .or(warp::path!("cli"/"tests"/"subdir"/"file_with_:_in_name.ts").map(|| { + Ok(res) + } + (_, "/cli/tests/subdir/file_with_:_in_name.ts") => { let mut res = Response::new(Body::from( "console.log('Hello from file_with_:_in_name.ts');", )); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/typescript"), ); - res - })) - .or(warp::path!("cli"/"tests"/"subdir"/"no_js_ext@1.0.0").map(|| { + Ok(res) + } + (_, "/cli/tests/subdir/no_js_ext@1.0.0") => { let mut res = Response::new(Body::from( r#"import { printHello } from "./mod2.ts"; printHello(); "#, )); - let h = res.headers_mut(); - h.insert( + res.headers_mut().insert( "Content-type", HeaderValue::from_static("application/javascript"), ); - res - })); - - let content_type_handler = warp::any() - .and(warp::path::peek()) - .and(warp::fs::dir(root_path())) - .map(custom_headers) - .or(etag_script) - .or(xtypescripttypes) - .or(echo_server) - .or(echo_multipart_file) - .or(multipart_form_data) - .or(bad_redirect) - .or(non_ascii_redirect); - - let http_fut = - warp::serve(content_type_handler.clone()).bind(([127, 0, 0, 1], PORT)); - - let https_fut = warp::serve(content_type_handler.clone()) - .tls() - .cert_path("std/http/testdata/tls/localhost.crt") - .key_path("std/http/testdata/tls/localhost.key") - .bind(([127, 0, 0, 1], HTTPS_PORT)); + Ok(res) + } + _ => { + let mut file_path = root_path(); + file_path.push(&req.uri().path()[1..]); + if let Ok(file) = tokio::fs::read(file_path).await { + let file_resp = custom_headers(&req.uri().path()[1..], file); + return Ok(file_resp); + } + + return Ok(Response::new(Body::empty())); + } + }; +} + +/// Taken from example in https://github.com/ctz/hyper-rustls/blob/a02ef72a227dcdf102f86e905baa7415c992e8b3/examples/server.rs +struct HyperAcceptor<'a> { + acceptor: Pin< + Box< + dyn Stream<Item = io::Result<tokio_rustls::server::TlsStream<TcpStream>>> + + 'a, + >, + >, +} + +impl hyper::server::accept::Accept for HyperAcceptor<'_> { + type Conn = tokio_rustls::server::TlsStream<TcpStream>; + type Error = io::Error; + + fn poll_accept( + mut self: Pin<&mut Self>, + cx: &mut Context, + ) -> Poll<Option<Result<Self::Conn, Self::Error>>> { + Pin::new(&mut self.acceptor).poll_next(cx) + } +} + +unsafe impl std::marker::Send for HyperAcceptor<'_> {} + +async fn wrap_redirect_server() { + let redirect_svc = + make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(redirect)) }); + let redirect_addr = SocketAddr::from(([127, 0, 0, 1], REDIRECT_PORT)); + let redirect_server = Server::bind(&redirect_addr).serve(redirect_svc); + if let Err(e) = redirect_server.await { + eprintln!("Redirect error: {:?}", e); + } +} + +async fn wrap_double_redirect_server() { + let double_redirects_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(double_redirects)) + }); + let double_redirects_addr = + SocketAddr::from(([127, 0, 0, 1], DOUBLE_REDIRECTS_PORT)); + let double_redirects_server = + Server::bind(&double_redirects_addr).serve(double_redirects_svc); + if let Err(e) = double_redirects_server.await { + eprintln!("Double redirect error: {:?}", e); + } +} + +async fn wrap_inf_redirect_server() { + let inf_redirects_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(inf_redirects)) + }); + let inf_redirects_addr = + SocketAddr::from(([127, 0, 0, 1], INF_REDIRECTS_PORT)); + let inf_redirects_server = + Server::bind(&inf_redirects_addr).serve(inf_redirects_svc); + if let Err(e) = inf_redirects_server.await { + eprintln!("Inf redirect error: {:?}", e); + } +} + +async fn wrap_another_redirect_server() { + let another_redirect_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(another_redirect)) + }); + let another_redirect_addr = + SocketAddr::from(([127, 0, 0, 1], ANOTHER_REDIRECT_PORT)); + let another_redirect_server = + Server::bind(&another_redirect_addr).serve(another_redirect_svc); + if let Err(e) = another_redirect_server.await { + eprintln!("Another redirect error: {:?}", e); + } +} + +async fn wrap_abs_redirect_server() { + let abs_redirect_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(absolute_redirect)) + }); + let abs_redirect_addr = + SocketAddr::from(([127, 0, 0, 1], REDIRECT_ABSOLUTE_PORT)); + let abs_redirect_server = + Server::bind(&abs_redirect_addr).serve(abs_redirect_svc); + if let Err(e) = abs_redirect_server.await { + eprintln!("Absolute redirect error: {:?}", e); + } +} + +async fn wrap_main_server() { + let main_server_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(main_server)) + }); + let main_server_addr = SocketAddr::from(([127, 0, 0, 1], PORT)); + let main_server = Server::bind(&main_server_addr).serve(main_server_svc); + if let Err(e) = main_server.await { + eprintln!("HTTP server error: {:?}", e); + } +} + +async fn wrap_main_https_server() { + let main_server_https_addr = SocketAddr::from(([127, 0, 0, 1], HTTPS_PORT)); + let cert_file = "std/http/testdata/tls/localhost.crt"; + let key_file = "std/http/testdata/tls/localhost.key"; + let tls_config = get_tls_config(cert_file, key_file) + .await + .expect("Cannot get TLS config"); + let mut tcp = TcpListener::bind(&main_server_https_addr) + .await + .expect("Cannot bind TCP"); + loop { + let tls_acceptor = TlsAcceptor::from(tls_config.clone()); + // Prepare a long-running future stream to accept and serve cients. + let incoming_tls_stream = tcp + .incoming() + .map_err(|e| { + eprintln!("Error Incoming: {:?}", e); + io::Error::new(io::ErrorKind::Other, e) + }) + .and_then(move |s| { + use futures::TryFutureExt; + tls_acceptor.accept(s).map_err(|e| { + eprintln!("TLS Error {:?}", e); + e + }) + }) + .boxed(); + + let main_server_https_svc = make_service_fn(|_| async { + Ok::<_, hyper::Error>(service_fn(main_server)) + }); + let main_server_https = Server::builder(HyperAcceptor { + acceptor: incoming_tls_stream, + }) + .serve(main_server_https_svc); + + //continue to prevent TLS error stopping the server + if main_server_https.await.is_err() { + continue; + } + } +} + +#[tokio::main] +pub async fn run_all_servers() { + if let Some(port) = env::args().nth(1) { + return hyper_hello(port.parse::<u16>().unwrap()).await; + } + + let redirect_server_fut = wrap_redirect_server(); + let double_redirects_server_fut = wrap_double_redirect_server(); + let inf_redirects_server_fut = wrap_inf_redirect_server(); + let another_redirect_server_fut = wrap_another_redirect_server(); + let abs_redirect_server_fut = wrap_abs_redirect_server(); + + let ws_addr = SocketAddr::from(([127, 0, 0, 1], WS_PORT)); + let ws_server_fut = run_ws_server(&ws_addr); + let wss_addr = SocketAddr::from(([127, 0, 0, 1], WSS_PORT)); + let wss_server_fut = run_wss_server(&wss_addr); + + let main_server_fut = wrap_main_server(); + let main_server_https_fut = wrap_main_https_server(); let mut server_fut = async { futures::join!( - http_fut, - https_fut, redirect_server_fut, ws_server_fut, wss_server_fut, another_redirect_server_fut, - inf_redirect_server_fut, - double_redirect_server_fut, - absolute_redirect_server_fut, + inf_redirects_server_fut, + double_redirects_server_fut, + abs_redirect_server_fut, + main_server_fut, + main_server_https_fut, ) } .boxed(); let mut did_print_ready = false; - future::poll_fn(move |cx| { + futures::future::poll_fn(move |cx| { let poll_result = server_fut.poll_unpin(cx); if !replace(&mut did_print_ready, true) { println!("ready"); @@ -492,38 +747,61 @@ pub async fn run_all_servers() { .await; } -fn custom_headers(path: warp::path::Peek, f: warp::fs::File) -> Box<dyn Reply> { - let p = path.as_str(); +fn custom_headers(p: &str, body: Vec<u8>) -> Response<Body> { + let mut response = Response::new(Body::from(body)); if p.ends_with("cli/tests/x_deno_warning.js") { - let f = with_header(f, "Content-Type", "application/javascript"); - let f = with_header(f, "X-Deno-Warning", "foobar"); - return Box::new(f); + response.headers_mut().insert( + "Content-Type", + HeaderValue::from_static("application/javascript"), + ); + response + .headers_mut() + .insert("X-Deno-Warning", HeaderValue::from_static("foobar")); + return response; } if p.ends_with("cli/tests/053_import_compression/brotli") { - let f = with_header(f, "Content-Encoding", "br"); - let f = with_header(f, "Content-Type", "application/javascript"); - let f = with_header(f, "Content-Length", "26"); - return Box::new(f); + response + .headers_mut() + .insert("Content-Encoding", HeaderValue::from_static("br")); + response.headers_mut().insert( + "Content-Type", + HeaderValue::from_static("application/javascript"), + ); + response + .headers_mut() + .insert("Content-Length", HeaderValue::from_static("26")); + return response; } if p.ends_with("cli/tests/053_import_compression/gziped") { - let f = with_header(f, "Content-Encoding", "gzip"); - let f = with_header(f, "Content-Type", "application/javascript"); - let f = with_header(f, "Content-Length", "39"); - return Box::new(f); + response + .headers_mut() + .insert("Content-Encoding", HeaderValue::from_static("gzip")); + response.headers_mut().insert( + "Content-Type", + HeaderValue::from_static("application/javascript"), + ); + response + .headers_mut() + .insert("Content-Length", HeaderValue::from_static("39")); + return response; } + if p.contains("cli/tests/encoding/") { let charset = p .split_terminator('/') .last() .unwrap() .trim_end_matches(".ts"); - let f = with_header( - f, + + response.headers_mut().insert( "Content-Type", - &format!("application/typescript;charset={}", charset)[..], + HeaderValue::from_str( + &format!("application/typescript;charset={}", charset)[..], + ) + .unwrap(), ); - return Box::new(f); + return response; } let content_type = if p.contains(".t1.") { @@ -559,10 +837,13 @@ fn custom_headers(path: warp::path::Peek, f: warp::fs::File) -> Box<dyn Reply> { }; if let Some(t) = content_type { - Box::new(with_header(f, "Content-Type", t)) - } else { - Box::new(f) + response + .headers_mut() + .insert("Content-Type", HeaderValue::from_str(t).unwrap()); + return response; } + + response } #[derive(Default)] @@ -790,7 +1071,7 @@ pub fn deno_cmd() -> Command { pub fn run_powershell_script_file( script_file_path: &str, args: Vec<&str>, -) -> Result<(), i64> { +) -> std::result::Result<(), i64> { let deno_dir = new_deno_dir(); let mut command = Command::new("powershell.exe"); |