├── README.md ├── .gitignore ├── src ├── macros.rs ├── err.rs ├── file.rs ├── main.rs ├── server.rs ├── opt.rs ├── routes.rs └── redir.rs ├── Cargo.toml ├── LICENSE ├── .github └── workflows │ └── ci.yml └── Cargo.lock /README.md: -------------------------------------------------------------------------------- 1 | # redirected 2 | Redirect local traffic somewhere else. 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/macros.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | macro_rules! case { 3 | ( $name:ident : $body:expr ) => { 4 | #[test] 5 | fn $name() { 6 | $body 7 | } 8 | }; 9 | } 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 | -------------------------------------------------------------------------------- /src/file.rs: -------------------------------------------------------------------------------- 1 | use futures::stream; 2 | use hyper::Body; 3 | use tokio::fs::File; 4 | use tokio::io::AsyncReadExt; 5 | 6 | pub fn body_stream(file: File) -> Body { 7 | Body::wrap_stream(stream::try_unfold(file, { 8 | let mut buf = [0; 4 * 1024]; 9 | move |mut file| async move { 10 | match file.read(&mut buf).await { 11 | Ok(0) => Ok(None), 12 | Ok(n) => Ok(Some((buf[..n].to_vec(), file))), 13 | Err(e) => Err(e), 14 | } 15 | } 16 | })) 17 | } 18 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "redirected" 3 | version = "0.5.4" 4 | authors = [] 5 | description = "Redirect local traffic somewhere else." 6 | edition = "2018" 7 | 8 | [dependencies] 9 | env_logger = { version = "0.9", default-features = false, features = ["humantime"] } 10 | futures = "0.3" 11 | http = "0.2" 12 | hyper = { version = "0.14", features = ["client", "server", "http1", "tcp", "stream"] } 13 | hyper-rustls = "0.23" 14 | log = "0.4" 15 | structopt = { version = "0.3", default-features = false } 16 | thiserror = "1.0" 17 | tokio = { version = "1.0" , features = ["fs", "io-util", "macros", "rt"] } 18 | 19 | [profile.release] 20 | panic = "abort" 21 | lto = true 22 | codegen-units = 1 23 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | mod macros; 3 | 4 | mod err; 5 | mod file; 6 | mod opt; 7 | mod redir; 8 | mod routes; 9 | mod server; 10 | 11 | use structopt::StructOpt; 12 | 13 | use crate::redir::Rules; 14 | 15 | #[tokio::main(flavor = "current_thread")] 16 | async fn main() -> Result<(), err::DisplayError> { 17 | let opt::Options { 18 | verbose, 19 | listen_addr, 20 | from, 21 | to, 22 | } = opt::Options::from_args(); 23 | 24 | env_logger::Builder::new() 25 | .filter_level(match verbose { 26 | 0 => log::LevelFilter::Warn, 27 | 1 => log::LevelFilter::Info, 28 | 2 => log::LevelFilter::Debug, 29 | _ => log::LevelFilter::Trace, 30 | }) 31 | .init(); 32 | 33 | server::run(&listen_addr, Rules::zip(from, to)?).await?; 34 | 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /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 std::convert::Infallible; 2 | use std::net::SocketAddr; 3 | use std::sync::Arc; 4 | 5 | use hyper::service::{make_service_fn, service_fn}; 6 | use hyper::{Client, Server}; 7 | use hyper_rustls::HttpsConnectorBuilder; 8 | 9 | use crate::err::Error; 10 | use crate::redir::Rules; 11 | use crate::routes::{respond_to_request, State}; 12 | 13 | pub async fn run(addr: &SocketAddr, rules: Rules) -> Result<(), Error> { 14 | let client = Client::builder().build( 15 | HttpsConnectorBuilder::new() 16 | .with_native_roots() 17 | .https_or_http() 18 | .enable_http1() 19 | .build(), 20 | ); 21 | 22 | let state = Arc::new(State::new(client, rules)); 23 | let make_svc = make_service_fn(move |_| { 24 | let state = Arc::clone(&state); 25 | let svc = service_fn(move |req| { 26 | let state = Arc::clone(&state); 27 | async move { respond_to_request(req, &state).await } 28 | }); 29 | async move { Ok::<_, Infallible>(svc) } 30 | }); 31 | 32 | Server::try_bind(addr)?.serve(make_svc).await?; 33 | 34 | Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /src/opt.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | 3 | use structopt::StructOpt; 4 | 5 | use crate::redir::{From, To}; 6 | 7 | #[derive(StructOpt, Debug)] 8 | #[structopt(about)] 9 | pub struct Options { 10 | #[structopt( 11 | short = "v", 12 | long = "verbose", 13 | parse(from_occurrences), 14 | global = true, 15 | help = "Logging verbosity (-v info, -vv debug, -vvv trace)" 16 | )] 17 | pub verbose: u8, 18 | 19 | #[structopt( 20 | help = "Socket address to listen on (--help for more)", 21 | long_help = r"Socket address to listen on: 22 | - incoming http connections are received on this socket 23 | Examples: 24 | - 127.0.0.1:3000 25 | - 0.0.0.0:80 26 | - [2001:db8::1]:8080" 27 | )] 28 | pub listen_addr: SocketAddr, 29 | 30 | #[structopt( 31 | short = "f", 32 | long = "from", 33 | required = true, 34 | parse(try_from_str), 35 | help = "Path prefixes to redirect from (--help for more)", 36 | long_help = r"Path prefixes to redirect from: 37 | - each prefix is checked in order, and the first match is chosen 38 | - 404s if no prefixes match 39 | Examples: 40 | - / 41 | - /resources/static/" 42 | )] 43 | pub from: Vec, 44 | 45 | #[structopt( 46 | short = "t", 47 | long = "to", 48 | required = true, 49 | parse(try_from_str), 50 | help = "Address prefixes to redirect to (--help for more)", 51 | long_help = r"Address prefixes to redirect to: 52 | - each matching request's tail is appended to the corresponding address prefix 53 | - some schemes have special behavior 54 | Examples: 55 | - http://localhost:8080/services/api/ 56 | - https://test.dev/v1/ 57 | - file://./static/ 58 | - file://./static/|./static/index.html (fallback to ./static/index.html) 59 | - status://404 (empty response with status 404)" 60 | )] 61 | pub to: Vec, 62 | } 63 | -------------------------------------------------------------------------------- /.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/redirected 52 | - run: ls -lh target/x86_64-unknown-linux-musl/release/redirected 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/redirected 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/redirected.exe 71 | - uses: softprops/action-gh-release@v1 72 | if: startsWith(github.ref, 'refs/tags/') 73 | with: 74 | files: target/release/redirected.exe 75 | env: 76 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 77 | -------------------------------------------------------------------------------- /src/routes.rs: -------------------------------------------------------------------------------- 1 | use hyper::client::HttpConnector; 2 | use hyper::{Body, Client, Request, Response, StatusCode}; 3 | use hyper_rustls::HttpsConnector; 4 | use tokio::fs::File; 5 | 6 | use crate::file; 7 | use crate::redir::{Action, Rules}; 8 | 9 | pub struct State { 10 | client: Client>, 11 | rules: Rules, 12 | } 13 | 14 | impl State { 15 | pub fn new(client: Client>, rules: Rules) -> Self { 16 | Self { client, rules } 17 | } 18 | } 19 | 20 | pub async fn respond_to_request( 21 | mut req: Request, 22 | state: &State, 23 | ) -> Result, hyper::Error> { 24 | match state.rules.try_match(req.uri()) { 25 | Some(Ok(Action::Http(uri))) => { 26 | log::info!("{} -> {}", req.uri(), uri); 27 | *req.uri_mut() = uri; 28 | state.client.request(req).await 29 | } 30 | Some(Ok(Action::File { path, fallback })) => { 31 | let found_file = match File::open(&path).await { 32 | Ok(file) => Ok((path, file)), 33 | Err(e) => match fallback { 34 | Some(fallback) => match File::open(&fallback).await { 35 | Ok(file) => Ok((fallback, file)), 36 | Err(_) => Err((path, e)), 37 | }, 38 | None => Err((path, e)), 39 | }, 40 | }; 41 | match found_file { 42 | Ok((found_path, file)) => { 43 | log::info!("{} -> {}", req.uri(), found_path.display()); 44 | Ok(Response::new(file::body_stream(file))) 45 | } 46 | Err((path, e)) => { 47 | log::warn!("{} -> [file error] {} : {}", req.uri(), path.display(), e); 48 | let mut resp = Response::new(Body::empty()); 49 | *resp.status_mut() = StatusCode::NOT_FOUND; 50 | Ok(resp) 51 | } 52 | } 53 | } 54 | Some(Ok(Action::Status(status))) => { 55 | log::info!("{} -> {}", req.uri(), status); 56 | let mut resp = Response::new(Body::empty()); 57 | *resp.status_mut() = status; 58 | Ok(resp) 59 | } 60 | Some(Err(e)) => { 61 | log::warn!("{} -> [internal error] : {}", req.uri(), e); 62 | let mut resp = Response::new(Body::empty()); 63 | *resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; 64 | Ok(resp) 65 | } 66 | None => { 67 | log::warn!("{} -> [no match]", req.uri()); 68 | let mut resp = Response::new(Body::empty()); 69 | *resp.status_mut() = StatusCode::BAD_GATEWAY; 70 | Ok(resp) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/redir.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use std::str::FromStr; 3 | 4 | use http::status::InvalidStatusCode; 5 | use http::uri::InvalidUri; 6 | use hyper::{StatusCode, Uri}; 7 | use thiserror::Error; 8 | 9 | #[derive(Debug)] 10 | pub struct From(String); 11 | 12 | #[derive(Debug, Error)] 13 | pub enum BadRedirectFrom { 14 | #[error("path does not start with slash")] 15 | NoLeadingSlash, 16 | #[error("path does not end with slash")] 17 | NoTrailingSlash, 18 | } 19 | 20 | impl FromStr for From { 21 | type Err = BadRedirectFrom; 22 | fn from_str(s: &str) -> Result { 23 | match () { 24 | _ if !s.starts_with('/') => Err(BadRedirectFrom::NoLeadingSlash), 25 | _ if !s.ends_with('/') => Err(BadRedirectFrom::NoTrailingSlash), 26 | _ => Ok(From(s.to_string())), 27 | } 28 | } 29 | } 30 | 31 | #[derive(Debug)] 32 | pub enum To { 33 | Http(String), 34 | File(PathBuf, Option), 35 | Status(StatusCode), 36 | } 37 | 38 | #[derive(Debug, Error)] 39 | pub enum BadRedirectTo { 40 | #[error("invalid uri: {0}")] 41 | InvalidUri(InvalidUri), 42 | #[error("invalid scheme: {0}")] 43 | InvalidScheme(String), 44 | #[error("invalid status code: {0}")] 45 | InvalidStatus(InvalidStatusCode), 46 | #[error("too many fallbacks provided")] 47 | TooManyFallbacks, 48 | #[error("fallback not allowed: {0}")] 49 | FallbackNotAllowed(String), 50 | #[error("path does not end with slash")] 51 | NoTrailingSlash, 52 | #[error("does not begin with scheme")] 53 | NoScheme, 54 | } 55 | 56 | impl FromStr for To { 57 | type Err = BadRedirectTo; 58 | fn from_str(to_str: &str) -> Result { 59 | let (path, fallback) = { 60 | let mut parts = to_str.split('|').fuse(); 61 | match (parts.next(), parts.next(), parts.next()) { 62 | (Some(path), fallback, None) => (path, fallback), 63 | _ => return Err(BadRedirectTo::TooManyFallbacks), 64 | } 65 | }; 66 | 67 | match path.parse::() { 68 | Ok(uri) => match (uri.scheme().map(|s| s.as_str()), fallback) { 69 | (Some("http"), None) | (Some("https"), None) => { 70 | let uri = uri.to_string(); 71 | match () { 72 | _ if !uri.ends_with('/') => Err(BadRedirectTo::NoTrailingSlash), 73 | _ => Ok(To::Http(uri)), 74 | } 75 | } 76 | (Some("file"), fallback) => { 77 | let uri = uri.authority().map_or("", |a| a.as_str()).to_string() + uri.path(); 78 | match () { 79 | _ if !uri.ends_with('/') => Err(BadRedirectTo::NoTrailingSlash), 80 | _ => Ok(To::File(PathBuf::from(uri), fallback.map(PathBuf::from))), 81 | } 82 | } 83 | (Some("status"), None) => { 84 | match StatusCode::from_bytes( 85 | uri.authority().map_or("", |a| a.as_str()).as_bytes(), 86 | ) { 87 | Ok(status) => Ok(To::Status(status)), 88 | Err(e) => Err(BadRedirectTo::InvalidStatus(e)), 89 | } 90 | } 91 | (Some(scheme), None) => Err(BadRedirectTo::InvalidScheme(scheme.to_string())), 92 | (Some(_), Some(fallback)) => { 93 | Err(BadRedirectTo::FallbackNotAllowed(fallback.to_string())) 94 | } 95 | (None, _) => Err(BadRedirectTo::NoScheme), 96 | }, 97 | Err(e) => Err(BadRedirectTo::InvalidUri(e)), 98 | } 99 | } 100 | } 101 | 102 | #[derive(Debug, Error)] 103 | pub enum BadRedirect { 104 | #[error("unequal number of `from` and `to` arguments")] 105 | UnequalFromTo, 106 | } 107 | 108 | #[derive(Debug)] 109 | pub struct Rules { 110 | redirects: Vec<(From, To)>, 111 | } 112 | 113 | impl Rules { 114 | pub fn zip(from: Vec, to: Vec) -> Result { 115 | if from.len() == to.len() { 116 | Ok(Self { 117 | redirects: from.into_iter().zip(to).collect(), 118 | }) 119 | } else { 120 | Err(BadRedirect::UnequalFromTo) 121 | } 122 | } 123 | 124 | pub fn try_match(&self, uri: &Uri) -> Option> { 125 | self.redirects.iter().find_map(|(from, to)| { 126 | let req_path = match to { 127 | To::Http(..) => uri.path_and_query()?.as_str(), 128 | To::File(..) | To::Status(..) => uri.path(), 129 | }; 130 | req_path.strip_prefix(from.0.as_str()).map(|req_tail| { 131 | Ok(match to { 132 | To::Http(prefix) => Action::Http((prefix.to_string() + req_tail).parse()?), 133 | To::File(prefix, fallback) => Action::File { 134 | path: prefix.join(req_tail), 135 | fallback: fallback.clone(), 136 | }, 137 | To::Status(status) => Action::Status(*status), 138 | }) 139 | }) 140 | }) 141 | } 142 | } 143 | 144 | pub enum Action { 145 | Http(Uri), 146 | File { 147 | path: PathBuf, 148 | fallback: Option, 149 | }, 150 | Status(StatusCode), 151 | } 152 | 153 | #[cfg(test)] 154 | #[rustfmt::skip] 155 | mod tests { 156 | use super::*; 157 | 158 | case!(from_just_slash: assert!(matches!(From::from_str("/"), Ok(_)))); 159 | case!(from_slash_api: assert!(matches!(From::from_str("/api/"), Ok(_)))); 160 | case!(from_multi_slash: assert!(matches!(From::from_str("/resources/static/"), Ok(_)))); 161 | 162 | case!(from_no_leading: assert!(matches!(From::from_str("foo/"), Err(BadRedirectFrom::NoLeadingSlash)))); 163 | case!(from_no_trailing: assert!(matches!(From::from_str("/foo"), Err(BadRedirectFrom::NoTrailingSlash)))); 164 | 165 | case!(to_localhost: assert!(matches!(To::from_str("http://localhost:3000/"), Ok(To::Http(_))))); 166 | case!(to_localhost_path: assert!(matches!(To::from_str("http://localhost:8080/services/api/"), Ok(To::Http(_))))); 167 | case!(to_localhost_https: assert!(matches!(To::from_str("https://localhost:8080/"), Ok(To::Http(_))))); 168 | case!(to_file: assert!(matches!(To::from_str("file://./"), Ok(To::File(_, None))))); 169 | case!(to_file_path: assert!(matches!(To::from_str("file://./static/"), Ok(To::File(_, None))))); 170 | case!(to_file_fallback: assert!(matches!(To::from_str("file://./static/|./static/index.html"), Ok(To::File(_, Some(_)))))); 171 | 172 | case!(to_bad_uri: assert!(matches!(To::from_str("example.com/"), Err(BadRedirectTo::InvalidUri(_))))); 173 | case!(to_bad_scheme: assert!(matches!(To::from_str("ftp://example.com/"), Err(BadRedirectTo::InvalidScheme(_))))); 174 | case!(to_many_fallbacks: assert!(matches!(To::from_str("file://./|./|./"), Err(BadRedirectTo::TooManyFallbacks)))); 175 | case!(to_bad_fallback: assert!(matches!(To::from_str("http://example.com/|./"), Err(BadRedirectTo::FallbackNotAllowed(_))))); 176 | case!(to_no_trailing: assert!(matches!(To::from_str("http://example.com/foo"), Err(BadRedirectTo::NoTrailingSlash)))); 177 | case!(to_no_scheme: assert!(matches!(To::from_str("/foo"), Err(BadRedirectTo::NoScheme)))); 178 | 179 | case!(rules_zip_unequal: assert!(matches!(Rules::zip(vec![From("/".to_string())], vec![]), Err(_)))); 180 | case!(rules_zip: assert!(matches!(Rules::zip(vec![From("/".to_string())], vec![To::Http("/".to_string())]), Ok(_)))); 181 | } 182 | -------------------------------------------------------------------------------- /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 = "base64" 7 | version = "0.13.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 10 | 11 | [[package]] 12 | name = "bitflags" 13 | version = "1.3.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 16 | 17 | [[package]] 18 | name = "bumpalo" 19 | version = "3.9.1" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 22 | 23 | [[package]] 24 | name = "bytes" 25 | version = "1.1.0" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 28 | 29 | [[package]] 30 | name = "cc" 31 | version = "1.0.73" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 34 | 35 | [[package]] 36 | name = "cfg-if" 37 | version = "1.0.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 40 | 41 | [[package]] 42 | name = "clap" 43 | version = "2.34.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 46 | dependencies = [ 47 | "bitflags", 48 | "textwrap", 49 | "unicode-width", 50 | ] 51 | 52 | [[package]] 53 | name = "core-foundation" 54 | version = "0.9.3" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 57 | dependencies = [ 58 | "core-foundation-sys", 59 | "libc", 60 | ] 61 | 62 | [[package]] 63 | name = "core-foundation-sys" 64 | version = "0.8.3" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 67 | 68 | [[package]] 69 | name = "env_logger" 70 | version = "0.9.0" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 73 | dependencies = [ 74 | "humantime", 75 | "log", 76 | ] 77 | 78 | [[package]] 79 | name = "fnv" 80 | version = "1.0.7" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 83 | 84 | [[package]] 85 | name = "futures" 86 | version = "0.3.21" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" 89 | dependencies = [ 90 | "futures-channel", 91 | "futures-core", 92 | "futures-executor", 93 | "futures-io", 94 | "futures-sink", 95 | "futures-task", 96 | "futures-util", 97 | ] 98 | 99 | [[package]] 100 | name = "futures-channel" 101 | version = "0.3.21" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 104 | dependencies = [ 105 | "futures-core", 106 | "futures-sink", 107 | ] 108 | 109 | [[package]] 110 | name = "futures-core" 111 | version = "0.3.21" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 114 | 115 | [[package]] 116 | name = "futures-executor" 117 | version = "0.3.21" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" 120 | dependencies = [ 121 | "futures-core", 122 | "futures-task", 123 | "futures-util", 124 | ] 125 | 126 | [[package]] 127 | name = "futures-io" 128 | version = "0.3.21" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 131 | 132 | [[package]] 133 | name = "futures-macro" 134 | version = "0.3.21" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" 137 | dependencies = [ 138 | "proc-macro2", 139 | "quote", 140 | "syn", 141 | ] 142 | 143 | [[package]] 144 | name = "futures-sink" 145 | version = "0.3.21" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 148 | 149 | [[package]] 150 | name = "futures-task" 151 | version = "0.3.21" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 154 | 155 | [[package]] 156 | name = "futures-util" 157 | version = "0.3.21" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 160 | dependencies = [ 161 | "futures-channel", 162 | "futures-core", 163 | "futures-io", 164 | "futures-macro", 165 | "futures-sink", 166 | "futures-task", 167 | "memchr", 168 | "pin-project-lite", 169 | "pin-utils", 170 | "slab", 171 | ] 172 | 173 | [[package]] 174 | name = "heck" 175 | version = "0.3.3" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 178 | dependencies = [ 179 | "unicode-segmentation", 180 | ] 181 | 182 | [[package]] 183 | name = "http" 184 | version = "0.2.6" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" 187 | dependencies = [ 188 | "bytes", 189 | "fnv", 190 | "itoa", 191 | ] 192 | 193 | [[package]] 194 | name = "http-body" 195 | version = "0.4.4" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" 198 | dependencies = [ 199 | "bytes", 200 | "http", 201 | "pin-project-lite", 202 | ] 203 | 204 | [[package]] 205 | name = "httparse" 206 | version = "1.7.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" 209 | 210 | [[package]] 211 | name = "httpdate" 212 | version = "1.0.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 215 | 216 | [[package]] 217 | name = "humantime" 218 | version = "2.1.0" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 221 | 222 | [[package]] 223 | name = "hyper" 224 | version = "0.14.18" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" 227 | dependencies = [ 228 | "bytes", 229 | "futures-channel", 230 | "futures-core", 231 | "futures-util", 232 | "http", 233 | "http-body", 234 | "httparse", 235 | "httpdate", 236 | "itoa", 237 | "pin-project-lite", 238 | "socket2", 239 | "tokio", 240 | "tower-service", 241 | "tracing", 242 | "want", 243 | ] 244 | 245 | [[package]] 246 | name = "hyper-rustls" 247 | version = "0.23.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" 250 | dependencies = [ 251 | "http", 252 | "hyper", 253 | "log", 254 | "rustls", 255 | "rustls-native-certs", 256 | "tokio", 257 | "tokio-rustls", 258 | ] 259 | 260 | [[package]] 261 | name = "itoa" 262 | version = "1.0.1" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 265 | 266 | [[package]] 267 | name = "js-sys" 268 | version = "0.3.57" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" 271 | dependencies = [ 272 | "wasm-bindgen", 273 | ] 274 | 275 | [[package]] 276 | name = "lazy_static" 277 | version = "1.4.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 280 | 281 | [[package]] 282 | name = "libc" 283 | version = "0.2.124" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" 286 | 287 | [[package]] 288 | name = "log" 289 | version = "0.4.16" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 292 | dependencies = [ 293 | "cfg-if", 294 | ] 295 | 296 | [[package]] 297 | name = "memchr" 298 | version = "2.4.1" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 301 | 302 | [[package]] 303 | name = "mio" 304 | version = "0.8.2" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" 307 | dependencies = [ 308 | "libc", 309 | "log", 310 | "miow", 311 | "ntapi", 312 | "wasi", 313 | "winapi", 314 | ] 315 | 316 | [[package]] 317 | name = "miow" 318 | version = "0.3.7" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 321 | dependencies = [ 322 | "winapi", 323 | ] 324 | 325 | [[package]] 326 | name = "ntapi" 327 | version = "0.3.7" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 330 | dependencies = [ 331 | "winapi", 332 | ] 333 | 334 | [[package]] 335 | name = "once_cell" 336 | version = "1.10.0" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 339 | 340 | [[package]] 341 | name = "openssl-probe" 342 | version = "0.1.5" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 345 | 346 | [[package]] 347 | name = "pin-project-lite" 348 | version = "0.2.8" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 351 | 352 | [[package]] 353 | name = "pin-utils" 354 | version = "0.1.0" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 357 | 358 | [[package]] 359 | name = "proc-macro-error" 360 | version = "1.0.4" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 363 | dependencies = [ 364 | "proc-macro-error-attr", 365 | "proc-macro2", 366 | "quote", 367 | "syn", 368 | "version_check", 369 | ] 370 | 371 | [[package]] 372 | name = "proc-macro-error-attr" 373 | version = "1.0.4" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 376 | dependencies = [ 377 | "proc-macro2", 378 | "quote", 379 | "version_check", 380 | ] 381 | 382 | [[package]] 383 | name = "proc-macro2" 384 | version = "1.0.37" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 387 | dependencies = [ 388 | "unicode-xid", 389 | ] 390 | 391 | [[package]] 392 | name = "quote" 393 | version = "1.0.18" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 396 | dependencies = [ 397 | "proc-macro2", 398 | ] 399 | 400 | [[package]] 401 | name = "redirected" 402 | version = "0.5.4" 403 | dependencies = [ 404 | "env_logger", 405 | "futures", 406 | "http", 407 | "hyper", 408 | "hyper-rustls", 409 | "log", 410 | "structopt", 411 | "thiserror", 412 | "tokio", 413 | ] 414 | 415 | [[package]] 416 | name = "ring" 417 | version = "0.16.20" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 420 | dependencies = [ 421 | "cc", 422 | "libc", 423 | "once_cell", 424 | "spin", 425 | "untrusted", 426 | "web-sys", 427 | "winapi", 428 | ] 429 | 430 | [[package]] 431 | name = "rustls" 432 | version = "0.20.4" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" 435 | dependencies = [ 436 | "log", 437 | "ring", 438 | "sct", 439 | "webpki", 440 | ] 441 | 442 | [[package]] 443 | name = "rustls-native-certs" 444 | version = "0.6.2" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" 447 | dependencies = [ 448 | "openssl-probe", 449 | "rustls-pemfile", 450 | "schannel", 451 | "security-framework", 452 | ] 453 | 454 | [[package]] 455 | name = "rustls-pemfile" 456 | version = "1.0.0" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" 459 | dependencies = [ 460 | "base64", 461 | ] 462 | 463 | [[package]] 464 | name = "schannel" 465 | version = "0.1.19" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 468 | dependencies = [ 469 | "lazy_static", 470 | "winapi", 471 | ] 472 | 473 | [[package]] 474 | name = "sct" 475 | version = "0.7.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 478 | dependencies = [ 479 | "ring", 480 | "untrusted", 481 | ] 482 | 483 | [[package]] 484 | name = "security-framework" 485 | version = "2.6.1" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" 488 | dependencies = [ 489 | "bitflags", 490 | "core-foundation", 491 | "core-foundation-sys", 492 | "libc", 493 | "security-framework-sys", 494 | ] 495 | 496 | [[package]] 497 | name = "security-framework-sys" 498 | version = "2.6.1" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 501 | dependencies = [ 502 | "core-foundation-sys", 503 | "libc", 504 | ] 505 | 506 | [[package]] 507 | name = "slab" 508 | version = "0.4.6" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" 511 | 512 | [[package]] 513 | name = "socket2" 514 | version = "0.4.4" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 517 | dependencies = [ 518 | "libc", 519 | "winapi", 520 | ] 521 | 522 | [[package]] 523 | name = "spin" 524 | version = "0.5.2" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 527 | 528 | [[package]] 529 | name = "structopt" 530 | version = "0.3.26" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" 533 | dependencies = [ 534 | "clap", 535 | "lazy_static", 536 | "structopt-derive", 537 | ] 538 | 539 | [[package]] 540 | name = "structopt-derive" 541 | version = "0.4.18" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" 544 | dependencies = [ 545 | "heck", 546 | "proc-macro-error", 547 | "proc-macro2", 548 | "quote", 549 | "syn", 550 | ] 551 | 552 | [[package]] 553 | name = "syn" 554 | version = "1.0.91" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 557 | dependencies = [ 558 | "proc-macro2", 559 | "quote", 560 | "unicode-xid", 561 | ] 562 | 563 | [[package]] 564 | name = "textwrap" 565 | version = "0.11.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 568 | dependencies = [ 569 | "unicode-width", 570 | ] 571 | 572 | [[package]] 573 | name = "thiserror" 574 | version = "1.0.30" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 577 | dependencies = [ 578 | "thiserror-impl", 579 | ] 580 | 581 | [[package]] 582 | name = "thiserror-impl" 583 | version = "1.0.30" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 586 | dependencies = [ 587 | "proc-macro2", 588 | "quote", 589 | "syn", 590 | ] 591 | 592 | [[package]] 593 | name = "tokio" 594 | version = "1.17.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" 597 | dependencies = [ 598 | "bytes", 599 | "libc", 600 | "memchr", 601 | "mio", 602 | "pin-project-lite", 603 | "socket2", 604 | "tokio-macros", 605 | "winapi", 606 | ] 607 | 608 | [[package]] 609 | name = "tokio-macros" 610 | version = "1.7.0" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" 613 | dependencies = [ 614 | "proc-macro2", 615 | "quote", 616 | "syn", 617 | ] 618 | 619 | [[package]] 620 | name = "tokio-rustls" 621 | version = "0.23.3" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e" 624 | dependencies = [ 625 | "rustls", 626 | "tokio", 627 | "webpki", 628 | ] 629 | 630 | [[package]] 631 | name = "tower-service" 632 | version = "0.3.1" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 635 | 636 | [[package]] 637 | name = "tracing" 638 | version = "0.1.34" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" 641 | dependencies = [ 642 | "cfg-if", 643 | "pin-project-lite", 644 | "tracing-core", 645 | ] 646 | 647 | [[package]] 648 | name = "tracing-core" 649 | version = "0.1.26" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" 652 | dependencies = [ 653 | "lazy_static", 654 | ] 655 | 656 | [[package]] 657 | name = "try-lock" 658 | version = "0.2.3" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 661 | 662 | [[package]] 663 | name = "unicode-segmentation" 664 | version = "1.9.0" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 667 | 668 | [[package]] 669 | name = "unicode-width" 670 | version = "0.1.9" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 673 | 674 | [[package]] 675 | name = "unicode-xid" 676 | version = "0.2.2" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 679 | 680 | [[package]] 681 | name = "untrusted" 682 | version = "0.7.1" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 685 | 686 | [[package]] 687 | name = "version_check" 688 | version = "0.9.4" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 691 | 692 | [[package]] 693 | name = "want" 694 | version = "0.3.0" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 697 | dependencies = [ 698 | "log", 699 | "try-lock", 700 | ] 701 | 702 | [[package]] 703 | name = "wasi" 704 | version = "0.11.0+wasi-snapshot-preview1" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 707 | 708 | [[package]] 709 | name = "wasm-bindgen" 710 | version = "0.2.80" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" 713 | dependencies = [ 714 | "cfg-if", 715 | "wasm-bindgen-macro", 716 | ] 717 | 718 | [[package]] 719 | name = "wasm-bindgen-backend" 720 | version = "0.2.80" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" 723 | dependencies = [ 724 | "bumpalo", 725 | "lazy_static", 726 | "log", 727 | "proc-macro2", 728 | "quote", 729 | "syn", 730 | "wasm-bindgen-shared", 731 | ] 732 | 733 | [[package]] 734 | name = "wasm-bindgen-macro" 735 | version = "0.2.80" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" 738 | dependencies = [ 739 | "quote", 740 | "wasm-bindgen-macro-support", 741 | ] 742 | 743 | [[package]] 744 | name = "wasm-bindgen-macro-support" 745 | version = "0.2.80" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" 748 | dependencies = [ 749 | "proc-macro2", 750 | "quote", 751 | "syn", 752 | "wasm-bindgen-backend", 753 | "wasm-bindgen-shared", 754 | ] 755 | 756 | [[package]] 757 | name = "wasm-bindgen-shared" 758 | version = "0.2.80" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" 761 | 762 | [[package]] 763 | name = "web-sys" 764 | version = "0.3.57" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" 767 | dependencies = [ 768 | "js-sys", 769 | "wasm-bindgen", 770 | ] 771 | 772 | [[package]] 773 | name = "webpki" 774 | version = "0.22.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" 777 | dependencies = [ 778 | "ring", 779 | "untrusted", 780 | ] 781 | 782 | [[package]] 783 | name = "winapi" 784 | version = "0.3.9" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 787 | dependencies = [ 788 | "winapi-i686-pc-windows-gnu", 789 | "winapi-x86_64-pc-windows-gnu", 790 | ] 791 | 792 | [[package]] 793 | name = "winapi-i686-pc-windows-gnu" 794 | version = "0.4.0" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 797 | 798 | [[package]] 799 | name = "winapi-x86_64-pc-windows-gnu" 800 | version = "0.4.0" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 803 | --------------------------------------------------------------------------------