diff --git a/CHANGELOG.md b/CHANGELOG.md index 703dcd19..467119f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,14 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe ## Unreleased -## 0.8.0 +## 0.9.0 +### fixed +- Closed [#81](https://github.com/thedodd/trunk/issues/81): this is no longer needed as we now have support for WebSockets. HTTP2 is still outstanding, but that will not be a blocker for use from the web. +- Closed [#95](https://github.com/thedodd/trunk/issues/95): fixed via a few small changes to precendce in routing. +- Closed [#53](https://github.com/thedodd/trunk/issues/53): we've now implemented support for proxying WebSockets. + ### changed -- Switch over to `Tokio` from `async_std` -- Closed [#81](https://github.com/thedodd/trunk/issues/81): Switch to warp from tide. -- Closed [#95](https://github.com/thedodd/trunk/issues/95): Fixed as a result of switching to warp. -- Closed [#53](https://github.com/thedodd/trunk/issues/53): Fixed as a result of switching to warp. - -## Upgrading from 0.8 -- `--proxy-rewrite` has been renamed to `--proxy-path`. -- `Trunk.toml` must be updated in a way that `backend` denotes the proxy backend and `path` denotes where the server will listen. See the [example config file](./Trunk.toml) and [README](./README.md#config-file) for more information. +- The `--proxy-ws` has been added to the `Trunk.toml` and specifies that the given endpoint is for a WebSocket. ## 0.8.2 & 0.8.1 ### fixed diff --git a/Cargo.lock b/Cargo.lock index 25b66d95..0a89eba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -41,7 +41,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" dependencies = [ "cipher", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -51,7 +51,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" dependencies = [ "cipher", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -69,17 +69,49 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "async-channel" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" dependencies = [ "concurrent-queue", "event-listener", "futures-core", ] +[[package]] +name = "async-dup" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" +dependencies = [ + "futures-io", + "simple-mutex", +] + [[package]] name = "async-executor" version = "1.4.0" @@ -110,6 +142,24 @@ dependencies = [ "once_cell", ] +[[package]] +name = "async-h1" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5142de15b549749cce62923a50714b0d7b77f5090ced141599e78899865451" +dependencies = [ + "async-channel", + "async-dup", + "async-std", + "byte-pool", + "futures-core", + "http-types", + "httparse", + "lazy_static", + "log", + "pin-project", +] + [[package]] name = "async-io" version = "1.3.1" @@ -164,17 +214,54 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "async-session" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345022a2eed092cd105cc1b26fd61c341e100bd5fcbbd792df4baf31c2cc631f" +dependencies = [ + "anyhow", + "async-std", + "async-trait", + "base64 0.12.3", + "bincode", + "blake3", + "chrono", + "hmac 0.8.1", + "kv-log-macro", + "rand 0.7.3", + "serde", + "serde_json", + "sha2", +] + +[[package]] +name = "async-sse" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53bba003996b8fd22245cd0c59b869ba764188ed435392cf2796d03b805ade10" +dependencies = [ + "async-channel", + "async-std", + "http-types", + "log", + "memchr", + "pin-project-lite 0.1.12", +] + [[package]] name = "async-std" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341" dependencies = [ + "async-attributes", "async-channel", "async-global-executor", "async-io", "async-lock", - "crossbeam-utils", + "async-process", + "crossbeam-utils 0.8.3", "futures-channel", "futures-core", "futures-io", @@ -185,7 +272,7 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite", + "pin-project-lite 0.2.5", "pin-utils", "slab", "wasm-bindgen-futures", @@ -197,6 +284,30 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" +[[package]] +name = "async-trait" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-tungstenite" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39eca8dd578b18e557361e50ca767df55c5e62f690a5e53868c3c7a8123145b7" +dependencies = [ + "futures-io", + "futures-util", + "log", + "pin-project", + "tungstenite", +] + [[package]] name = "atomic-waker" version = "1.0.0" @@ -238,6 +349,16 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bincode" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" +dependencies = [ + "byteorder", + "serde", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -245,15 +366,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "block-buffer" -version = "0.7.3" +name = "blake3" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +checksum = "e9ff35b701f3914bdb8fad3368d822c766ef2858b2583198e41639b936f09d3f" dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.3", + "arrayref", + "arrayvec", + "cc", + "cfg-if 0.1.10", + "constant_time_eq", + "crypto-mac 0.8.0", + "digest", ] [[package]] @@ -262,16 +386,7 @@ 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]] @@ -289,32 +404,32 @@ dependencies = [ ] [[package]] -name = "buf_redux" -version = "0.8.4" +name = "bumpalo" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" [[package]] -name = "bumpalo" -version = "3.6.0" +name = "byte-pool" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9" +checksum = "1e38e98299d518ec351ca016363e0cbfc77059dcd08dfa9700d15e405536097a" +dependencies = [ + "crossbeam-queue", + "stable_deref_trait", +] [[package]] -name = "byte-tools" -version = "0.3.1" +name = "byteorder" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] -name = "byteorder" -version = "1.4.2" +name = "bytes" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" @@ -352,9 +467,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" @@ -368,13 +483,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "serde", + "time 0.1.44", + "winapi 0.3.9", +] + [[package]] name = "cipher" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -436,18 +565,24 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "cookie" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784ad0fbab4f3e9cef09f20e0aea6000ae08d2cb98ac4c0abc53df18803d702f" +checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" dependencies = [ "aes-gcm", - "base64 0.12.3", + "base64 0.13.0", "hkdf", - "hmac", + "hmac 0.10.1", "percent-encoding", - "rand 0.7.3", + "rand 0.8.3", "sha2", "time 0.2.25", "version_check", @@ -472,7 +607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.3", ] [[package]] @@ -483,41 +618,72 @@ checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-utils 0.8.3", ] [[package]] name = "crossbeam-epoch" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" +checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" dependencies = [ "cfg-if 1.0.0", - "const_fn", - "crossbeam-utils", + "crossbeam-utils 0.8.3", "lazy_static", "memoffset", "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + [[package]] name = "crossbeam-utils" -version = "0.8.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ "autocfg", "cfg-if 1.0.0", "lazy_static", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "crypto-mac" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" dependencies = [ - "generic-array 0.14.4", + "generic-array", "subtle", ] @@ -567,6 +733,47 @@ dependencies = [ "cipher", ] +[[package]] +name = "curl" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e268162af1a5fe89917ae25ba3b0a77c8da752bdc58e7dbb4f15b91fbd33756e" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi 0.3.9", +] + +[[package]] +name = "curl-sys" +version = "0.4.40+curl-7.75.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffafc1c35958318bd7fdd0582995ce4c72f4f461a8e70499ccee83a619fd562" +dependencies = [ + "cc", + "libc", + "libnghttp2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi 0.3.9", +] + +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -590,22 +797,13 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" -[[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]] @@ -647,6 +845,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "envy" version = "0.4.2" @@ -662,12 +869,6 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fastrand" version = "1.4.0" @@ -677,6 +878,22 @@ dependencies = [ "instant", ] +[[package]] +name = "femme" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af1a24f391a5a94d756db5092c6576aad494b88a71a5a36b20c67b63e0df034" +dependencies = [ + "cfg-if 0.1.10", + "js-sys", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "filetime" version = "0.2.14" @@ -689,6 +906,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "flume" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bebadab126f8120d410b677ed95eee4ba6eb7c6dd8e34a5ec88a08050e26132" +dependencies = [ + "futures-core", + "futures-sink", + "spinning_top", +] + [[package]] name = "fnv" version = "1.0.7" @@ -697,9 +925,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", "percent-encoding", @@ -758,9 +986,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150" +checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" dependencies = [ "futures-channel", "futures-core", @@ -773,9 +1001,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846" +checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" dependencies = [ "futures-core", "futures-sink", @@ -783,15 +1011,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65" +checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" [[package]] name = "futures-executor" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9" +checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" dependencies = [ "futures-core", "futures-task", @@ -800,9 +1028,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500" +checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" [[package]] name = "futures-lite" @@ -815,15 +1043,15 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite", + "pin-project-lite 0.2.5", "waker-fn", ] [[package]] name = "futures-macro" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd" +checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -833,24 +1061,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6" +checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" [[package]] name = "futures-task" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86" -dependencies = [ - "once_cell", -] +checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" [[package]] name = "futures-util" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b" +checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" dependencies = [ "futures-channel", "futures-core", @@ -859,7 +1084,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.5", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -875,15 +1100,6 @@ dependencies = [ "byteorder", ] -[[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" @@ -913,7 +1129,7 @@ checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.10.0+wasi-snapshot-preview1", ] [[package]] @@ -922,7 +1138,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" dependencies = [ - "opaque-debug 0.3.0", + "opaque-debug", "polyval", ] @@ -941,11 +1157,11 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5" +checksum = "d832b01df74254fe364568d6ddc294443f61cbec82816b60904303af87efae78" dependencies = [ - "bytes", + "bytes 1.0.1", "fnv", "futures-core", "futures-sink", @@ -956,7 +1172,6 @@ dependencies = [ "tokio", "tokio-util", "tracing", - "tracing-futures", ] [[package]] @@ -965,31 +1180,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" -[[package]] -name = "headers" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62689dc57c7456e69712607ffcbd0aa1dfcccf9af73727e9b25bc1825375cac3" -dependencies = [ - "base64 0.13.0", - "bitflags", - "bytes", - "headers-core", - "http", - "mime", - "sha-1 0.8.2", - "time 0.1.43", -] - -[[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.2" @@ -1014,8 +1204,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" dependencies = [ - "digest 0.9.0", - "hmac", + "digest", + "hmac 0.10.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest", ] [[package]] @@ -1024,8 +1224,8 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ - "crypto-mac", - "digest 0.9.0", + "crypto-mac 0.10.0", + "digest", ] [[package]] @@ -1048,7 +1248,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" dependencies = [ - "bytes", + "bytes 1.0.1", "fnv", "itoa", ] @@ -1059,10 +1259,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" dependencies = [ - "bytes", + "bytes 1.0.1", "http", ] +[[package]] +name = "http-client" +version = "6.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "663563ebc56b0bac7e08722cca7742612fd99d9bd6d05cf904ed9d9212065a34" +dependencies = [ + "async-std", + "async-trait", + "cfg-if 1.0.0", + "dashmap", + "http-types", + "isahc", + "log", +] + [[package]] name = "http-types" version = "2.10.0" @@ -1076,7 +1291,7 @@ dependencies = [ "cookie", "futures-lite", "infer", - "pin-project-lite", + "pin-project-lite 0.2.5", "rand 0.7.3", "serde", "serde_json", @@ -1103,7 +1318,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7" dependencies = [ - "bytes", + "bytes 1.0.1", "futures-channel", "futures-core", "futures-util", @@ -1113,7 +1328,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project 1.0.5", + "pin-project", "socket2", "tokio", "tower-service", @@ -1121,11 +1336,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "futures-util", + "hyper", + "log", + "rustls", + "tokio", + "tokio-rustls", + "webpki", +] + [[package]] name = "idna" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094" +checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" dependencies = [ "matches", "unicode-bidi", @@ -1182,11 +1412,11 @@ dependencies = [ [[package]] name = "input_buffer" -version = "0.4.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" +checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754" dependencies = [ - "bytes", + "bytes 0.5.6", ] [[package]] @@ -1221,6 +1451,35 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnet" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" + +[[package]] +name = "isahc" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2948a0ce43e2c2ef11d7edf6816508998d99e13badd1150be0914205df9388a" +dependencies = [ + "bytes 0.5.6", + "crossbeam-utils 0.8.3", + "curl", + "curl-sys", + "flume", + "futures-lite", + "http", + "log", + "once_cell", + "slab", + "sluice", + "tracing", + "tracing-futures", + "url", + "waker-fn", +] + [[package]] name = "itoa" version = "0.4.7" @@ -1229,9 +1488,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.47" +version = "0.3.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" +checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78" dependencies = [ "wasm-bindgen", ] @@ -1269,9 +1528,31 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.86" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" + +[[package]] +name = "libnghttp2-sys" +version = "0.1.6+1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0af55541a8827e138d59ec9e5877fb6095ece63fb6f4da45e7491b4fbd262855" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "libz-sys" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] [[package]] name = "linked-hash-map" @@ -1279,6 +1560,15 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -1318,6 +1608,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" version = "2.3.4" @@ -1370,9 +1666,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" +checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" dependencies = [ "libc", "log", @@ -1415,24 +1711,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "multipart" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4" -dependencies = [ - "buf_redux", - "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand 0.7.3", - "safemem", - "tempfile", - "twoway", -] - [[package]] name = "nb-connect" version = "1.0.3" @@ -1505,6 +1783,25 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -1523,15 +1820,9 @@ checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" [[package]] name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" - -[[package]] -name = "opaque-debug" -version = "0.2.3" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" [[package]] name = "opaque-debug" @@ -1541,13 +1832,33 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open" -version = "1.4.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48" +checksum = "b2033f93630dd4b04768ecf5e16bcd3002a89e1e1dbef375bf290dd67e2b7a4d" dependencies = [ + "which", "winapi 0.3.9", ] +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" + +[[package]] +name = "openssl-sys" +version = "0.9.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking" version = "2.0.0" @@ -1623,29 +1934,20 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" -dependencies = [ - "pin-project-internal 0.4.27", -] - [[package]] name = "pin-project" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63" dependencies = [ - "pin-project-internal 1.0.5", + "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.27" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" +checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" dependencies = [ "proc-macro2", "quote", @@ -1653,21 +1955,16 @@ dependencies = [ ] [[package]] -name = "pin-project-internal" -version = "1.0.5" +name = "pin-project-lite" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" +checksum = "0cf491442e4b033ed1c722cb9f0df5fcfcf4de682466c46469c36bc47dc5548a" [[package]] name = "pin-utils" @@ -1701,7 +1998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" dependencies = [ "cpuid-bool 0.2.0", - "opaque-debug 0.3.0", + "opaque-debug", "universal-hash", ] @@ -1762,12 +2059,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.9" @@ -1888,7 +2179,7 @@ checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils", + "crossbeam-utils 0.8.3", "lazy_static", "num_cpus", ] @@ -1912,31 +2203,78 @@ dependencies = [ ] [[package]] -name = "regex-syntax" -version = "0.6.22" +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + +[[package]] +name = "remove_dir_all" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b19f5c2df95a07275e7224924cc62f76f04525f4fda801473f85e325e81977" +dependencies = [ + "log", + "num_cpus", + "rayon", + "winapi 0.3.9", +] + +[[package]] +name = "reqwest" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34" +dependencies = [ + "base64 0.13.0", + "bytes 1.0.1", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project-lite 0.2.5", + "rustls", + "serde", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", "winapi 0.3.9", ] [[package]] -name = "remove_dir_all" -version = "0.6.1" +name = "route-recognizer" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b19f5c2df95a07275e7224924cc62f76f04525f4fda801473f85e325e81977" -dependencies = [ - "log", - "num_cpus", - "rayon", - "winapi 0.3.9", -] +checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rustc_version" @@ -1948,16 +2286,23 @@ dependencies = [ ] [[package]] -name = "ryu" -version = "1.0.5" +name = "rustls" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b" +dependencies = [ + "base64 0.13.0", + "log", + "ring", + "sct", + "webpki", +] [[package]] -name = "safemem" -version = "0.3.3" +name = "ryu" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" @@ -1991,10 +2336,14 @@ dependencies = [ ] [[package]] -name = "scoped-tls" -version = "1.0.0" +name = "schannel" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi 0.3.9", +] [[package]] name = "scopeguard" @@ -2002,6 +2351,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "seahash" version = "4.1.0" @@ -2084,9 +2443,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.62" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", @@ -2141,27 +2500,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.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4b312c3731e3fe78a185e6b9b911a7aa715b8e31cce117975219aab2acf285d" +checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f" dependencies = [ - "block-buffer 0.9.0", + "block-buffer", "cfg-if 1.0.0", "cpuid-bool 0.1.2", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest", + "opaque-debug", ] [[package]] @@ -2176,18 +2523,18 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" dependencies = [ - "block-buffer 0.9.0", + "block-buffer", "cfg-if 1.0.0", "cpuid-bool 0.1.2", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest", + "opaque-debug", ] [[package]] name = "signal-hook" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f5e3fe0c66f67197236097d89de1e86216f1f6fdeaf47c442f854ab46c240" +checksum = "8a7f3f92a1da3d6b1d32245d0cbcbbab0cfc45996d8df619c42bccfa6d2bbb5f" dependencies = [ "libc", "signal-hook-registry", @@ -2202,6 +2549,15 @@ dependencies = [ "libc", ] +[[package]] +name = "simple-mutex" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" +dependencies = [ + "event-listener", +] + [[package]] name = "siphasher" version = "0.3.3" @@ -2214,6 +2570,17 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "sluice" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fa0333a60ff2e3474a6775cc611840c2a55610c831dd366503474c02f1a28f5" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", +] + [[package]] name = "smallvec" version = "1.6.1" @@ -2231,6 +2598,21 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spinning_top" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e529d73e80d64b5f2631f9035113347c578a1c9c7774b83a2b880788459ab36" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2356,6 +2738,34 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +[[package]] +name = "surf" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a154d33ca6b5e1fe6fd1c760e5a5cc1202425f6cca2e13229f16a69009f6328" +dependencies = [ + "async-std", + "async-trait", + "cfg-if 1.0.0", + "encoding_rs", + "futures-util", + "http-client", + "http-types", + "log", + "mime_guess", + "once_cell", + "pin-project-lite 0.2.5", + "serde", + "serde_json", + "web-sys", +] + +[[package]] +name = "sval" +version = "1.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f6ee7c7b87caf59549e9fe45d6a69c75c8019e79e212a835c5da0e92f0ba08" + [[package]] name = "syn" version = "1.0.60" @@ -2367,20 +2777,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand 0.8.3", - "redox_syscall", - "remove_dir_all 0.5.3", - "winapi 0.3.9", -] - [[package]] name = "tendril" version = "0.4.2" @@ -2428,31 +2824,73 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "tide" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c459573f0dd2cc734b539047f57489ea875af8ee950860ded20cf93a79a1dee0" +dependencies = [ + "async-h1", + "async-session", + "async-sse", + "async-std", + "async-trait", + "femme", + "futures-util", + "http-client", + "http-types", + "kv-log-macro", + "log", + "pin-project-lite 0.2.5", + "route-recognizer", + "serde", + "serde_json", +] + +[[package]] +name = "tide-websockets" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9eef759bbe19bd62693c01f1ac58207290513096caccafed140dbc81deaa47" +dependencies = [ + "async-dup", + "async-std", + "async-tungstenite", + "base64 0.13.0", + "futures-util", + "pin-project", + "serde", + "serde_json", + "sha-1", + "tide", +] + [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -2516,51 +2954,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" dependencies = [ "autocfg", - "bytes", + "bytes 1.0.1", "libc", "memchr", - "mio 0.7.7", - "num_cpus", - "once_cell", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-macros" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-stream" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1981ad97df782ab506a1f43bf82c967326960d278acf3bf8279809648c3ff3ea" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", + "mio 0.7.9", + "pin-project-lite 0.2.5", ] [[package]] -name = "tokio-tungstenite" -version = "0.13.0" +name = "tokio-rustls" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ - "futures-util", - "log", - "pin-project 1.0.5", + "rustls", "tokio", - "tungstenite", + "webpki", ] [[package]] @@ -2569,11 +2978,11 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b" dependencies = [ - "bytes", + "bytes 1.0.1", "futures-core", "futures-sink", "log", - "pin-project-lite", + "pin-project-lite 0.2.5", "tokio", ] @@ -2594,16 +3003,28 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.23" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d40a22fd029e33300d8d89a5cc8ffce18bb7c587662f54629e94c9de5487f3" +checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite", + "pin-project-lite 0.2.5", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.17" @@ -2615,11 +3036,11 @@ dependencies = [ [[package]] name = "tracing-futures" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 0.4.27", + "pin-project", "tracing", ] @@ -2629,6 +3050,7 @@ version = "0.9.0" dependencies = [ "anyhow", "async-process", + "async-std", "cargo_metadata", "console 0.14.0", "dunce", @@ -2638,20 +3060,20 @@ dependencies = [ "http-types", "indicatif", "insta", - "lazy_static", "nipper", "notify", "open", - "remove_dir_all 0.6.1", + "remove_dir_all", + "reqwest", "sass-rs", "seahash", "serde", "structopt", "structopt-derive", - "tokio", - "tokio-tungstenite", + "surf", + "tide", + "tide-websockets", "toml", - "warp", ] [[package]] @@ -2662,32 +3084,23 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.12.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" +checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23" dependencies = [ - "base64 0.13.0", + "base64 0.12.3", "byteorder", - "bytes", + "bytes 0.5.6", "http", "httparse", "input_buffer", "log", - "rand 0.8.3", - "sha-1 0.9.3", + "rand 0.7.3", + "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" @@ -2751,15 +3164,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" dependencies = [ - "generic-array 0.14.4", + "generic-array", "subtle", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" dependencies = [ "form_urlencoded", "idna", @@ -2781,8 +3200,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b676010e055c99033117c2343b33a40a30b91fecd6c49055ac9cd2d6c305ab1" dependencies = [ "ctor", + "sval", ] +[[package]] +name = "vcpkg" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" + [[package]] name = "vec-arena" version = "1.0.0" @@ -2828,36 +3254,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "warp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dafd0aac2818a94a34df0df1100a7356c493d8ede4393875fd0b5c51bb6bc80" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "multipart", - "percent-encoding", - "pin-project 1.0.5", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tokio-util", - "tower-service", - "tracing", - "tracing-futures", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -2866,25 +3262,27 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" +checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7" dependencies = [ "cfg-if 1.0.0", + "serde", + "serde_json", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" +checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8" dependencies = [ "bumpalo", "lazy_static", @@ -2897,9 +3295,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94" +checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2909,9 +3307,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" +checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2919,9 +3317,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" +checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e" dependencies = [ "proc-macro2", "quote", @@ -2932,20 +3330,39 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" +checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1" [[package]] name = "web-sys" -version = "0.3.47" +version = "0.3.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" +checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82015b7e0b8bad8185994674a13a93306bea76cf5a16c5a181382fd3a5ec2376" +dependencies = [ + "webpki", +] + [[package]] name = "wepoll-sys" version = "3.0.1" @@ -2955,6 +3372,16 @@ dependencies = [ "cc", ] +[[package]] +name = "which" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef" +dependencies = [ + "libc", + "thiserror", +] + [[package]] name = "winapi" version = "0.2.8" @@ -2998,6 +3425,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 6a15aaf9..16983c91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ panic = "abort" [dependencies] anyhow = "1" async-process = "1" +async-std = { version="1.9", default-features = false, features=["attributes", "std", "unstable"] } cargo_metadata = "0.12" console = "0.14" dunce = "1" @@ -26,30 +27,20 @@ fs_extra = "1" futures = "0.3" http-types = "2" indicatif = "0.15" -lazy_static = "1.4.0" nipper = { git = "https://github.com/thedodd/nipper.git", branch = "iter-attrs" } notify = "4" open = "1" remove_dir_all = "0.6" +reqwest = { version = "0.11.1", default-features = false, features = ["rustls-tls", "stream"] } sass-rs = "0.2.2" seahash = "4" serde = { version="1", features=["derive"] } structopt = "0.3" structopt-derive = "0.4" -tokio = { version="1", features=[ - # See https://docs.rs/tokio/1.2.0/tokio/#feature-flags - "rt", - "rt-multi-thread", - "net", - "time", - "process", - "macros", - "sync", - "fs" -]} -tokio-tungstenite = "0.13.0" +surf = "2" +tide = { version="0.16.0", features=["unstable"] } +tide-websockets = "0.2.0" toml = "0.5" -warp = "0.3.0" [dev-dependencies] insta = "0.16.1" diff --git a/README.md b/README.md index 2ee14983..da18e219 100644 --- a/README.md +++ b/README.md @@ -159,12 +159,12 @@ The `trunk serve` command accepts two proxy related flags. `--proxy-backend` specifies the URL of the backend server to which requests should be proxied. The URI segment of the given URL will be used as the path on the Trunk server to handle proxy requests. E.G., `trunk serve --proxy-backend=http://localhost:9000/api/` will proxy any requests received on the path `/api/` to the server listening at `http://localhost:9000/api/`. Further path segments or query parameters will be seamlessly passed along. -`--proxy-path` specifies the path on which the Trunk server is to listen for proxy requests. Any requests received on the given URI will be routed to the proxy backend. E.G., `trunk serve --proxy-backend=http://localhost:9000/api --proxy-path=/api/` will proxy any requests received on `/api/` over to `http://localhost:9000/api`. +`--proxy-rewrite` specifies an alternative URI on which the Trunk server is to listen for proxy requests. Any requests received on the given URI will be rewritten to match the URI of the proxy backend, effectively stripping the rewrite prefix. E.G., `trunk serve --proxy-backend=http://localhost:9000/ --proxy-rewrite=/api/` will proxy any requests received on `/api/` over to `http://localhost:9000/` with the `/api/` prefix stripped from the request, while everything following the `/api/` prefix will be left unchanged. -`--proxy-ws` specifies that the proxy is for a websocket endpoint. +`--proxy-ws` specifies that the proxy is for a WebSocket endpoint. ### config file -The `Trunk.toml` config file accepts multiple `[[proxy]]` sections, which allows for multiple proxies to be configured. Each section requires at least the `backend` field, and optionally accepts the `path` and `ws` fields, corresponding to the `--proxy-*` CLI flags discussed above. +The `Trunk.toml` config file accepts multiple `[[proxy]]` sections, which allows for multiple proxies to be configured. Each section requires at least the `backend` field, and optionally accepts the `rewrite` and `ws` fields, corresponding to the `--proxy-*` CLI flags discussed above. As it is with other Trunk config, a proxy declared via CLI will take final precedence and will cause any config file proxies to be ignored, even if there are multiple proxies declared in the config file. @@ -172,8 +172,8 @@ The following is a snippet from the `Trunk.toml` file in this repo: ```toml [[proxy]] +rewrite = "/api/v1/" backend = "http://localhost:9000/" -path = "/api/" ``` ## contributing diff --git a/Trunk.toml b/Trunk.toml index 21ed7ca5..91889637 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -33,21 +33,19 @@ cargo = false # Proxies are only run as part of the `trunk serve` command. [[proxy]] -# This websocket proxy example has a backend and a path field. This example will listen for -# websocket connections at `/api/ws` and proxy the those to `http://localhost:9000/api/ws`. -# Websocket proxies must be listed before http ones. -path = "/api/ws/" +# This WebSocket proxy example has a backend and ws field. This example will listen for +# WebSocket connections at `/api/ws` and proxy them to `http://localhost:9000/api/ws`. backend = "http://localhost:9000/api/ws" ws = true [[proxy]] -# This proxy example has a backend and a path field. Only the requests received on `path` will be -# proxied to the backend. The request URIs are not modified when proxied. -# This example will listen at `/api/v1` and proxy the requests to `http://localhost:9000/` -path = "/api/v1/" -backend = "http://localhost:9000" +# This proxy example has a backend and a rewrite field. Requests received on `rewrite` will be +# proxied to the backend after rewriting the `rewrite` prefix to the `backend`'s URI prefix. +# E.G., `/api/v1/resource/x/y/z` -> `/resource/x/y/z` +rewrite = "/api/v1/" +backend = "http://localhost:9000/" [[proxy]] -# This proxy specifies only the backend, which is the only required field. The request URIs are not modified when proxied. -# This example will listen at `/` and proxy the requests to `http://localhost:9000/api/v2` -backend = "http://localhost:9000/api/v2" +# This proxy specifies only the backend, which is the only required field. In this example, +# request URIs are not modified when proxied. +backend = "http://localhost:9000/api/v2/" diff --git a/site/content/configuration.md b/site/content/configuration.md index 67d70d18..1967bbf3 100644 --- a/site/content/configuration.md +++ b/site/content/configuration.md @@ -25,12 +25,12 @@ The `trunk serve` command accepts two proxy related flags. `--proxy-backend` specifies the URL of the backend server to which requests should be proxied. The URI segment of the given URL will be used as the path on the Trunk server to handle proxy requests. E.G., `trunk serve --proxy-backend=http://localhost:9000/api/` will proxy any requests received on the path `/api/` to the server listening at `http://localhost:9000/api/`. Further path segments or query parameters will be seamlessly passed along. -`--proxy-path` specifies the path on which the Trunk server is to listen for proxy requests. Any requests received on the given URI will be routed to the proxy backend. E.G., `trunk serve --proxy-backend=http://localhost:9000/api --proxy-path=/api/` will proxy any requests received on `/api/` over to `http://localhost:9000/api`. +`--proxy-rewrite` specifies an alternative URI on which the Trunk server is to listen for proxy requests. Any requests received on the given URI will be rewritten to match the URI of the proxy backend, effectively stripping the rewrite prefix. E.G., `trunk serve --proxy-backend=http://localhost:9000/ --proxy-rewrite=/api/` will proxy any requests received on `/api/` over to `http://localhost:9000/` with the `/api/` prefix stripped from the request, while everything following the `/api/` prefix will be left unchanged. -`--proxy-ws` specifies that the proxy is for a websocket endpoint. +`--proxy-ws` specifies that the proxy is for a WebSocket endpoint. ## Config File -The `Trunk.toml` config file accepts multiple `[[proxy]]` sections, which allows for multiple proxies to be configured. Each section requires at least the `backend` field, and optionally accepts the `path` and `ws` fields, both corresponding to the `--proxy-*` CLI flags discussed above. +The `Trunk.toml` config file accepts multiple `[[proxy]]` sections, which allows for multiple proxies to be configured. Each section requires at least the `backend` field, and optionally accepts the `rewrite` and `ws` fields, both corresponding to the `--proxy-*` CLI flags discussed above. As it is with other Trunk config, a proxy declared via CLI will take final precedence and will cause any config file proxies to be ignored, even if there are multiple proxies declared in the config file. @@ -38,6 +38,6 @@ The following is a snippet from the `Trunk.toml` file in the Trunk repo: ```toml [[proxy]] +rewrite = "/api/v1/" backend = "http://localhost:9000/" -path = "/api/" ``` diff --git a/src/build.rs b/src/build.rs index 1d3cb1fe..e09abac7 100644 --- a/src/build.rs +++ b/src/build.rs @@ -4,9 +4,10 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{Context, Result}; +use async_std::fs; +use futures::channel::mpsc::Sender; +use futures::stream::StreamExt; use indicatif::ProgressBar; -use tokio::fs; -use tokio::sync::mpsc::Sender; use crate::common::{remove_dir_all, BUILDING, ERROR, SUCCESS}; use crate::config::{RtcBuild, STAGE_DIR}; @@ -75,11 +76,7 @@ impl BuildSystem { // Spawn the source HTML pipeline. This will spawn all other pipelines derived from // the source HTML, and will ultimately generate and write the final HTML. - self.html_pipeline - .clone() - .spawn() - .await - .context("error joining spawned HTML pipeline")??; + self.html_pipeline.clone().spawn().await.context("error joining spawned HTML pipeline")?; // Move distrbution from staging dist to final dist self.finalize_dist().await.context("error applying built distribution")?; @@ -121,7 +118,8 @@ impl BuildSystem { let staging_dist = self.cfg.staging_dist.clone(); let mut entries = fs::read_dir(&staging_dist).await.context("error reading staging dist dir")?; - while let Some(entry) = entries.next_entry().await.context("error reading contents of staging dist dir")? { + while let Some(entry) = entries.next().await { + let entry = entry.context("error reading contents of staging dist dir")?; let target_path = final_dist.join(entry.file_name()); fs::rename(entry.path(), &target_path) @@ -136,14 +134,15 @@ impl BuildSystem { let final_dist = self.cfg.final_dist.clone(); let mut entries = fs::read_dir(&final_dist).await.context("error reading final dist dir")?; - while let Some(entry) = entries.next_entry().await.context("error reading contents of staging dist dir")? { + while let Some(entry) = entries.next().await { + let entry = entry.context("error reading contents of staging dist dir")?; if entry.file_name() == STAGE_DIR { continue; } let file_type = entry.file_type().await.context("error reading metadata of file in final dist dir")?; if file_type.is_dir() { - remove_dir_all(entry.path()).await.context("error cleaning final dist")?; + remove_dir_all(entry.path().into()).await.context("error cleaning final dist")?; } else if file_type.is_symlink() || file_type.is_file() { fs::remove_file(entry.path()).await.context("error cleaning final dist")?; } diff --git a/src/common.rs b/src/common.rs index a924ab7d..2a14380d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,14 +1,14 @@ //! Common functionality and types. +use std::io::ErrorKind; use std::path::{Path, PathBuf}; use anyhow::{anyhow, Context, Result}; -use tokio::task::spawn_blocking; +use async_std::fs; +use async_std::task::spawn_blocking; use console::Emoji; use indicatif::{ProgressBar, ProgressStyle}; -use std::io::ErrorKind; -use tokio::fs; pub static BUILDING: Emoji<'_, '_> = Emoji("📦", ""); pub static SUCCESS: Emoji<'_, '_> = Emoji("✅", ""); @@ -28,7 +28,7 @@ pub async fn copy_dir_recursive(from_dir: PathBuf, to_dir: PathBuf) -> Result<() return Err(anyhow!("directory can not be copied as it does not exist {:?}", &from_dir)); } - spawn_blocking(move || { + spawn_blocking(move || -> Result<()> { let opts = fs_extra::dir::CopyOptions { overwrite: true, content_only: true, @@ -38,7 +38,7 @@ pub async fn copy_dir_recursive(from_dir: PathBuf, to_dir: PathBuf) -> Result<() Ok(()) }) .await - .context("error copying directory")? + .context("error copying directory") } /// A utility function to recursively delete a directory. @@ -53,18 +53,16 @@ pub async fn remove_dir_all(from_dir: PathBuf) -> Result<()> { ::remove_dir_all::remove_dir_all(from_dir.as_path()).context("error removing directory")?; Ok(()) }) - .await? + .await } -/// Checks if path exists. In case of error, it is returned back from caller. -/// This is behavior is in contrast to [`std::fs::Path::Exists`] -/// -/// Taken from: [tokio#3375 (comment)](https://github.com/tokio-rs/tokio/pull/3375#issuecomment-758612179) +/// Checks if path exists. pub async fn path_exists(path: impl AsRef) -> Result { - let exists = fs::metadata(&path) + let exists = fs::metadata(path.as_ref()) .await .map(|_| true) - .or_else(|error| if error.kind() == ErrorKind::NotFound { Ok(false) } else { Err(error) })?; + .or_else(|error| if error.kind() == ErrorKind::NotFound { Ok(false) } else { Err(error) }) + .with_context(|| format!("error checking for existance of path at {:?}", path.as_ref()))?; Ok(exists) } diff --git a/src/config/manifest.rs b/src/config/manifest.rs index 0c186688..5661828c 100644 --- a/src/config/manifest.rs +++ b/src/config/manifest.rs @@ -1,8 +1,8 @@ use std::path::Path; use anyhow::{Context, Result}; +use async_std::task::spawn_blocking; use cargo_metadata::{Metadata, MetadataCommand, Package}; -use tokio::task::spawn_blocking; /// A wrapper around the cargo project's metadata. #[derive(Clone, Debug)] @@ -20,7 +20,7 @@ impl CargoMetadata { pub async fn new(manifest: &Path) -> Result { let mut cmd = MetadataCommand::new(); cmd.manifest_path(dunce::simplified(manifest)); - let metadata = spawn_blocking(move || cmd.exec()).await.context("error getting cargo metadata")??; + let metadata = spawn_blocking(move || cmd.exec()).await.context("error getting cargo metadata")?; let package = metadata .root_package() diff --git a/src/config/mod.rs b/src/config/mod.rs index 20709fe0..e773934a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -8,8 +8,8 @@ mod manifest; mod models; mod rt; -/// The default name of the directory where final build artifacts are placed after a successful -/// build. +/// The default name of the directory where final build artifacts are +/// placed after a successful build. pub const DIST_DIR: &str = "dist"; /// The name of the directory used to stage build artifacts during an active build. pub const STAGE_DIR: &str = ".stage"; diff --git a/src/config/models.rs b/src/config/models.rs index 0d2140b8..14c679be 100644 --- a/src/config/models.rs +++ b/src/config/models.rs @@ -52,12 +52,12 @@ pub struct ConfigOptsServe { #[structopt(long = "proxy-backend")] #[serde(default)] pub proxy_backend: Option, - /// The URI on which to accept requests which are to be proxied to backend + /// The URI on which to accept requests which are to be rewritten and proxied to backend /// [default: None] - #[structopt(long = "proxy-path")] + #[structopt(long = "proxy-rewrite")] #[serde(default)] - pub proxy_path: Option, - /// Whether the endpoint for a websocket [default: false] + pub proxy_rewrite: Option, + /// Configure the proxy for handling WebSockets [default: false] #[structopt(long = "proxy-ws")] #[serde(default)] pub proxy_ws: bool, @@ -89,8 +89,8 @@ pub struct ConfigOptsProxy { /// /// When a value is specified, requests received on this URI will have this URI segment replaced /// with the URI of the `backend`. - pub path: Option, - /// Whether the proxy is for a websocket endpoint + pub rewrite: Option, + /// Configure the proxy for handling WebSockets. #[serde(default)] pub ws: bool, } @@ -188,7 +188,7 @@ impl ConfigOpts { port: cli.port, open: cli.open, proxy_backend: cli.proxy_backend, - proxy_path: cli.proxy_path, + proxy_rewrite: cli.proxy_rewrite, proxy_ws: cli.proxy_ws, }; let cfg = ConfigOpts { @@ -323,7 +323,7 @@ impl ConfigOpts { (Some(val), None) | (None, Some(val)) => Some(val), (Some(l), Some(mut g)) => { g.proxy_backend = g.proxy_backend.or(l.proxy_backend); - g.proxy_path = g.proxy_path.or(l.proxy_path); + g.proxy_rewrite = g.proxy_rewrite.or(l.proxy_rewrite); g.port = g.port.or(l.port); g.proxy_ws = g.proxy_ws || l.proxy_ws; // NOTE: this can not be disabled in the cascade. diff --git a/src/config/rt.rs b/src/config/rt.rs index 21ab279a..a28f2f55 100644 --- a/src/config/rt.rs +++ b/src/config/rt.rs @@ -113,9 +113,9 @@ pub struct RtcServe { pub open: bool, /// A URL to which requests will be proxied. pub proxy_backend: Option, - /// The URI on which to accept requests which are to be proxied to backend. - pub proxy_path: Option, - /// Whether the endpoint is for websocket. + /// The URI on which to accept requests which are to be rewritten and proxied to backend. + pub proxy_rewrite: Option, + /// Configure the proxy for handling WebSockets. pub proxy_ws: bool, /// Any proxies configured to run along with the server. pub proxies: Option>, @@ -131,7 +131,7 @@ impl RtcServe { port: opts.port.unwrap_or(8080), open: opts.open, proxy_backend: opts.proxy_backend, - proxy_path: opts.proxy_path, + proxy_rewrite: opts.proxy_rewrite, proxy_ws: opts.proxy_ws, proxies, }) diff --git a/src/main.rs b/src/main.rs index 6aa2e656..503e0e9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,17 +11,11 @@ use std::path::PathBuf; use anyhow::Result; use structopt::StructOpt; -use tokio::task::LocalSet; -#[tokio::main] +#[async_std::main] async fn main() -> Result<()> { - // Build the Trunk CLI, processing CLI args, and then run the CLI. We run everything from an - // initial local set. This allows us to ensure that the HTML pipeline (which is !Send + !Sync) - // is able to be successfully spawned on this local set. No other pipelines should have any - // reason to not be Send + Sync. This is really an API limitation of the `nipper` crate. let cli = Trunk::from_args(); - let local_set = LocalSet::new(); - local_set.run_until(async move { cli.run().await }).await + cli.run().await } /// Build, bundle & ship your Rust WASM application to the web. diff --git a/src/pipelines/copydir.rs b/src/pipelines/copydir.rs index 86a77134..26ac1cd6 100644 --- a/src/pipelines/copydir.rs +++ b/src/pipelines/copydir.rs @@ -4,10 +4,10 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, Context, Result}; +use async_std::fs; +use async_std::task::{spawn, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::fs; -use tokio::task::{spawn, JoinHandle}; use super::ATTR_HREF; use super::{LinkAttrs, TrunkLinkPipelineOutput}; @@ -53,7 +53,7 @@ impl CopyDir { .file_name() .ok_or_else(|| anyhow!("could not get directory name of dir {:?}", &canonical_path))?; let dir_out = self.cfg.staging_dist.join(dir_name); - copy_dir_recursive(canonical_path, dir_out).await?; + copy_dir_recursive(canonical_path.into(), dir_out).await?; self.progress.set_message("finished copying directory"); Ok(TrunkLinkPipelineOutput::CopyDir(CopyDirOutput(self.id))) }) diff --git a/src/pipelines/copyfile.rs b/src/pipelines/copyfile.rs index 90e068ec..bc1d4e27 100644 --- a/src/pipelines/copyfile.rs +++ b/src/pipelines/copyfile.rs @@ -4,9 +4,9 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, Result}; +use async_std::task::{spawn, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::task::{spawn, JoinHandle}; use super::ATTR_HREF; use super::{AssetFile, LinkAttrs, TrunkLinkPipelineOutput}; diff --git a/src/pipelines/css.rs b/src/pipelines/css.rs index ca85c08f..28f26e86 100644 --- a/src/pipelines/css.rs +++ b/src/pipelines/css.rs @@ -4,9 +4,9 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, Result}; +use async_std::task::{spawn, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::task::{spawn, JoinHandle}; use super::ATTR_HREF; use super::{AssetFile, HashedFileOutput, LinkAttrs, TrunkLinkPipelineOutput}; diff --git a/src/pipelines/html.rs b/src/pipelines/html.rs index efc3d200..d27f027f 100644 --- a/src/pipelines/html.rs +++ b/src/pipelines/html.rs @@ -4,12 +4,12 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, ensure, Context, Result}; +use async_std::fs; +use async_std::task::{spawn_local, JoinHandle}; +use futures::channel::mpsc::Sender; use futures::stream::{FuturesUnordered, StreamExt}; use indicatif::ProgressBar; use nipper::Document; -use tokio::fs; -use tokio::sync::mpsc::Sender; -use tokio::task::JoinHandle; use crate::config::RtcBuild; use crate::pipelines::rust_app::RustApp; @@ -58,7 +58,7 @@ impl HtmlPipeline { /// Spawn a new pipeline. pub fn spawn(self: Arc) -> JoinHandle> { - tokio::task::spawn_local(self.build()) + spawn_local(self.build()) } /// Perform the build routine of this pipeline. @@ -128,7 +128,7 @@ impl HtmlPipeline { /// Finalize asset pipelines & prep the DOM for final output. async fn finalize_asset_pipelines(&self, target_html: &mut Document, mut pipelines: AssetPipelineHandles) -> Result<()> { while let Some(asset_res) = pipelines.next().await { - let asset = asset_res.context("failed to spawn assets finalization")??; + let asset = asset_res.context("failed to spawn assets finalization")?; asset.finalize(target_html).await?; } Ok(()) diff --git a/src/pipelines/icon.rs b/src/pipelines/icon.rs index 287dace8..b4ddd7bf 100644 --- a/src/pipelines/icon.rs +++ b/src/pipelines/icon.rs @@ -4,9 +4,9 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, Result}; +use async_std::task::{spawn, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::task::{spawn, JoinHandle}; use super::ATTR_HREF; use super::{AssetFile, HashedFileOutput, LinkAttrs, TrunkLinkPipelineOutput}; diff --git a/src/pipelines/inline.rs b/src/pipelines/inline.rs index 0b53725b..8c00dfb9 100644 --- a/src/pipelines/inline.rs +++ b/src/pipelines/inline.rs @@ -5,9 +5,9 @@ use std::str::FromStr; use std::sync::Arc; use anyhow::{anyhow, bail, Result}; +use async_std::task::{spawn, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::task::JoinHandle; use super::{AssetFile, LinkAttrs, TrunkLinkPipelineOutput, ATTR_HREF, ATTR_TYPE}; @@ -48,7 +48,7 @@ impl Inline { /// Spawn the pipeline for this asset type. pub fn spawn(self) -> JoinHandle> { - tokio::spawn(async move { + spawn(async move { self.progress.set_message("reading file content"); let content = self.asset.read_to_string().await?; self.progress.set_message("finished reading file content"); diff --git a/src/pipelines/mod.rs b/src/pipelines/mod.rs index 68a7fc82..c26d1fef 100644 --- a/src/pipelines/mod.rs +++ b/src/pipelines/mod.rs @@ -14,11 +14,11 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::{anyhow, bail, ensure, Context, Result}; +use async_std::fs; +use async_std::task::JoinHandle; +use futures::channel::mpsc::Sender; use indicatif::ProgressBar; use nipper::Document; -use tokio::fs; -use tokio::sync::mpsc::Sender; -use tokio::task::JoinHandle; use crate::config::RtcBuild; use crate::pipelines::copydir::{CopyDir, CopyDirOutput}; @@ -159,7 +159,7 @@ impl AssetFile { let path = fs::canonicalize(&path) .await .with_context(|| format!("error getting canonical path for {:?}", &path))?; - ensure!(path.is_file(), "target file does not appear to exist on disk {:?}", &path); + ensure!(path.is_file().await, "target file does not appear to exist on disk {:?}", &path); let file_name = match path.file_name() { Some(file_name) => file_name.to_owned(), None => bail!("asset has no file name {:?}", &path), @@ -173,7 +173,7 @@ impl AssetFile { None => bail!("asset has no file extension {:?}", &path), }; Ok(Self { - path, + path: path.into(), file_name, file_stem, ext, diff --git a/src/pipelines/rust_app.rs b/src/pipelines/rust_app.rs index 84e1f369..7f89570f 100644 --- a/src/pipelines/rust_app.rs +++ b/src/pipelines/rust_app.rs @@ -6,11 +6,11 @@ use std::sync::Arc; use anyhow::{anyhow, ensure, Context, Result}; use async_process::{Command, Stdio}; +use async_std::fs; +use async_std::task::{spawn, JoinHandle}; +use futures::channel::mpsc::Sender; use indicatif::ProgressBar; use nipper::Document; -use tokio::fs; -use tokio::sync::mpsc::Sender; -use tokio::task::{spawn, JoinHandle}; use super::{LinkAttrs, TrunkLinkPipelineOutput}; use super::{ATTR_HREF, SNIPPETS_DIR}; diff --git a/src/pipelines/rust_worker.rs b/src/pipelines/rust_worker.rs index 5a3aa20f..c54967c3 100644 --- a/src/pipelines/rust_worker.rs +++ b/src/pipelines/rust_worker.rs @@ -6,10 +6,10 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{bail, Result}; +use async_std::task::JoinHandle; +use futures::channel::mpsc::Sender; use indicatif::ProgressBar; use nipper::Document; -use tokio::sync::mpsc::Sender; -use tokio::task::JoinHandle; use super::{LinkAttrs, TrunkLinkPipelineOutput}; use crate::config::{CargoMetadata, RtcBuild}; diff --git a/src/pipelines/sass.rs b/src/pipelines/sass.rs index edd61a00..d935ae0f 100644 --- a/src/pipelines/sass.rs +++ b/src/pipelines/sass.rs @@ -4,10 +4,10 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{anyhow, Context, Result}; +use async_std::fs; +use async_std::task::{spawn, spawn_blocking, JoinHandle}; use indicatif::ProgressBar; use nipper::Document; -use tokio::fs; -use tokio::task::{spawn, spawn_blocking, JoinHandle}; use super::ATTR_HREF; use super::{AssetFile, HashedFileOutput, LinkAttrs, TrunkLinkPipelineOutput}; @@ -49,13 +49,10 @@ impl Sass { if self.cfg.release { opts.output_style = sass_rs::OutputStyle::Compressed; } - let css = spawn_blocking(move || sass_rs::compile_file(&path_str, opts)) - .await - .context("error joining spawned sass/scss pipeline")? - .map_err(|err| { - self.progress.println(err); - anyhow!("error compiling sass for {:?}", &self.asset.path) - })?; + let css = spawn_blocking(move || sass_rs::compile_file(&path_str, opts)).await.map_err(|err| { + self.progress.println(err); + anyhow!("error compiling sass for {:?}", &self.asset.path) + })?; // Hash the contents to generate a file name, and then write the contents to the dist dir. let hash = seahash::hash(css.as_bytes()); diff --git a/src/proxy.rs b/src/proxy.rs index b1d7d16d..36755901 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,157 +1,79 @@ -use std::borrow::Cow; -use std::str::FromStr; - -use anyhow::Error; -use futures::{SinkExt, StreamExt}; -use hyper::Client; -use lazy_static::lazy_static; -use tokio_tungstenite::tungstenite::protocol::CloseFrame; -use tokio_tungstenite::tungstenite::Message as TungsteniteMessage; -use warp::filters::BoxedFilter; -use warp::http::{Request, Uri}; -use warp::hyper::client::connect::dns::GaiResolver; -use warp::hyper::client::HttpConnector; -use warp::hyper::Body; -use warp::reject::Reject; -use warp::ws::{self, Message as WarpMessage}; -use warp::{http, hyper, reject, Filter, Rejection, Reply}; - -use crate::common::ERROR; - -#[derive(Debug)] -pub struct ProxyRejection(pub Error); - -impl Reject for ProxyRejection {} - -pub fn extract_request() -> impl Filter,), Error = Rejection> + Copy { - warp::method() - .and(warp::path::full()) - .and(warp::header::headers_cloned()) - .and(warp::body::bytes()) - .and_then( - |method: http::Method, path: warp::path::FullPath, headers: http::HeaderMap, body| async move { - let mut req = http::Request::builder() - .method(method) - .uri(path.as_str()) - .body(warp::hyper::Body::from(body)) - .map_err(|e| reject::custom(ProxyRejection(Error::from(e))))?; - { - *req.headers_mut() = headers; - } - Ok::<_, Rejection>(req) - }, - ) -} - -lazy_static! { - // ideally this should use reqwest but there's no way to convert - // `http::Request` into `reqwest::Request`. - // see reqwest#1156 (https://github.com/seanmonstar/reqwest/issues/1156) for more info - // For any other usage, consider depending upon and using reqwest instead - static ref CLIENT: Client, Body> = Client::new(); -} - -async fn http_proxy_handler(mut request: Request, proxy_to: String) -> Result { - let uri = request.uri(); - let proxy_to = proxy_to.strip_suffix("/").unwrap_or(&proxy_to); - - // the urls are already parsed to be correct so its safe to unwrap here - *request.uri_mut() = Uri::from_str(&format!("{}{}", proxy_to, uri)).unwrap(); - - CLIENT.request(request).await.map_err(|e| reject::custom(ProxyRejection(Error::from(e)))) -} - -pub fn http_proxy(path: BoxedFilter<()>, proxy_to: String) -> impl Filter + Clone { - path.and(extract_request()) - .and(warp::any().map(move || proxy_to.clone())) - .and_then(http_proxy_handler) -} - -async fn ws_proxy_handler(ws: ws::Ws, redirect_to: String) -> Result { - let resp = ws.on_upgrade(|ws_conn| async move { - let (mut warp_sink, mut warp_source) = ws_conn.split(); - let (mut remote_sink, mut remote_source) = match tokio_tungstenite::connect_async(redirect_to).await { - Ok(ws) => ws.0.split(), - Err(e) => { - eprintln!("{} error occurred while opening proxy websocket: {}", ERROR, e); - if warp_sink.send(WarpMessage::close()).await.is_ok() { - if let Err(e) = warp_sink.flush().await { - eprintln!("error flushing warp sink: {}", e); - } - }; - return; - } - }; - - let redirect_warp = async move { - while let Some(Ok(msg)) = remote_source.next().await { - let msg = match msg { - TungsteniteMessage::Binary(data) => WarpMessage::binary(data), - TungsteniteMessage::Text(data) => WarpMessage::text(data), - TungsteniteMessage::Ping(data) => WarpMessage::ping(data), - TungsteniteMessage::Pong(_) => continue, - TungsteniteMessage::Close(Some(frame)) => WarpMessage::close_with(frame.code, frame.reason), - TungsteniteMessage::Close(None) => WarpMessage::close(), - }; - if let Err(e) = warp_sink.send(msg).await { - eprintln!("error forwarding WebSocket message to client: {}", e); - - if let Err(e) = warp_sink.flush().await { - eprintln!("error flushing warp sink: {}", e); - } - } - } - }; - let redirect_remote = async move { - while let Some(Ok(msg)) = warp_source.next().await { - let msg = if msg.is_binary() { - TungsteniteMessage::binary(msg.into_bytes()) - } else if msg.is_text() { - match msg.to_str() { - Ok(text) => TungsteniteMessage::text(text), - Err(err) => { - eprintln!("error extracting proxied WebSocket text {:?}", err); - continue; - } - } - } else if msg.is_close() { - let frame = msg.close_frame().map(|(code, reason)| CloseFrame { - code: code.into(), - reason: Cow::from(reason.to_owned()), - }); - TungsteniteMessage::Close(frame) - } else if msg.is_ping() { - TungsteniteMessage::Ping(msg.into_bytes()) - } else if msg.is_pong() { - TungsteniteMessage::Pong(msg.into_bytes()) - } else { - eprintln!("unrecognized message from proxied WebSocket: {:?}", msg); - continue; - }; - - if let Err(e) = remote_sink.send(msg).await { - eprintln!("error forwarding WebSocket message to server: {}", e); - - if let Err(e) = remote_sink.flush().await { - eprintln!("error flushing remote sink: {}", e); - } - } - } - }; - - let handle1 = tokio::spawn(redirect_warp); - let handle2 = tokio::spawn(redirect_remote); - - if let Err(e) = tokio::try_join!(handle1, handle2) { - eprintln!("{} WebSocket proxy error: {}", ERROR, e) - }; - }); - - Ok(resp.into_response()) +use std::sync::Arc; + +use http_types::{Method, Url}; +use tide::{Request, Result, Server}; + +use crate::serve::State; + +/// All HTTP methods, used for registering proxy endpoints with proper precedence. +static HTTP_METHODS: [Method; 9] = [ + Method::Get, + Method::Head, + Method::Post, + Method::Put, + Method::Delete, + Method::Connect, + Method::Options, + Method::Trace, + Method::Patch, +]; + +/// A handler used for proxying HTTP requests to a backend. +pub struct ProxyHandlerHttp { + /// The URL of the backend to which requests are to be proxied. + backend: Url, + /// An optional rewrite path to be used as the listening URI prefix, but which will be + /// stripped before being sent to the proxy backend. + rewrite: Option, } -pub fn ws_proxy(path: BoxedFilter<()>, redirect_to: String) -> impl Filter + Clone { - path.and(ws::ws()) - .and(warp::any().map(move || redirect_to.clone())) - .and_then(ws_proxy_handler) +impl ProxyHandlerHttp { + /// Create a new instance. + pub fn new(backend: Url, rewrite: Option) -> Self { + Self { backend, rewrite } + } + + /// The path on which this proxy handler is to listen. + pub fn path(&self) -> &str { + self.rewrite.as_ref().map(AsRef::as_ref).unwrap_or_else(|| self.backend.path()) + } + + /// Register this proxy handler on the given app. + pub fn register(self: Arc, app: &mut Server) { + for method in HTTP_METHODS.iter() { + let handler = self.clone(); + app.at(handler.path()).strip_prefix().method(*method, move |req: Request| { + let handler = handler.clone(); + async move { handler.proxy_request(req).await } + }); + } + } + + /// Proxy the given request to the target backend. + pub async fn proxy_request(&self, mut req: Request) -> Result { + // Build a new request to be sent to the proxy backend. + let req_url = req.url(); + let req_path = req_url.path(); + let mut url = self.backend.clone(); + if let Ok(mut segments) = url.path_segments_mut() { + segments.pop_if_empty().extend(req_path.trim_start_matches('/').split('/')); + } + url.set_query(req_url.query()); + let mut request = surf::RequestBuilder::new(req.method(), url).body(req.take_body()); + for (hname, hval) in req.iter() { + request = request.header(hname, hval); + } + // Ensure the host header is set to target the backend itself. + if let Some(host) = self.backend.host_str() { + request = request.header("host", host); + } + + // Send the request & unpack the response. + let mut res = request.send().await?; + let mut response = tide::Response::builder(res.status()).body(res.take_body()); + for (hname, hval) in res.iter() { + response = response.header(hname, hval); + } + Ok(response.build()) + } } diff --git a/src/serve.rs b/src/serve.rs index d7f1f4ac..2af5e2db 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -1,15 +1,18 @@ +use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::Result; +use async_std::fs; +use async_std::task::{spawn, spawn_local, JoinHandle}; use indicatif::ProgressBar; -use tokio::task::JoinHandle; -use warp::{Filter, Rejection, Reply}; +use tide::http::mime; +use tide::{Middleware, Next, Request, Response, StatusCode}; +// use tide_websockets::{Message, WebSocket}; -use crate::common::{ERROR, SERVER}; +use crate::common::SERVER; use crate::config::RtcServe; -use crate::proxy::{http_proxy, ws_proxy, ProxyRejection}; +use crate::proxy::ProxyHandlerHttp; use crate::watch::WatchSystem; -use warp::http::status::StatusCode; /// A system encapsulating a build & watch system, responsible for serving generated content. pub struct ServeSystem { @@ -36,8 +39,8 @@ impl ServeSystem { pub async fn run(mut self) -> Result<()> { // Spawn the watcher & the server. self.watch.build().await; - let watch_handle = tokio::spawn(self.watch.run()); - let server_handle = Self::spawn_server(self.cfg.clone(), self.http_addr.clone(), self.progress.clone()); + let watch_handle = spawn_local(self.watch.run()); + let server_handle = Self::spawn_server(self.cfg.clone(), self.http_addr.clone(), self.progress.clone())?; // Open the browser. if self.cfg.open { @@ -46,77 +49,71 @@ impl ServeSystem { } } - let _ = server_handle.await; - let _ = watch_handle.await; + server_handle.await; + watch_handle.await; Ok(()) } - fn spawn_server(cfg: Arc, http_addr: String, progress: ProgressBar) -> JoinHandle<()> { - // Build proxies. - let mut proxy_route = dummy().boxed(); - - if let Some(backend) = &cfg.proxy_backend { - let path = cfg.proxy_path.clone().unwrap_or_else(String::new); - let mut paths = warp::any().boxed(); - for path in path.split('/').into_iter().map(|it| it.to_owned()) { - paths = paths.and(warp::path(path)).boxed(); - } + fn spawn_server(cfg: Arc, http_addr: String, progress: ProgressBar) -> Result> { + // Prep state. + let listen_addr = format!("0.0.0.0:{}", cfg.port); + let index = Arc::new(cfg.watch.build.final_dist.join("index.html")); - let proxy_to = backend.to_string(); + // Build app. + tide::log::with_level(tide::log::LevelFilter::Error); + let mut app = tide::with_state(State { index }); + app.with(IndexHtmlMiddleware) + .at(&cfg.watch.build.public_url) + .serve_dir(cfg.watch.build.final_dist.to_string_lossy().as_ref())?; - if cfg.proxy_ws { - progress.println(format!("{} proxying websocket /{} -> {}", SERVER, path, proxy_to)); - proxy_route = ws_proxy(paths, proxy_to).map(Reply::into_response).boxed(); - } else { - progress.println(format!("{} proxying http /{} -> {}", SERVER, path, proxy_to)); - proxy_route = http_proxy(paths, proxy_to).map(Reply::into_response).boxed(); - }; + // Build proxies. + if let Some(backend) = &cfg.proxy_backend { + let handler = Arc::new(ProxyHandlerHttp::new(backend.clone(), cfg.proxy_rewrite.clone())); + progress.println(format!("{} proxying {} -> {}\n", SERVER, handler.path(), &backend)); + handler.register(&mut app); } else if let Some(proxies) = &cfg.proxies { - for proxy_config in proxies { - let path = proxy_config.path.clone().unwrap_or_else(String::new); - let proxy_to = proxy_config.backend.to_string(); - - // `warp::path` requires that `/` must not be inside the passed path so we - // remove that and handle segments with `and`ing the `warp::path` for each segment - let mut paths = warp::any().boxed(); - for path in path.split('/').into_iter().map(|it| it.to_owned()) { - paths = paths.and(warp::path(path)).boxed(); - } - - if proxy_config.ws { - progress.println(format!("{} proxying websocket /{} -> {}", SERVER, path, proxy_to)); - proxy_route = proxy_route.or(ws_proxy(paths, proxy_to)).map(Reply::into_response).boxed(); - } else { - progress.println(format!("{} proxying http /{} -> {}", SERVER, path, proxy_to)); - proxy_route = proxy_route.or(http_proxy(paths, proxy_to)).map(Reply::into_response).boxed(); - }; + for proxy in proxies.iter() { + let handler = Arc::new(ProxyHandlerHttp::new(proxy.backend.clone(), proxy.rewrite.clone())); + progress.println(format!("{} proxying {} -> {}\n", SERVER, handler.path(), &proxy.backend)); + handler.register(&mut app); } - }; - - let routes = warp::fs::dir(cfg.watch.build.final_dist.clone()) - .or(proxy_route) - .or(warp::fs::file(cfg.watch.build.final_dist.join("index.html"))) - .recover(rejection_handler); + } // Listen and serve. progress.println(format!("{} server running at {}\n", SERVER, &http_addr)); - tokio::spawn(async move { - warp::serve(routes).run(([0, 0, 0, 0], cfg.port)).await; - }) + Ok(spawn(async move { + if let Err(err) = app.listen(listen_addr).await { + progress.println(err.to_string()); + } + })) } } -// workaround to make compiler happy -fn dummy() -> impl Filter + Clone + Sync + Send { - warp::any().and_then(|| async move { Err(warp::reject()) }) +/// Server state. +#[derive(Clone, Debug)] +pub struct State { + /// The path to the index.html file. + pub index: Arc, } -async fn rejection_handler(err: Rejection) -> Result { - let mut error = "".to_string(); - if let Some(e) = err.find::() { - eprintln!("{} proxy error: {}", ERROR, e.0); - error = e.0.to_string(); - } +async fn load_index_html(index: &Path) -> tide::Result> { + Ok(fs::read(index).await?) +} - Ok(warp::reply::with_status(error, StatusCode::INTERNAL_SERVER_ERROR)) +/// Middleware for accessing the index.html from any request which needs it. +struct IndexHtmlMiddleware; + +#[tide::utils::async_trait] +impl Middleware for IndexHtmlMiddleware { + async fn handle(&self, req: Request, next: Next<'_, State>) -> tide::Result { + let index = req.state().index.clone(); + let res = next.run(req).await; + Ok(match res.status() { + StatusCode::NotFound => Response::builder(StatusCode::Ok) + .content_type(mime::HTML) + .body(load_index_html(&index).await?) + .build(), + _ => res, + }) + } } diff --git a/src/watch.rs b/src/watch.rs index 951bdd5f..2e95e6f7 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -2,10 +2,11 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{Context, Result}; +use async_std::task::{spawn_blocking, JoinHandle}; +use futures::channel::mpsc::{channel, Receiver, Sender}; +use futures::prelude::*; use indicatif::ProgressBar; use notify::{watcher, DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher}; -use tokio::sync::mpsc::{channel, Receiver, Sender}; -use tokio::task::{spawn_blocking, JoinHandle}; use crate::build::BuildSystem; use crate::config::RtcWatch; @@ -59,14 +60,11 @@ impl WatchSystem { /// Run the watch system, responding to events and triggering builds. pub async fn run(mut self) { loop { - tokio::select! { - // NOTE WELL: as of Trunk 0.8.0, this channel is only ever used to ignore the - // cargo target dir, which is determined dynamically at runtime. The path MUST - // be the canonical path when it is sent over this channel from the build system. - ign_res = self.build_rx.recv() => if let Some(ign) = ign_res { + futures::select! { + ign_res = self.build_rx.next() => if let Some(ign) = ign_res { self.update_ignore_list(ign); }, - ev_res = self.watch_rx.recv() => if let Some(ev) = ev_res { + ev_res = self.watch_rx.next() => if let Some(ev) = ev_res { self.handle_watch_event(ev).await; }, } @@ -98,14 +96,19 @@ impl WatchSystem { } } - fn update_ignore_list(&mut self, path: PathBuf) { + fn update_ignore_list(&mut self, arg_path: PathBuf) { + let path = match arg_path.canonicalize() { + Ok(canon_path) => canon_path, + Err(_) => arg_path, + }; + if !self.ignored_paths.contains(&path) { self.ignored_paths.push(path); } } } -fn build_watcher(watch_tx: Sender, paths: Vec) -> Result<(JoinHandle<()>, RecommendedWatcher)> { +fn build_watcher(mut watch_tx: Sender, paths: Vec) -> Result<(JoinHandle<()>, RecommendedWatcher)> { let (tx, rx) = std::sync::mpsc::channel(); let mut watcher = watcher(tx, std::time::Duration::from_secs(1)).context("failed to build file system watcher")?;