├── README.md ├── .gitignore ├── src ├── err.rs ├── main.rs ├── opt.rs ├── path.rs ├── server.rs └── routes.rs ├── Cargo.toml ├── LICENSE ├── .github └── workflows │ └── ci.yml └── Cargo.lock /README.md: -------------------------------------------------------------------------------- 1 | # retransmitted 2 | Simple CORS proxy. 3 | 4 | ⚠️ MOVED TO A SUBCOMMAND OF https://github.com/erikdesjardins/re ⚠️ 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | /target 9 | **/*.rs.bk 10 | -------------------------------------------------------------------------------- /src/err.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Debug, Display}; 2 | 3 | pub type Error = Box; 4 | 5 | pub struct DisplayError(Error); 6 | 7 | impl Debug for DisplayError { 8 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 9 | Display::fmt(&self.0, f) 10 | } 11 | } 12 | 13 | impl> From for DisplayError { 14 | fn from(display: T) -> Self { 15 | DisplayError(display.into()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "retransmitted" 3 | version = "0.2.1" 4 | authors = [] 5 | description = "Simple CORS proxy." 6 | edition = "2018" 7 | 8 | [dependencies] 9 | env_logger = { version = "0.9", default-features = false, features = ["humantime"] } 10 | hyper = { version = "0.14", features = ["client", "server", "http1", "http2"] } 11 | hyper-rustls = { version = "0.23", features = ["http2"] } 12 | log = "0.4" 13 | ring = "0.16" 14 | structopt = { version = "0.3", default-features = false } 15 | thiserror = "1.0" 16 | tokio = { version = "1.0" , features = ["macros", "rt"] } 17 | 18 | [profile.release] 19 | panic = "abort" 20 | lto = true 21 | codegen-units = 1 22 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod err; 2 | mod opt; 3 | mod path; 4 | mod routes; 5 | mod server; 6 | 7 | #[tokio::main(flavor = "current_thread")] 8 | async fn main() -> Result<(), err::DisplayError> { 9 | let opt::Options { 10 | verbose, 11 | listen_addr, 12 | secret_key, 13 | } = structopt::StructOpt::from_args(); 14 | 15 | env_logger::Builder::new() 16 | .filter_level(match verbose { 17 | 0 => log::LevelFilter::Warn, 18 | 1 => log::LevelFilter::Info, 19 | 2 => log::LevelFilter::Debug, 20 | _ => log::LevelFilter::Trace, 21 | }) 22 | .init(); 23 | 24 | server::run(listen_addr, secret_key).await?; 25 | 26 | Ok(()) 27 | } 28 | -------------------------------------------------------------------------------- /src/opt.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | use structopt::StructOpt; 3 | 4 | #[derive(StructOpt, Debug)] 5 | #[structopt(about)] 6 | pub struct Options { 7 | #[structopt( 8 | short = "v", 9 | long = "verbose", 10 | parse(from_occurrences), 11 | global = true, 12 | help = "Logging verbosity (-v info, -vv debug, -vvv trace)" 13 | )] 14 | pub verbose: u8, 15 | 16 | #[structopt(help = "Socket address to listen on (e.g. 0.0.0.0:443)")] 17 | pub listen_addr: SocketAddr, 18 | 19 | #[structopt( 20 | long = "secret-key", 21 | help = "Secret key, clients must provide it in the x-retransmitted-key header" 22 | )] 23 | pub secret_key: String, 24 | } 25 | -------------------------------------------------------------------------------- /src/path.rs: -------------------------------------------------------------------------------- 1 | use hyper::http::uri::InvalidUri; 2 | use hyper::Uri; 3 | use std::borrow::Cow; 4 | use std::str::FromStr; 5 | 6 | pub fn extract_uri_from_path(uri: &Uri) -> Option)>> { 7 | let path = uri 8 | .path_and_query() 9 | .and_then(|p| p.as_str().strip_prefix('/'))?; 10 | 11 | let unparsed = if path.starts_with("https:") || path.starts_with("http:") { 12 | Cow::Borrowed(path) 13 | } else { 14 | // if no protocol provided, default to https: 15 | Cow::Owned(format!("https://{}", path)) 16 | }; 17 | 18 | Some(match Uri::from_str(&unparsed) { 19 | Ok(u) => Ok(u), 20 | Err(e) => Err((e, unparsed)), 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/server.rs: -------------------------------------------------------------------------------- 1 | use crate::err::Error; 2 | use crate::routes::{respond_to_request, State}; 3 | use hyper::service::{make_service_fn, service_fn}; 4 | use hyper::{Client, Server}; 5 | use hyper_rustls::HttpsConnectorBuilder; 6 | use std::convert::Infallible; 7 | use std::net::SocketAddr; 8 | use std::sync::Arc; 9 | 10 | pub async fn run(addr: SocketAddr, secret_key: String) -> Result<(), Error> { 11 | let client = Client::builder().build( 12 | HttpsConnectorBuilder::new() 13 | .with_native_roots() 14 | .https_or_http() 15 | .enable_http1() 16 | .enable_http2() 17 | .build(), 18 | ); 19 | 20 | let state = Arc::new(State { client, secret_key }); 21 | let make_svc = make_service_fn(move |_| { 22 | let state = Arc::clone(&state); 23 | let svc = service_fn(move |req| { 24 | let state = Arc::clone(&state); 25 | async move { respond_to_request(req, &state).await } 26 | }); 27 | async move { Ok::<_, Infallible>(svc) } 28 | }); 29 | 30 | Server::try_bind(&addr)?.serve(make_svc).await?; 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v*.*.* 9 | pull_request: 10 | 11 | jobs: 12 | fmt: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: actions-rs/toolchain@v1 17 | with: 18 | toolchain: stable 19 | - run: rustup component add rustfmt 20 | - run: cargo fmt --all -- --check 21 | 22 | clippy: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: actions-rs/toolchain@v1 27 | with: 28 | toolchain: stable 29 | - run: rustup component add clippy 30 | - run: RUSTFLAGS="-D warnings" cargo clippy 31 | 32 | test: 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v2 36 | - uses: actions-rs/toolchain@v1 37 | with: 38 | toolchain: stable 39 | - run: cargo test 40 | 41 | build-linux: 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v2 45 | - uses: actions-rs/toolchain@v1 46 | with: 47 | toolchain: stable 48 | target: x86_64-unknown-linux-musl 49 | - run: sudo apt-get install musl-tools 50 | - run: cargo build --release --target=x86_64-unknown-linux-musl 51 | - run: strip target/x86_64-unknown-linux-musl/release/retransmitted 52 | - run: ls -lh target/x86_64-unknown-linux-musl/release/retransmitted 53 | - uses: softprops/action-gh-release@v1 54 | if: startsWith(github.ref, 'refs/tags/') 55 | with: 56 | files: target/x86_64-unknown-linux-musl/release/retransmitted 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | 60 | build-windows: 61 | runs-on: windows-latest 62 | steps: 63 | - uses: actions/checkout@v2 64 | - uses: actions-rs/toolchain@v1 65 | with: 66 | toolchain: stable 67 | - run: cargo build --release 68 | env: 69 | RUSTFLAGS: -Ctarget-feature=+crt-static 70 | - run: dir target/release/retransmitted.exe 71 | - uses: softprops/action-gh-release@v1 72 | if: startsWith(github.ref, 'refs/tags/') 73 | with: 74 | files: target/release/retransmitted.exe 75 | env: 76 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 77 | -------------------------------------------------------------------------------- /src/routes.rs: -------------------------------------------------------------------------------- 1 | use crate::path::extract_uri_from_path; 2 | use hyper::client::HttpConnector; 3 | use hyper::http::HeaderValue; 4 | use hyper::{header, Body, Client, Method, Request, Response, StatusCode}; 5 | use hyper_rustls::HttpsConnector; 6 | use std::convert::Infallible; 7 | use std::mem; 8 | 9 | pub struct State { 10 | pub client: Client>, 11 | pub secret_key: String, 12 | } 13 | 14 | #[allow(clippy::declare_interior_mutable_const)] 15 | pub async fn respond_to_request( 16 | mut req: Request, 17 | state: &State, 18 | ) -> Result, Infallible> { 19 | const X_RETRANSMITTED_KEY: &str = "x-retransmitted-key"; 20 | const ANY: HeaderValue = HeaderValue::from_static("*"); 21 | const ALLOWED_HEADERS: HeaderValue = HeaderValue::from_static(X_RETRANSMITTED_KEY); 22 | 23 | if req.method() == Method::OPTIONS { 24 | log::info!("{} {} -> [preflight response]", req.method(), req.uri()); 25 | let mut resp = Response::new(Body::empty()); 26 | resp.headers_mut() 27 | .append(header::ACCESS_CONTROL_ALLOW_ORIGIN, ANY); 28 | resp.headers_mut() 29 | .append(header::ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_HEADERS); 30 | return Ok(resp); 31 | } 32 | 33 | let provided_key = match req.headers_mut().remove(X_RETRANSMITTED_KEY) { 34 | Some(k) => k, 35 | None => { 36 | log::info!("{} {} -> [missing key]", req.method(), req.uri()); 37 | let mut resp = Response::new(Body::empty()); 38 | *resp.status_mut() = StatusCode::UNAUTHORIZED; 39 | return Ok(resp); 40 | } 41 | }; 42 | match ring::constant_time::verify_slices_are_equal( 43 | provided_key.as_bytes(), 44 | state.secret_key.as_bytes(), 45 | ) { 46 | Ok(()) => {} 47 | Err(ring::error::Unspecified) => { 48 | log::warn!("{} {} -> [invalid key]", req.method(), req.uri()); 49 | let mut resp = Response::new(Body::empty()); 50 | *resp.status_mut() = StatusCode::UNAUTHORIZED; 51 | return Ok(resp); 52 | } 53 | } 54 | 55 | let uri = match extract_uri_from_path(req.uri()) { 56 | None => { 57 | log::warn!("{} {} -> [missing url]", req.method(), req.uri()); 58 | let mut resp = Response::new(Body::empty()); 59 | *resp.status_mut() = StatusCode::BAD_REQUEST; 60 | return Ok(resp); 61 | } 62 | Some(Err((e, unparsed))) => { 63 | log::warn!( 64 | "{} {} -> [invalid url] {:?} {}", 65 | req.method(), 66 | req.uri(), 67 | unparsed, 68 | e 69 | ); 70 | let mut resp = Response::new(Body::empty()); 71 | *resp.status_mut() = StatusCode::BAD_REQUEST; 72 | return Ok(resp); 73 | } 74 | Some(Ok(u)) => u, 75 | }; 76 | 77 | let orig_method = req.method().clone(); 78 | let orig_uri = mem::replace(req.uri_mut(), uri); 79 | let mut resp = match state.client.request(req).await { 80 | Ok(r) => r, 81 | Err(e) => { 82 | log::error!("{} {} -> [proxy error] {}", orig_method, orig_uri, e); 83 | let mut resp = Response::new(Body::empty()); 84 | *resp.status_mut() = StatusCode::BAD_GATEWAY; 85 | return Ok(resp); 86 | } 87 | }; 88 | 89 | log::info!("{} {} -> [success]", orig_method, orig_uri); 90 | resp.headers_mut() 91 | .append(header::ACCESS_CONTROL_ALLOW_ORIGIN, ANY); 92 | Ok(resp) 93 | } 94 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.1.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 10 | 11 | [[package]] 12 | name = "base64" 13 | version = "0.13.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 16 | 17 | [[package]] 18 | name = "bitflags" 19 | version = "1.3.2" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 22 | 23 | [[package]] 24 | name = "bumpalo" 25 | version = "3.9.1" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 28 | 29 | [[package]] 30 | name = "bytes" 31 | version = "1.1.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 34 | 35 | [[package]] 36 | name = "cc" 37 | version = "1.0.73" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 40 | 41 | [[package]] 42 | name = "cfg-if" 43 | version = "1.0.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 46 | 47 | [[package]] 48 | name = "clap" 49 | version = "2.34.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 52 | dependencies = [ 53 | "bitflags", 54 | "textwrap", 55 | "unicode-width", 56 | ] 57 | 58 | [[package]] 59 | name = "core-foundation" 60 | version = "0.9.3" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 63 | dependencies = [ 64 | "core-foundation-sys", 65 | "libc", 66 | ] 67 | 68 | [[package]] 69 | name = "core-foundation-sys" 70 | version = "0.8.3" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 73 | 74 | [[package]] 75 | name = "env_logger" 76 | version = "0.9.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 79 | dependencies = [ 80 | "humantime", 81 | "log", 82 | ] 83 | 84 | [[package]] 85 | name = "fnv" 86 | version = "1.0.7" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 89 | 90 | [[package]] 91 | name = "futures-channel" 92 | version = "0.3.21" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 95 | dependencies = [ 96 | "futures-core", 97 | ] 98 | 99 | [[package]] 100 | name = "futures-core" 101 | version = "0.3.21" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 104 | 105 | [[package]] 106 | name = "futures-sink" 107 | version = "0.3.21" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 110 | 111 | [[package]] 112 | name = "futures-task" 113 | version = "0.3.21" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 116 | 117 | [[package]] 118 | name = "futures-util" 119 | version = "0.3.21" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 122 | dependencies = [ 123 | "futures-core", 124 | "futures-task", 125 | "pin-project-lite", 126 | "pin-utils", 127 | ] 128 | 129 | [[package]] 130 | name = "h2" 131 | version = "0.3.13" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" 134 | dependencies = [ 135 | "bytes", 136 | "fnv", 137 | "futures-core", 138 | "futures-sink", 139 | "futures-util", 140 | "http", 141 | "indexmap", 142 | "slab", 143 | "tokio", 144 | "tokio-util", 145 | "tracing", 146 | ] 147 | 148 | [[package]] 149 | name = "hashbrown" 150 | version = "0.11.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 153 | 154 | [[package]] 155 | name = "heck" 156 | version = "0.3.3" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 159 | dependencies = [ 160 | "unicode-segmentation", 161 | ] 162 | 163 | [[package]] 164 | name = "http" 165 | version = "0.2.6" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" 168 | dependencies = [ 169 | "bytes", 170 | "fnv", 171 | "itoa", 172 | ] 173 | 174 | [[package]] 175 | name = "http-body" 176 | version = "0.4.4" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" 179 | dependencies = [ 180 | "bytes", 181 | "http", 182 | "pin-project-lite", 183 | ] 184 | 185 | [[package]] 186 | name = "httparse" 187 | version = "1.7.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" 190 | 191 | [[package]] 192 | name = "httpdate" 193 | version = "1.0.2" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 196 | 197 | [[package]] 198 | name = "humantime" 199 | version = "2.1.0" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 202 | 203 | [[package]] 204 | name = "hyper" 205 | version = "0.14.18" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" 208 | dependencies = [ 209 | "bytes", 210 | "futures-channel", 211 | "futures-core", 212 | "futures-util", 213 | "h2", 214 | "http", 215 | "http-body", 216 | "httparse", 217 | "httpdate", 218 | "itoa", 219 | "pin-project-lite", 220 | "socket2", 221 | "tokio", 222 | "tower-service", 223 | "tracing", 224 | "want", 225 | ] 226 | 227 | [[package]] 228 | name = "hyper-rustls" 229 | version = "0.23.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" 232 | dependencies = [ 233 | "http", 234 | "hyper", 235 | "log", 236 | "rustls", 237 | "rustls-native-certs", 238 | "tokio", 239 | "tokio-rustls", 240 | ] 241 | 242 | [[package]] 243 | name = "indexmap" 244 | version = "1.8.1" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" 247 | dependencies = [ 248 | "autocfg", 249 | "hashbrown", 250 | ] 251 | 252 | [[package]] 253 | name = "itoa" 254 | version = "1.0.1" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 257 | 258 | [[package]] 259 | name = "js-sys" 260 | version = "0.3.57" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" 263 | dependencies = [ 264 | "wasm-bindgen", 265 | ] 266 | 267 | [[package]] 268 | name = "lazy_static" 269 | version = "1.4.0" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 272 | 273 | [[package]] 274 | name = "libc" 275 | version = "0.2.124" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" 278 | 279 | [[package]] 280 | name = "log" 281 | version = "0.4.16" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 284 | dependencies = [ 285 | "cfg-if", 286 | ] 287 | 288 | [[package]] 289 | name = "memchr" 290 | version = "2.4.1" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 293 | 294 | [[package]] 295 | name = "mio" 296 | version = "0.8.2" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" 299 | dependencies = [ 300 | "libc", 301 | "log", 302 | "miow", 303 | "ntapi", 304 | "wasi", 305 | "winapi", 306 | ] 307 | 308 | [[package]] 309 | name = "miow" 310 | version = "0.3.7" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 313 | dependencies = [ 314 | "winapi", 315 | ] 316 | 317 | [[package]] 318 | name = "ntapi" 319 | version = "0.3.7" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 322 | dependencies = [ 323 | "winapi", 324 | ] 325 | 326 | [[package]] 327 | name = "once_cell" 328 | version = "1.10.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 331 | 332 | [[package]] 333 | name = "openssl-probe" 334 | version = "0.1.5" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 337 | 338 | [[package]] 339 | name = "pin-project-lite" 340 | version = "0.2.8" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 343 | 344 | [[package]] 345 | name = "pin-utils" 346 | version = "0.1.0" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 349 | 350 | [[package]] 351 | name = "proc-macro-error" 352 | version = "1.0.4" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 355 | dependencies = [ 356 | "proc-macro-error-attr", 357 | "proc-macro2", 358 | "quote", 359 | "syn", 360 | "version_check", 361 | ] 362 | 363 | [[package]] 364 | name = "proc-macro-error-attr" 365 | version = "1.0.4" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 368 | dependencies = [ 369 | "proc-macro2", 370 | "quote", 371 | "version_check", 372 | ] 373 | 374 | [[package]] 375 | name = "proc-macro2" 376 | version = "1.0.37" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 379 | dependencies = [ 380 | "unicode-xid", 381 | ] 382 | 383 | [[package]] 384 | name = "quote" 385 | version = "1.0.18" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 388 | dependencies = [ 389 | "proc-macro2", 390 | ] 391 | 392 | [[package]] 393 | name = "retransmitted" 394 | version = "0.2.1" 395 | dependencies = [ 396 | "env_logger", 397 | "hyper", 398 | "hyper-rustls", 399 | "log", 400 | "ring", 401 | "structopt", 402 | "thiserror", 403 | "tokio", 404 | ] 405 | 406 | [[package]] 407 | name = "ring" 408 | version = "0.16.20" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 411 | dependencies = [ 412 | "cc", 413 | "libc", 414 | "once_cell", 415 | "spin", 416 | "untrusted", 417 | "web-sys", 418 | "winapi", 419 | ] 420 | 421 | [[package]] 422 | name = "rustls" 423 | version = "0.20.4" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" 426 | dependencies = [ 427 | "log", 428 | "ring", 429 | "sct", 430 | "webpki", 431 | ] 432 | 433 | [[package]] 434 | name = "rustls-native-certs" 435 | version = "0.6.2" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" 438 | dependencies = [ 439 | "openssl-probe", 440 | "rustls-pemfile", 441 | "schannel", 442 | "security-framework", 443 | ] 444 | 445 | [[package]] 446 | name = "rustls-pemfile" 447 | version = "1.0.0" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" 450 | dependencies = [ 451 | "base64", 452 | ] 453 | 454 | [[package]] 455 | name = "schannel" 456 | version = "0.1.19" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 459 | dependencies = [ 460 | "lazy_static", 461 | "winapi", 462 | ] 463 | 464 | [[package]] 465 | name = "sct" 466 | version = "0.7.0" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 469 | dependencies = [ 470 | "ring", 471 | "untrusted", 472 | ] 473 | 474 | [[package]] 475 | name = "security-framework" 476 | version = "2.6.1" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" 479 | dependencies = [ 480 | "bitflags", 481 | "core-foundation", 482 | "core-foundation-sys", 483 | "libc", 484 | "security-framework-sys", 485 | ] 486 | 487 | [[package]] 488 | name = "security-framework-sys" 489 | version = "2.6.1" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 492 | dependencies = [ 493 | "core-foundation-sys", 494 | "libc", 495 | ] 496 | 497 | [[package]] 498 | name = "slab" 499 | version = "0.4.6" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" 502 | 503 | [[package]] 504 | name = "socket2" 505 | version = "0.4.4" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 508 | dependencies = [ 509 | "libc", 510 | "winapi", 511 | ] 512 | 513 | [[package]] 514 | name = "spin" 515 | version = "0.5.2" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 518 | 519 | [[package]] 520 | name = "structopt" 521 | version = "0.3.26" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" 524 | dependencies = [ 525 | "clap", 526 | "lazy_static", 527 | "structopt-derive", 528 | ] 529 | 530 | [[package]] 531 | name = "structopt-derive" 532 | version = "0.4.18" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" 535 | dependencies = [ 536 | "heck", 537 | "proc-macro-error", 538 | "proc-macro2", 539 | "quote", 540 | "syn", 541 | ] 542 | 543 | [[package]] 544 | name = "syn" 545 | version = "1.0.91" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 548 | dependencies = [ 549 | "proc-macro2", 550 | "quote", 551 | "unicode-xid", 552 | ] 553 | 554 | [[package]] 555 | name = "textwrap" 556 | version = "0.11.0" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 559 | dependencies = [ 560 | "unicode-width", 561 | ] 562 | 563 | [[package]] 564 | name = "thiserror" 565 | version = "1.0.30" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 568 | dependencies = [ 569 | "thiserror-impl", 570 | ] 571 | 572 | [[package]] 573 | name = "thiserror-impl" 574 | version = "1.0.30" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 577 | dependencies = [ 578 | "proc-macro2", 579 | "quote", 580 | "syn", 581 | ] 582 | 583 | [[package]] 584 | name = "tokio" 585 | version = "1.17.0" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" 588 | dependencies = [ 589 | "bytes", 590 | "libc", 591 | "memchr", 592 | "mio", 593 | "pin-project-lite", 594 | "socket2", 595 | "tokio-macros", 596 | "winapi", 597 | ] 598 | 599 | [[package]] 600 | name = "tokio-macros" 601 | version = "1.7.0" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" 604 | dependencies = [ 605 | "proc-macro2", 606 | "quote", 607 | "syn", 608 | ] 609 | 610 | [[package]] 611 | name = "tokio-rustls" 612 | version = "0.23.3" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e" 615 | dependencies = [ 616 | "rustls", 617 | "tokio", 618 | "webpki", 619 | ] 620 | 621 | [[package]] 622 | name = "tokio-util" 623 | version = "0.7.1" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" 626 | dependencies = [ 627 | "bytes", 628 | "futures-core", 629 | "futures-sink", 630 | "pin-project-lite", 631 | "tokio", 632 | "tracing", 633 | ] 634 | 635 | [[package]] 636 | name = "tower-service" 637 | version = "0.3.1" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 640 | 641 | [[package]] 642 | name = "tracing" 643 | version = "0.1.34" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" 646 | dependencies = [ 647 | "cfg-if", 648 | "pin-project-lite", 649 | "tracing-attributes", 650 | "tracing-core", 651 | ] 652 | 653 | [[package]] 654 | name = "tracing-attributes" 655 | version = "0.1.20" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 658 | dependencies = [ 659 | "proc-macro2", 660 | "quote", 661 | "syn", 662 | ] 663 | 664 | [[package]] 665 | name = "tracing-core" 666 | version = "0.1.26" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" 669 | dependencies = [ 670 | "lazy_static", 671 | ] 672 | 673 | [[package]] 674 | name = "try-lock" 675 | version = "0.2.3" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 678 | 679 | [[package]] 680 | name = "unicode-segmentation" 681 | version = "1.9.0" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 684 | 685 | [[package]] 686 | name = "unicode-width" 687 | version = "0.1.9" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 690 | 691 | [[package]] 692 | name = "unicode-xid" 693 | version = "0.2.2" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 696 | 697 | [[package]] 698 | name = "untrusted" 699 | version = "0.7.1" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 702 | 703 | [[package]] 704 | name = "version_check" 705 | version = "0.9.4" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 708 | 709 | [[package]] 710 | name = "want" 711 | version = "0.3.0" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 714 | dependencies = [ 715 | "log", 716 | "try-lock", 717 | ] 718 | 719 | [[package]] 720 | name = "wasi" 721 | version = "0.11.0+wasi-snapshot-preview1" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 724 | 725 | [[package]] 726 | name = "wasm-bindgen" 727 | version = "0.2.80" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" 730 | dependencies = [ 731 | "cfg-if", 732 | "wasm-bindgen-macro", 733 | ] 734 | 735 | [[package]] 736 | name = "wasm-bindgen-backend" 737 | version = "0.2.80" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" 740 | dependencies = [ 741 | "bumpalo", 742 | "lazy_static", 743 | "log", 744 | "proc-macro2", 745 | "quote", 746 | "syn", 747 | "wasm-bindgen-shared", 748 | ] 749 | 750 | [[package]] 751 | name = "wasm-bindgen-macro" 752 | version = "0.2.80" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" 755 | dependencies = [ 756 | "quote", 757 | "wasm-bindgen-macro-support", 758 | ] 759 | 760 | [[package]] 761 | name = "wasm-bindgen-macro-support" 762 | version = "0.2.80" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" 765 | dependencies = [ 766 | "proc-macro2", 767 | "quote", 768 | "syn", 769 | "wasm-bindgen-backend", 770 | "wasm-bindgen-shared", 771 | ] 772 | 773 | [[package]] 774 | name = "wasm-bindgen-shared" 775 | version = "0.2.80" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" 778 | 779 | [[package]] 780 | name = "web-sys" 781 | version = "0.3.57" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" 784 | dependencies = [ 785 | "js-sys", 786 | "wasm-bindgen", 787 | ] 788 | 789 | [[package]] 790 | name = "webpki" 791 | version = "0.22.0" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" 794 | dependencies = [ 795 | "ring", 796 | "untrusted", 797 | ] 798 | 799 | [[package]] 800 | name = "winapi" 801 | version = "0.3.9" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 804 | dependencies = [ 805 | "winapi-i686-pc-windows-gnu", 806 | "winapi-x86_64-pc-windows-gnu", 807 | ] 808 | 809 | [[package]] 810 | name = "winapi-i686-pc-windows-gnu" 811 | version = "0.4.0" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 814 | 815 | [[package]] 816 | name = "winapi-x86_64-pc-windows-gnu" 817 | version = "0.4.0" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 820 | --------------------------------------------------------------------------------