├── .gitignore ├── .cargo └── config.toml ├── .vscode └── settings.json ├── Cargo.toml ├── README.md ├── src ├── error.rs ├── main.rs ├── exit.rs ├── tests.rs └── entry.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | #[build] 2 | #rustflags = ["--cfg", "tokio_unstable"] 3 | [env] 4 | RUST_TEST_NOCAPTURE = "1" 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.checkOnSave.extraArgs": [ 3 | "--tests" 4 | ], 5 | "rust-analyzer.checkOnSave.enable": true 6 | } 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tcp-over-http" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [features] 7 | rustc_stable = [] 8 | 9 | [profile.release] 10 | #https://github.com/flamegraph-rs/flamegraph 11 | #debug = true 12 | 13 | [dependencies] 14 | actix-web = "*" 15 | tokio = { version = "*", features = ["net", "rt-multi-thread", "macros"] } 16 | clap = { version = "*", features = ["derive"] } 17 | reqwest = { version = "*", features = ["stream"] } 18 | tokio-util = { version = "*", features = ["io", "compat"] } 19 | futures = "*" 20 | lazy_static = "*" 21 | #url = "*" 22 | anyhow = "*" 23 | halfbrown = "*" 24 | uuid = { version = "*", features = ["v4"] } 25 | #log = "*" 26 | bytes = "*" 27 | ouroboros = "*" 28 | #console-subscriber = "*" 29 | stream-cancel = "*" 30 | derivative = "*" 31 | tokio-stream = "*" 32 | itertools = "*" 33 | rand = "*" 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 📡 TCP over HTTP 2 | 3 | ## 🥦 The Questions 4 | 5 | - #### 🪃 What does it do? 6 | 7 | You can proxy TCP traffic over HTTP. 8 | 9 | A basic setup would be: 10 | 11 | ``` 12 | [Your TCP target] <--TCP-- [Exit Node] 13 | ^ 14 | | 15 | HTTP 16 | | 17 | [Your TCP client] --TCP--> [Entry Node] 18 | ``` 19 | 20 | - #### 🍩 Why? 21 | 22 | ~~I was bored.~~ 23 | 24 | This allows you to reach servers behind a HTTP reverse proxy. 25 | Suddenly you can do SSH to a server which is behind a NGINX proxy. 26 | 27 | If you have for example a HTTP gateway, you can now also have 28 | a TCP gateway. 29 | 30 | - #### 🍾 Why not? 31 | 32 | If a server only opens port 80, nobody expects you 33 | to tunnel through and reach the SSH server. 34 | Security wise, no admin would want this tool on their 35 | server without them knowing. 36 | 37 | ## 🌲 Installation 38 | 39 | - get yourself a rust toolchain via rustup https://www.rust-lang.org/tools/install 40 | - go nightly: `rustup default nightly` 41 | - ```bash 42 | cargo install --locked --git https://github.com/julianbuettner/tcp-over-http 43 | ``` 44 | 45 | _Note_: 46 | If you want to use the stable version, checkout tag `rocket-stable`, 47 | which uses rocket and can be build with stable. 48 | 49 | - ```bash 50 | cargo install --locked --git https://github.com/julianbuettner/tcp-over-http --tag rocket-stable 51 | ``` 52 | 53 | ## 🎺 Usage 54 | 55 | Replace `tcp-over-http` by `cargo run --release --` 56 | if you have not installed the binary. 57 | 58 | ```bash 59 | tcp-over-http --help 60 | 61 | # Start our exit node to reach our SSH server (default listen localhost:8080) 62 | tcp-over-http exit --help 63 | tcp-over-http exit --target-addr localhost:22 64 | 65 | # Start our entry node (default listen localhost:1415) 66 | tcp-over-http entry --help 67 | tcp-over-http entry --target-url http://localhost:8080/ 68 | 69 | # Test it 70 | ssh localhost -p 1415 71 | ``` 72 | 73 | ## ⌚️ Performance 74 | 75 | This package is not optimized for stability ~~or speed~~. 76 | 77 | _Setup_ 78 | 79 | ```bash 80 | # Terminal 0 - Netcat listening 81 | nc -l 1234 > /dev/null 82 | 83 | # Terminal 1 - Exit Node 84 | tcp-over-http exit --target-addr localhost:1234 85 | 86 | # Terminal 2 - Entry Node 87 | tcp-over-http entry --target-url http://localhost:8080/ 88 | 89 | # Terminal 3 - Sending \0 data 90 | # Using pipeviewer (pv) to see current data rate 91 | time cat /dev/zero | pv | nc localhost 1415 92 | ``` 93 | 94 | ### 🏅 Result: 900MiB/s vs 1.3GiB/s (nc | pv > nc) 95 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fmt::{Debug, Formatter}, 3 | panic::Location, 4 | }; 5 | 6 | use anyhow::anyhow; 7 | use derivative::Derivative; 8 | 9 | fn to_string_fmt(t: &T, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { 10 | f.write_str(&t.to_string()) 11 | } 12 | 13 | #[derive(Derivative)] 14 | #[derivative(Debug)] 15 | pub(crate) struct TraceError { 16 | #[derivative(Debug(format_with = "self::to_string_fmt"))] 17 | source: &'static Location<'static>, 18 | #[derivative(Debug(format_with = "self::to_string_fmt"))] 19 | error: String, 20 | message: Option, 21 | } 22 | 23 | impl TraceError { 24 | fn with_context(mut self, message: String) -> Self { 25 | self.message = Some(message); 26 | self 27 | } 28 | } 29 | 30 | pub(crate) type Trace = Result; 31 | 32 | pub(crate) trait TraceExt { 33 | type Output; 34 | fn trace(self) -> Result; 35 | } 36 | 37 | impl TraceExt for Option { 38 | type Output = T; 39 | #[track_caller] 40 | fn trace(self) -> Result { 41 | match self { 42 | Some(x) => Ok(x), 43 | None => Err(TraceError::from(anyhow!("NoneError"))), 44 | } 45 | } 46 | } 47 | 48 | pub(crate) trait ContextExt { 49 | type Output; 50 | fn with_context(self, message: impl Into) -> TraceError; 51 | } 52 | 53 | impl ContextExt for T { 54 | type Output = T; 55 | #[track_caller] 56 | fn with_context(self, message: impl Into) -> TraceError { 57 | let message = message.into(); 58 | TraceError::from(self).with_context(message) 59 | } 60 | } 61 | 62 | auto trait Not {} 63 | impl !Not for TraceError {} 64 | 65 | impl From for TraceError { 66 | #[track_caller] 67 | fn from(error: T) -> Self { 68 | TraceError { 69 | source: std::intrinsics::caller_location(), 70 | error: format!("{error:#?}"), 71 | message: None, 72 | } 73 | } 74 | } 75 | 76 | #[test] 77 | fn trace_error() { 78 | #![allow(non_upper_case_globals)] 79 | 80 | use anyhow::anyhow; 81 | 82 | const creative_error_msg: &str = "enhance your calm"; 83 | 84 | const line: u32 = line!() + 2; 85 | fn inner() -> Result<(), TraceError> { 86 | Err(anyhow!(creative_error_msg))? 87 | } 88 | let col = { 89 | {}; 90 | column!() 91 | }; 92 | 93 | let err = inner().unwrap_err(); 94 | 95 | assert_eq!( 96 | format!("{err:?}"), 97 | format!( 98 | "TraceError {{ source: {}:{}:{}, error: {:?}, message: None }}", 99 | file!(), 100 | line, 101 | col, 102 | creative_error_msg, 103 | ) 104 | ); 105 | } 106 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //#![allow(warnings)] 2 | #![cfg_attr( 3 | not(feature = "rustc_stable"), 4 | feature( 5 | core_intrinsics, 6 | auto_traits, 7 | negative_impls, 8 | panic_internals, 9 | panic_info_message 10 | ) 11 | )] 12 | #![allow(clippy::needless_return)] 13 | #![warn(clippy::pedantic)] 14 | 15 | use anyhow::anyhow; 16 | use clap::{Parser, Subcommand}; 17 | use reqwest::Url; 18 | use std::{convert::Infallible, net::SocketAddr, str::FromStr}; 19 | use tokio::net::lookup_host; 20 | 21 | mod entry; 22 | mod exit; 23 | 24 | #[cfg(test)] 25 | mod tests; 26 | 27 | #[cfg(not(feature = "rustc_stable"))] 28 | mod error; 29 | 30 | pub(crate) fn join_url<'a>(base: &Url, path: impl IntoIterator) -> Url { 31 | //url::ParseError 32 | assert!(base.path().ends_with('/')); 33 | let mut it = path.into_iter(); 34 | let first = it.next().unwrap(); 35 | let mut next = it.next(); 36 | if next.is_some() { 37 | assert!(first.ends_with('/')); 38 | } 39 | let mut last = base.join(first).unwrap(); 40 | while let Some(x) = next { 41 | last = last.join(x).unwrap(); 42 | next = it.next(); 43 | if next.is_some() { 44 | assert!(x.ends_with('/')); 45 | } 46 | } 47 | return last; 48 | } 49 | 50 | #[derive(Clone, Debug, Subcommand)] 51 | enum CommandMode { 52 | /// Spin up entry node. Receives incoming TCP and forwards HTTP. 53 | Entry { 54 | #[clap(short, long, value_parser, default_value = "localhost:1415")] 55 | bind_addr: ResolveAddr, 56 | 57 | /// URL of the exit node. 58 | #[clap(short, long, value_parser)] 59 | target_url: Url, 60 | }, 61 | /// Spin up exit node. Receives incoming HTTP and forwards TCP. 62 | Exit { 63 | #[clap(short, long, value_parser, default_value = "localhost:8080")] 64 | bind_addr: ResolveAddr, 65 | 66 | #[clap(short, long)] 67 | target_addr: ResolveAddr, 68 | }, 69 | } 70 | 71 | #[derive(Clone, Debug)] 72 | struct ResolveAddr(String); //lookup_host 73 | impl FromStr for ResolveAddr { 74 | type Err = Infallible; 75 | fn from_str(s: &str) -> Result { 76 | Ok(Self(s.to_owned())) 77 | } 78 | } 79 | impl ResolveAddr { 80 | async fn resolve(self) -> Vec { 81 | lookup_host(&self.0) 82 | .await 83 | .map_err(|e| anyhow!("{self:#?} - {e:#?}")) 84 | .unwrap() 85 | .collect::>() 86 | } 87 | } 88 | 89 | #[derive(Parser, Debug)] 90 | #[clap(author, version, about, long_about = None)] 91 | struct CliArgs { 92 | #[clap(subcommand)] 93 | pub mode: CommandMode, 94 | } 95 | 96 | fn init_panic_hook() { 97 | static ONCE_GUARD: std::sync::Once = std::sync::Once::new(); 98 | ONCE_GUARD.call_once(|| { 99 | let org = std::panic::take_hook(); 100 | std::panic::set_hook(Box::new(move |info| { 101 | org(info); 102 | std::process::exit(101); 103 | })); 104 | }); 105 | } 106 | 107 | #[tokio::main] 108 | async fn main() { 109 | init_panic_hook(); 110 | 111 | match CliArgs::parse().mode { 112 | CommandMode::Entry { 113 | bind_addr, 114 | target_url, 115 | } => { 116 | entry::main(&bind_addr.resolve().await, target_url) 117 | .await 118 | .1 119 | .await; 120 | } 121 | CommandMode::Exit { 122 | bind_addr, 123 | target_addr, 124 | } => exit::main(&bind_addr.resolve().await, target_addr.resolve().await) 125 | .1 126 | .await 127 | .unwrap(), 128 | } 129 | } 130 | 131 | use std::pin::Pin; 132 | use tokio::net::tcp::OwnedReadHalf; 133 | use tokio::sync::OwnedMutexGuard; 134 | use tokio_util::codec::{BytesCodec, FramedRead}; 135 | 136 | #[ouroboros::self_referencing] 137 | pub(crate) struct Wrapper { 138 | guard: OwnedMutexGuard, 139 | #[borrows(mut guard)] 140 | #[not_covariant] 141 | fr: FramedRead<&'this mut OwnedReadHalf, BytesCodec>, 142 | } 143 | 144 | impl futures::Stream for Wrapper { 145 | type Item = Result; 146 | fn poll_next( 147 | mut self: std::pin::Pin<&mut Self>, 148 | cx: &mut std::task::Context<'_>, 149 | ) -> std::task::Poll> { 150 | self.with_fr_mut(|fr| Pin::new(fr).poll_next(cx)) 151 | } 152 | } 153 | 154 | pub(crate) type Artex = std::sync::Arc>; 155 | pub(crate) fn artex(t: T) -> Artex { 156 | std::sync::Arc::new(tokio::sync::Mutex::new(t)) 157 | } 158 | -------------------------------------------------------------------------------- /src/exit.rs: -------------------------------------------------------------------------------- 1 | use crate::artex; 2 | use crate::{ouroboros_impl_wrapper::WrapperBuilder, Artex}; 3 | use actix_web::dev::Server; 4 | use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder}; 5 | use anyhow::anyhow; 6 | use futures::stream::TryStreamExt; 7 | use halfbrown::HashMap as Map; 8 | use std::net::SocketAddr; 9 | use stream_cancel::{Trigger, Valve}; 10 | use tokio::{net::TcpStream, sync::RwLock}; 11 | use tokio_util::codec::{BytesCodec, FramedRead}; 12 | use tokio_util::sync::CancellationToken; 13 | use uuid::Uuid; 14 | 15 | #[derive(Debug)] 16 | pub(crate) struct UpExitSession { 17 | pub(crate) tcp_out: Artex, 18 | pub(crate) stop_copy: CancellationToken, 19 | } 20 | 21 | use derivative::Derivative; 22 | 23 | #[derive(Derivative)] 24 | #[derivative(Debug)] 25 | pub(crate) struct DownExitSession { 26 | pub(crate) tcp_in: Artex, 27 | #[derivative(Debug = "ignore")] 28 | stream_valve: Valve, 29 | #[derivative(Debug = "ignore")] 30 | stop_stream: Trigger, 31 | } 32 | 33 | #[derive(Debug)] 34 | pub(crate) struct ExitSession { 35 | pub(crate) up: UpExitSession, 36 | pub(crate) down: DownExitSession, 37 | } 38 | impl ExitSession { 39 | fn new(conn: TcpStream) -> Self { 40 | let (down, up) = conn.into_split(); 41 | let (trigger, valve) = Valve::new(); 42 | ExitSession { 43 | up: UpExitSession { 44 | tcp_out: artex(up), 45 | stop_copy: CancellationToken::new(), 46 | }, 47 | down: DownExitSession { 48 | tcp_in: artex(down), 49 | stream_valve: valve, 50 | stop_stream: trigger, 51 | }, 52 | } 53 | } 54 | } 55 | 56 | #[derive(Debug)] 57 | pub(crate) struct ExitSessionManager { 58 | target_addr: Vec, 59 | pub(crate) sessions: RwLock>, 60 | } 61 | 62 | impl ExitSessionManager { 63 | fn new(target_addr: Vec) -> Self { 64 | Self { 65 | target_addr, 66 | sessions: tokio::sync::RwLock::new(Map::new()), 67 | } 68 | } 69 | } 70 | 71 | #[get("/open")] 72 | async fn open(manager: web::Data) -> Vec { 73 | let stream = match TcpStream::connect(manager.target_addr.as_slice()).await { 74 | Ok(x) => x, 75 | Err(x) => { 76 | dbg!(x, "couldnt connect to target"); 77 | //signal 78 | return vec![]; 79 | } 80 | }; 81 | let uid = Uuid::new_v4(); 82 | let mut guard = manager.sessions.write().await; 83 | guard.insert(uid, ExitSession::new(stream)); 84 | return uid.into_bytes().to_vec(); 85 | } 86 | 87 | #[post("/upload/{uid_s}")] 88 | async fn upload( 89 | manager: web::Data, 90 | uid_s: web::Path, 91 | http_receive_data: web::Payload, 92 | ) -> impl Responder { 93 | let (guard, stop_copy) = { 94 | let uid = Uuid::parse_str(&uid_s).unwrap(); 95 | let guard = manager.sessions.read().await; 96 | let up_sess = &guard 97 | .get(&uid) 98 | .ok_or_else(|| anyhow!("Session {:#x?} not found!", uid)) 99 | .unwrap() 100 | .up; 101 | ( 102 | up_sess.tcp_out.clone().lock_owned(), 103 | up_sess.stop_copy.clone(), 104 | ) 105 | }; 106 | let r = http_receive_data 107 | .map_err(|x| Err(x).unwrap()) 108 | .into_async_read(); 109 | let mut r = tokio_util::compat::FuturesAsyncReadCompatExt::compat(r); 110 | let tcp_out = &mut *guard.await; 111 | return tokio::select! { 112 | x = tokio::io::copy(&mut r, tcp_out) => { 113 | if let Err(x) = x { 114 | dbg!("target disconnect", x); 115 | HttpResponse::Ok().body("target disconnect") 116 | } else { 117 | HttpResponse::Ok().body("finished") 118 | } 119 | } 120 | _ = stop_copy.cancelled() => { 121 | HttpResponse::Ok().body("cancelled") 122 | } 123 | }; 124 | } 125 | 126 | #[get("/download/{uid_s}")] 127 | async fn download( 128 | manager: web::Data, 129 | uid_s: web::Path, 130 | ) -> impl Responder { 131 | let (guard, valve) = { 132 | let uid = Uuid::parse_str(&uid_s).unwrap(); 133 | let guard = manager.sessions.read().await; 134 | let down_sess = &guard 135 | .get(&uid) 136 | .ok_or_else(|| anyhow!("Session {:#x?} not found!", uid)) 137 | .unwrap() 138 | .down; 139 | ( 140 | down_sess.tcp_in.clone().lock_owned(), 141 | down_sess.stream_valve.clone(), 142 | ) 143 | }; 144 | let stream = WrapperBuilder { 145 | guard: guard.await, 146 | fr_builder: |a| FramedRead::new(a, BytesCodec::new()), 147 | } 148 | .build(); 149 | let stream = valve.wrap(stream); 150 | //BytesMut -> Bytes 151 | return HttpResponse::Ok().streaming(stream.map_ok(Into::into)); 152 | } 153 | 154 | #[get("/close/{uid_s}")] 155 | async fn close(manager: web::Data, uid_s: web::Path) -> impl Responder { 156 | let uid = Uuid::parse_str(&uid_s).unwrap(); 157 | println!("Close session {uid:#x?}"); 158 | let mut guard = manager.sessions.write().await; 159 | let sess = guard 160 | .remove(&uid) 161 | .ok_or_else(|| anyhow!("Session with ID {uid:#x?} not found")) 162 | .unwrap(); 163 | sess.down.stop_stream.cancel(); 164 | sess.up.stop_copy.cancel(); 165 | HttpResponse::Ok() 166 | } 167 | 168 | pub fn main(bind_addr: &[SocketAddr], target_addr: Vec) -> (Vec, Server) { 169 | let session_manager = web::Data::new(ExitSessionManager::new(target_addr)); 170 | #[cfg(test)] 171 | { 172 | *test::ARC.try_lock().unwrap() = Some(session_manager.clone()); 173 | } 174 | let x = HttpServer::new(move || { 175 | App::new() 176 | .app_data(session_manager.clone()) 177 | //.app_data(web::PayloadConfig::new(1024 * 1024)) 178 | .service(open) 179 | .service(upload) 180 | .service(download) 181 | .service(close) 182 | }) 183 | .bind(bind_addr) 184 | .unwrap(); 185 | let bound = x.addrs(); 186 | println!("Listening on {bound:?}"); 187 | return (bound, x.run()); 188 | } 189 | 190 | #[cfg(test)] 191 | pub(crate) mod test { 192 | use super::ExitSessionManager; 193 | use actix_web::web; 194 | use tokio::sync::Mutex; 195 | 196 | pub(crate) static ARC: Mutex>> = Mutex::const_new(None); 197 | } 198 | -------------------------------------------------------------------------------- /src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | entry, 3 | exit::{self, ExitSession, ExitSessionManager}, 4 | init_panic_hook, ResolveAddr, 5 | }; 6 | use actix_web::web; 7 | use halfbrown::HashMap; 8 | use itertools::Itertools; 9 | use rand::RngCore; 10 | use std::{convert::TryInto, net::SocketAddr, sync::atomic::Ordering, time::Duration}; 11 | use std::{ops::Deref, sync::Arc}; 12 | use tokio::{ 13 | io::{AsyncReadExt, AsyncWriteExt}, 14 | join, 15 | net::TcpStream, 16 | sync::{MutexGuard, RwLockReadGuard}, 17 | time::sleep, 18 | }; 19 | use uuid::Uuid; 20 | 21 | const TEST_SIZE: usize = (1024 * 1024 * 10) + 42; 22 | 23 | struct Persist { 24 | entry_conn: TcpStream, 25 | exit_conn: TcpStream, 26 | } 27 | 28 | async fn roundtrip() -> Persist { 29 | let localhost = localhost().await; 30 | 31 | let target_listen = tokio::net::TcpListener::bind(localhost).await.unwrap(); 32 | let (exit_addr, f_exit) = exit::main(localhost, vec![target_listen.local_addr().unwrap()]); 33 | 34 | let exit_addr = exit_addr.first().unwrap(); 35 | 36 | let (entry_addr, f_entry) = entry::main( 37 | localhost, 38 | format!("http://{exit_addr}/").as_str().try_into().unwrap(), 39 | ) 40 | .await; 41 | 42 | let f_test = async { 43 | //get rand 44 | let irand = { 45 | let mut rand_buf = vec![0; TEST_SIZE]; 46 | rand::rngs::mock::StepRng::new(0, 1).fill_bytes(&mut rand_buf); 47 | rand_buf 48 | }; 49 | //connect to entry 50 | let mut entry_conn = TcpStream::connect(entry_addr).await.unwrap(); 51 | //send rand 52 | let join_send = async { 53 | entry_conn.write_all(&irand).await.unwrap(); 54 | }; 55 | //recv rand 56 | let mut exit_conn = target_listen.accept().await.unwrap().0; 57 | let mut post = vec![0; TEST_SIZE]; 58 | let join_recv = async { 59 | exit_conn.read_exact(&mut post).await.unwrap(); 60 | }; 61 | // 62 | join!(join_send, join_recv); 63 | //assert rand 64 | assert!(post == irand); 65 | 66 | //make response 67 | let response = { 68 | let mut response_buf = irand; 69 | rand::rngs::mock::StepRng::new(TEST_SIZE.try_into().unwrap(), 1) 70 | .fill_bytes(&mut response_buf); 71 | response_buf 72 | }; 73 | //send respond 74 | let join_send = async { 75 | exit_conn.write_all(&response).await.unwrap(); 76 | }; 77 | //recv response 78 | let join_recv = async { 79 | entry_conn.read_exact(&mut post).await.unwrap(); 80 | }; 81 | // 82 | join!(join_send, join_recv); 83 | //assert response 84 | assert!(post == response); 85 | 86 | Persist { 87 | entry_conn, 88 | exit_conn, 89 | } 90 | }; 91 | 92 | tokio::select! { 93 | _ = f_exit => { 94 | panic!() 95 | } 96 | _ = f_entry => { 97 | panic!() 98 | } 99 | x = f_test => { 100 | return x; 101 | } 102 | }; 103 | } 104 | 105 | #[test] 106 | fn test() { 107 | init_panic_hook(); 108 | 109 | RT.block_on(async { 110 | #[ouroboros::self_referencing] 111 | struct Guard { 112 | o: MutexGuard<'static, Option>>, 113 | #[borrows(o)] 114 | #[covariant] 115 | r: RwLockReadGuard<'this, HashMap>, 116 | } 117 | impl Deref for Guard { 118 | type Target = HashMap; 119 | fn deref(&self) -> &Self::Target { 120 | #[allow(clippy::explicit_deref_methods)] 121 | self.borrow_r().deref() 122 | } 123 | } 124 | let lock = || async { 125 | let guard: Guard = GuardAsyncBuilder { 126 | o: crate::exit::test::ARC.lock().await, 127 | r_builder: |x| Box::pin(x.as_ref().unwrap().sessions.read()), 128 | } 129 | .build() 130 | .await; 131 | guard 132 | }; 133 | 134 | #[allow(clippy::async_yields_async)] 135 | let assert = || async { 136 | let guard = lock().await; 137 | let one = guard.iter().at_most_one().unwrap().unwrap(); 138 | let sess = one.1; 139 | let tcp_in = &sess.down.tcp_in; 140 | assert_eq!(Arc::strong_count(tcp_in), 2); 141 | let tcp_out = &sess.up.tcp_out; 142 | assert_eq!(Arc::strong_count(tcp_out), 2); 143 | tcp_in.try_lock().unwrap_err(); 144 | tcp_out.try_lock().unwrap_err(); 145 | assert!(!sess.up.stop_copy.is_cancelled()); 146 | let tcp_in = tcp_in.clone(); 147 | let tcp_out = tcp_out.clone(); 148 | 149 | async move { 150 | assert_eq!(Arc::strong_count(&tcp_in), 1); 151 | assert_eq!(Arc::strong_count(&tcp_out), 1); 152 | drop(tcp_in.try_lock().unwrap()); 153 | drop(tcp_out.try_lock().unwrap()); 154 | assert_eq!(lock().await.len(), 0); 155 | 156 | assert_eq!(crate::entry::AC.load(Ordering::SeqCst), 0); 157 | } 158 | }; 159 | 160 | let roundtrip = |rst| async move { 161 | let conn = roundtrip().await; 162 | if rst { 163 | conn.entry_conn.set_linger(Some(Duration::ZERO)).unwrap(); 164 | conn.exit_conn.set_linger(Some(Duration::ZERO)).unwrap(); 165 | } 166 | (conn.entry_conn, conn.exit_conn, assert().await) 167 | }; 168 | 169 | let (entry_conn, exit_conn, assert) = roundtrip(false).await; 170 | drop((entry_conn, exit_conn)); 171 | sleep(Duration::from_millis(100)).await; 172 | assert.await; 173 | 174 | let roundtrip = || roundtrip(true); 175 | 176 | dbg!(); 177 | 178 | let (entry_conn, exit_conn, assert) = roundtrip().await; 179 | drop(entry_conn); 180 | sleep(Duration::from_millis(100)).await; 181 | assert.await; 182 | drop(exit_conn); 183 | 184 | dbg!(); 185 | 186 | let (entry_conn, exit_conn, assert) = roundtrip().await; 187 | drop(exit_conn); 188 | sleep(Duration::from_millis(100)).await; 189 | assert.await; 190 | drop(entry_conn); 191 | 192 | dbg!(); 193 | 194 | let (entry_conn, exit_conn, assert) = roundtrip().await; 195 | 196 | drop((entry_conn, exit_conn)); 197 | sleep(Duration::from_millis(100)).await; 198 | assert.await; 199 | 200 | dbg!(); 201 | }); 202 | } 203 | 204 | #[test] 205 | fn resolve() { 206 | RT.block_on(async { 207 | let addr = ResolveAddr("localhost:0".to_owned()).resolve().await; 208 | let addr = addr.into_iter().map(|x| x.to_string()).collect::>(); 209 | assert_eq!(addr, ["[::1]:0", "127.0.0.1:0"]); 210 | }); 211 | } 212 | 213 | lazy_static::lazy_static! { 214 | static ref RT: tokio::runtime::Runtime = tokio::runtime::Runtime::new().unwrap(); 215 | } 216 | 217 | async fn localhost() -> &'static [SocketAddr] { 218 | static ONCE: tokio::sync::OnceCell> = tokio::sync::OnceCell::const_new(); 219 | 220 | ONCE.get_or_init(|| async { 221 | tokio::net::lookup_host("localhost:0") 222 | .await 223 | .unwrap() 224 | .collect_vec() 225 | }) 226 | .await 227 | } 228 | -------------------------------------------------------------------------------- /src/entry.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Trace; 2 | use crate::ouroboros_impl_wrapper::WrapperBuilder; 3 | use crate::{artex, join_url}; 4 | 5 | use bytes::Bytes; 6 | use futures::Future; 7 | use reqwest::{Body, Client, Response, Url}; 8 | use std::convert::{identity, Infallible, TryInto}; 9 | use std::io::ErrorKind; 10 | use std::net::SocketAddr; 11 | use std::sync::Arc; 12 | use stream_cancel::Valve; 13 | use tokio::net::TcpListener; 14 | use tokio_stream::StreamExt; 15 | use tokio_util::codec::{BytesCodec, FramedRead}; 16 | use tokio_util::sync::CancellationToken; 17 | use uuid::Uuid; 18 | 19 | lazy_static::lazy_static! { 20 | pub(crate) static ref CLIENT: Client = Client::new(); 21 | } 22 | 23 | async fn close_session(target: &Url, uid: Uuid) { 24 | let resp = CLIENT 25 | .get(join_url(target, ["close/", &uid.to_string()])) 26 | .send() 27 | .await 28 | .unwrap(); 29 | assert_ok(resp).await; 30 | } 31 | async fn init_http_session(target: &Url) -> Trace { 32 | let resp = CLIENT.get(join_url(target, ["open"])).send().await.unwrap(); 33 | let resp = assert_ok(resp).await; 34 | return Ok(Uuid::from_bytes( 35 | match identity::<&[u8]>(&resp.bytes().await.unwrap()).try_into() { 36 | Ok(x) => x, 37 | Err(x) => { 38 | use crate::error::ContextExt; 39 | //signal from exit 40 | return Err(x.with_context("couldnt connect to target")); 41 | } 42 | }, 43 | )); 44 | } 45 | 46 | async fn upload_req(target: &Url, uid: Uuid, data: S) 47 | where 48 | S: futures::TryStream + Send + Sync + 'static, 49 | S::Error: Into>, 50 | bytes::Bytes: From, 51 | { 52 | let resp = CLIENT 53 | .post(join_url(target, ["upload/", &uid.to_string()])) 54 | .body(Body::wrap_stream(data)) 55 | .send() 56 | .await 57 | .unwrap(); 58 | let resp = assert_ok(resp).await; 59 | dbg!(resp.text().await.unwrap()); 60 | } 61 | 62 | async fn download_req( 63 | target: &Url, 64 | uid: Uuid, 65 | ) -> impl futures::Stream> { 66 | let resp = CLIENT 67 | .get(join_url(target, ["download/", &uid.to_string()])) 68 | .send() 69 | .await 70 | .unwrap(); 71 | let resp = assert_ok(resp).await; 72 | return resp.bytes_stream(); 73 | } 74 | 75 | async fn process_socket(target_url: Arc, socket: tokio::net::TcpStream) -> Trace { 76 | let uid = init_http_session(&target_url).await?; 77 | println!("HTTP Server copies. Established session {uid:#x?}"); 78 | 79 | let (s_read, mut s_write) = socket.into_split(); 80 | 81 | let stop_download = CancellationToken::new(); 82 | let (stop_upload, valve) = Valve::new(); 83 | 84 | let upload_join = { 85 | let stop_download = stop_download.clone(); 86 | let target_url = target_url.clone(); 87 | let s_read = artex(s_read); 88 | async move { 89 | #[allow(clippy::never_loop)] 90 | loop { 91 | let stream = WrapperBuilder { 92 | guard: s_read.clone().try_lock_owned().unwrap(), 93 | fr_builder: |a| FramedRead::new(a, BytesCodec::new()), 94 | } 95 | .build(); 96 | 97 | let stream = stream.map_while::, _>(|x| match x { 98 | Ok(x) => Some(Ok(x)), 99 | Err(x) => { 100 | dbg!(x); 101 | None 102 | } 103 | }); 104 | let stream = valve.wrap(stream); 105 | upload_req(&target_url, uid, stream).await; 106 | //200 107 | break; 108 | } 109 | stop_download.cancel(); 110 | } 111 | }; 112 | 113 | let download_join = { 114 | let target_url = target_url.clone(); 115 | async move { 116 | #[allow(clippy::never_loop)] 117 | loop { 118 | use futures::TryStreamExt; 119 | use tokio_util::compat::FuturesAsyncReadCompatExt; 120 | 121 | let s = download_req(&target_url, uid).await; 122 | let mut r = s 123 | .map_while(|x| match x { 124 | Ok(x) => Some(Ok(x)), 125 | Err(x) => { 126 | dbg!(x); 127 | None 128 | } 129 | }) 130 | .into_async_read() 131 | .compat(); 132 | 133 | tokio::select! { 134 | x = tokio::io::copy(&mut r, &mut s_write) => x.expect("unreachable"), 135 | _ = stop_download.cancelled() => break, 136 | }; 137 | 138 | break; 139 | } 140 | stop_upload.cancel(); 141 | } 142 | }; 143 | let upload_join = tokio::spawn(upload_join); 144 | let download_join = tokio::spawn(download_join); 145 | upload_join.await.unwrap(); 146 | download_join.await.unwrap(); 147 | close_session(&target_url, uid).await; 148 | return Ok(uid); 149 | } 150 | 151 | pub async fn main( 152 | bind_addr: &[SocketAddr], 153 | target_url: Url, 154 | ) -> (SocketAddr, impl Future) { 155 | //console_subscriber::init(); 156 | let listener_result = TcpListener::bind(bind_addr).await; 157 | if let Err(bind_err) = listener_result { 158 | match bind_err.kind() { 159 | ErrorKind::AddrInUse => eprintln!( 160 | "Port {:?} is already in use.", 161 | bind_addr.iter().map(SocketAddr::port).collect::>() 162 | ), 163 | ErrorKind::AddrNotAvailable => { 164 | eprintln!( 165 | "Could not bind to IP {:?}. Not found.", 166 | bind_addr.iter().map(SocketAddr::ip).collect::>() 167 | ); 168 | } 169 | ErrorKind::PermissionDenied => eprintln!( 170 | "Permission denied. Port {:?} to low for non-root user?", 171 | bind_addr.iter().map(SocketAddr::port).collect::>() 172 | ), 173 | e => eprintln!( 174 | "Could not listen to your desired ip address or port: {:?}", 175 | e 176 | ), 177 | } 178 | panic!(); 179 | }; 180 | let listener = listener_result.unwrap(); 181 | let bound = listener.local_addr().unwrap(); 182 | println!("Listening on {bound}"); 183 | let target_url = Arc::new(target_url); 184 | return (bound, async move { 185 | loop { 186 | let (socket, _) = listener.accept().await.unwrap(); 187 | let target_url = target_url.clone(); 188 | let _join_handle = tokio::spawn(async move { 189 | #[cfg(test)] 190 | AC.fetch_add(1, std::sync::atomic::Ordering::SeqCst); 191 | drop(dbg!(process_socket(target_url, socket).await)); 192 | #[cfg(test)] 193 | AC.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); 194 | }); 195 | } 196 | }); 197 | } 198 | 199 | #[cfg(test)] 200 | pub(crate) static AC: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); 201 | 202 | #[track_caller] 203 | fn assert_ok(resp: Response) -> impl std::future::Future { 204 | #[cfg(feature = "rustc_stable")] 205 | return async move { resp }; 206 | #[cfg(not(feature = "rustc_stable"))] 207 | { 208 | let blame_caller = std::intrinsics::caller_location(); 209 | async move { 210 | if resp.status() == reqwest::StatusCode::OK { 211 | return resp; 212 | } 213 | let s = format!("{resp:#?}"); 214 | let bytes = resp.bytes().await; 215 | let resp_body = bytes.as_ref().map(|x| std::str::from_utf8(x)); 216 | eprintln!("{s}"); 217 | eprintln!("{resp_body:#?}"); 218 | eprintln!("caller: {blame_caller}"); 219 | panic!("status was not ok"); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /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 = "Inflector" 7 | version = "0.11.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" 10 | 11 | [[package]] 12 | name = "actix-codec" 13 | version = "0.5.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" 16 | dependencies = [ 17 | "bitflags", 18 | "bytes", 19 | "futures-core", 20 | "futures-sink", 21 | "log", 22 | "memchr", 23 | "pin-project-lite", 24 | "tokio", 25 | "tokio-util", 26 | ] 27 | 28 | [[package]] 29 | name = "actix-http" 30 | version = "3.2.2" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" 33 | dependencies = [ 34 | "actix-codec", 35 | "actix-rt", 36 | "actix-service", 37 | "actix-utils", 38 | "ahash", 39 | "base64", 40 | "bitflags", 41 | "brotli", 42 | "bytes", 43 | "bytestring", 44 | "derive_more", 45 | "encoding_rs", 46 | "flate2", 47 | "futures-core", 48 | "h2", 49 | "http", 50 | "httparse", 51 | "httpdate", 52 | "itoa", 53 | "language-tags", 54 | "local-channel", 55 | "mime", 56 | "percent-encoding", 57 | "pin-project-lite", 58 | "rand", 59 | "sha1", 60 | "smallvec", 61 | "tracing", 62 | "zstd", 63 | ] 64 | 65 | [[package]] 66 | name = "actix-macros" 67 | version = "0.2.3" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" 70 | dependencies = [ 71 | "quote", 72 | "syn", 73 | ] 74 | 75 | [[package]] 76 | name = "actix-router" 77 | version = "0.5.1" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" 80 | dependencies = [ 81 | "bytestring", 82 | "http", 83 | "regex", 84 | "serde", 85 | "tracing", 86 | ] 87 | 88 | [[package]] 89 | name = "actix-rt" 90 | version = "2.7.0" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" 93 | dependencies = [ 94 | "futures-core", 95 | "tokio", 96 | ] 97 | 98 | [[package]] 99 | name = "actix-server" 100 | version = "2.1.1" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" 103 | dependencies = [ 104 | "actix-rt", 105 | "actix-service", 106 | "actix-utils", 107 | "futures-core", 108 | "futures-util", 109 | "mio", 110 | "num_cpus", 111 | "socket2", 112 | "tokio", 113 | "tracing", 114 | ] 115 | 116 | [[package]] 117 | name = "actix-service" 118 | version = "2.0.2" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" 121 | dependencies = [ 122 | "futures-core", 123 | "paste", 124 | "pin-project-lite", 125 | ] 126 | 127 | [[package]] 128 | name = "actix-utils" 129 | version = "3.0.0" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" 132 | dependencies = [ 133 | "local-waker", 134 | "pin-project-lite", 135 | ] 136 | 137 | [[package]] 138 | name = "actix-web" 139 | version = "4.2.1" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" 142 | dependencies = [ 143 | "actix-codec", 144 | "actix-http", 145 | "actix-macros", 146 | "actix-router", 147 | "actix-rt", 148 | "actix-server", 149 | "actix-service", 150 | "actix-utils", 151 | "actix-web-codegen", 152 | "ahash", 153 | "bytes", 154 | "bytestring", 155 | "cfg-if", 156 | "cookie", 157 | "derive_more", 158 | "encoding_rs", 159 | "futures-core", 160 | "futures-util", 161 | "http", 162 | "itoa", 163 | "language-tags", 164 | "log", 165 | "mime", 166 | "once_cell", 167 | "pin-project-lite", 168 | "regex", 169 | "serde", 170 | "serde_json", 171 | "serde_urlencoded", 172 | "smallvec", 173 | "socket2", 174 | "time", 175 | "url", 176 | ] 177 | 178 | [[package]] 179 | name = "actix-web-codegen" 180 | version = "4.1.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" 183 | dependencies = [ 184 | "actix-router", 185 | "proc-macro2", 186 | "quote", 187 | "syn", 188 | ] 189 | 190 | [[package]] 191 | name = "adler" 192 | version = "1.0.2" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 195 | 196 | [[package]] 197 | name = "ahash" 198 | version = "0.7.6" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 201 | dependencies = [ 202 | "getrandom", 203 | "once_cell", 204 | "version_check", 205 | ] 206 | 207 | [[package]] 208 | name = "aho-corasick" 209 | version = "0.7.19" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" 212 | dependencies = [ 213 | "memchr", 214 | ] 215 | 216 | [[package]] 217 | name = "aliasable" 218 | version = "0.1.3" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" 221 | 222 | [[package]] 223 | name = "alloc-no-stdlib" 224 | version = "2.0.4" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 227 | 228 | [[package]] 229 | name = "alloc-stdlib" 230 | version = "0.2.2" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 233 | dependencies = [ 234 | "alloc-no-stdlib", 235 | ] 236 | 237 | [[package]] 238 | name = "anyhow" 239 | version = "1.0.65" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" 242 | 243 | [[package]] 244 | name = "atty" 245 | version = "0.2.14" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 248 | dependencies = [ 249 | "hermit-abi", 250 | "libc", 251 | "winapi", 252 | ] 253 | 254 | [[package]] 255 | name = "autocfg" 256 | version = "1.1.0" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 259 | 260 | [[package]] 261 | name = "base64" 262 | version = "0.13.0" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 265 | 266 | [[package]] 267 | name = "bitflags" 268 | version = "1.3.2" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 271 | 272 | [[package]] 273 | name = "block-buffer" 274 | version = "0.10.3" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 277 | dependencies = [ 278 | "generic-array", 279 | ] 280 | 281 | [[package]] 282 | name = "brotli" 283 | version = "3.3.4" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 286 | dependencies = [ 287 | "alloc-no-stdlib", 288 | "alloc-stdlib", 289 | "brotli-decompressor", 290 | ] 291 | 292 | [[package]] 293 | name = "brotli-decompressor" 294 | version = "2.3.2" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" 297 | dependencies = [ 298 | "alloc-no-stdlib", 299 | "alloc-stdlib", 300 | ] 301 | 302 | [[package]] 303 | name = "bumpalo" 304 | version = "3.11.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" 307 | 308 | [[package]] 309 | name = "bytes" 310 | version = "1.2.1" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" 313 | 314 | [[package]] 315 | name = "bytestring" 316 | version = "1.1.0" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "86b6a75fd3048808ef06af5cd79712be8111960adaf89d90250974b38fc3928a" 319 | dependencies = [ 320 | "bytes", 321 | ] 322 | 323 | [[package]] 324 | name = "cc" 325 | version = "1.0.73" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 328 | dependencies = [ 329 | "jobserver", 330 | ] 331 | 332 | [[package]] 333 | name = "cfg-if" 334 | version = "1.0.0" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 337 | 338 | [[package]] 339 | name = "clap" 340 | version = "4.0.13" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "69d64e88428747154bd8bc378d178377ef4dace7a5735ca1f3855be72f2c2cb5" 343 | dependencies = [ 344 | "atty", 345 | "bitflags", 346 | "clap_derive", 347 | "clap_lex", 348 | "once_cell", 349 | "strsim", 350 | "termcolor", 351 | ] 352 | 353 | [[package]] 354 | name = "clap_derive" 355 | version = "4.0.13" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad" 358 | dependencies = [ 359 | "heck", 360 | "proc-macro-error", 361 | "proc-macro2", 362 | "quote", 363 | "syn", 364 | ] 365 | 366 | [[package]] 367 | name = "clap_lex" 368 | version = "0.3.0" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" 371 | dependencies = [ 372 | "os_str_bytes", 373 | ] 374 | 375 | [[package]] 376 | name = "convert_case" 377 | version = "0.4.0" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 380 | 381 | [[package]] 382 | name = "cookie" 383 | version = "0.16.1" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" 386 | dependencies = [ 387 | "percent-encoding", 388 | "time", 389 | "version_check", 390 | ] 391 | 392 | [[package]] 393 | name = "core-foundation" 394 | version = "0.9.3" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 397 | dependencies = [ 398 | "core-foundation-sys", 399 | "libc", 400 | ] 401 | 402 | [[package]] 403 | name = "core-foundation-sys" 404 | version = "0.8.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 407 | 408 | [[package]] 409 | name = "cpufeatures" 410 | version = "0.2.5" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 413 | dependencies = [ 414 | "libc", 415 | ] 416 | 417 | [[package]] 418 | name = "crc32fast" 419 | version = "1.3.2" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 422 | dependencies = [ 423 | "cfg-if", 424 | ] 425 | 426 | [[package]] 427 | name = "crypto-common" 428 | version = "0.1.6" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 431 | dependencies = [ 432 | "generic-array", 433 | "typenum", 434 | ] 435 | 436 | [[package]] 437 | name = "derivative" 438 | version = "2.2.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 441 | dependencies = [ 442 | "proc-macro2", 443 | "quote", 444 | "syn", 445 | ] 446 | 447 | [[package]] 448 | name = "derive_more" 449 | version = "0.99.17" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 452 | dependencies = [ 453 | "convert_case", 454 | "proc-macro2", 455 | "quote", 456 | "rustc_version", 457 | "syn", 458 | ] 459 | 460 | [[package]] 461 | name = "digest" 462 | version = "0.10.5" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" 465 | dependencies = [ 466 | "block-buffer", 467 | "crypto-common", 468 | ] 469 | 470 | [[package]] 471 | name = "either" 472 | version = "1.8.0" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 475 | 476 | [[package]] 477 | name = "encoding_rs" 478 | version = "0.8.31" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 481 | dependencies = [ 482 | "cfg-if", 483 | ] 484 | 485 | [[package]] 486 | name = "fastrand" 487 | version = "1.8.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 490 | dependencies = [ 491 | "instant", 492 | ] 493 | 494 | [[package]] 495 | name = "flate2" 496 | version = "1.0.24" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" 499 | dependencies = [ 500 | "crc32fast", 501 | "miniz_oxide", 502 | ] 503 | 504 | [[package]] 505 | name = "fnv" 506 | version = "1.0.7" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 509 | 510 | [[package]] 511 | name = "foreign-types" 512 | version = "0.3.2" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 515 | dependencies = [ 516 | "foreign-types-shared", 517 | ] 518 | 519 | [[package]] 520 | name = "foreign-types-shared" 521 | version = "0.1.1" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 524 | 525 | [[package]] 526 | name = "form_urlencoded" 527 | version = "1.1.0" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 530 | dependencies = [ 531 | "percent-encoding", 532 | ] 533 | 534 | [[package]] 535 | name = "futures" 536 | version = "0.3.24" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" 539 | dependencies = [ 540 | "futures-channel", 541 | "futures-core", 542 | "futures-executor", 543 | "futures-io", 544 | "futures-sink", 545 | "futures-task", 546 | "futures-util", 547 | ] 548 | 549 | [[package]] 550 | name = "futures-channel" 551 | version = "0.3.24" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" 554 | dependencies = [ 555 | "futures-core", 556 | "futures-sink", 557 | ] 558 | 559 | [[package]] 560 | name = "futures-core" 561 | version = "0.3.24" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" 564 | 565 | [[package]] 566 | name = "futures-executor" 567 | version = "0.3.24" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" 570 | dependencies = [ 571 | "futures-core", 572 | "futures-task", 573 | "futures-util", 574 | ] 575 | 576 | [[package]] 577 | name = "futures-io" 578 | version = "0.3.24" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" 581 | 582 | [[package]] 583 | name = "futures-macro" 584 | version = "0.3.24" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" 587 | dependencies = [ 588 | "proc-macro2", 589 | "quote", 590 | "syn", 591 | ] 592 | 593 | [[package]] 594 | name = "futures-sink" 595 | version = "0.3.24" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" 598 | 599 | [[package]] 600 | name = "futures-task" 601 | version = "0.3.24" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" 604 | 605 | [[package]] 606 | name = "futures-util" 607 | version = "0.3.24" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" 610 | dependencies = [ 611 | "futures-channel", 612 | "futures-core", 613 | "futures-io", 614 | "futures-macro", 615 | "futures-sink", 616 | "futures-task", 617 | "memchr", 618 | "pin-project-lite", 619 | "pin-utils", 620 | "slab", 621 | ] 622 | 623 | [[package]] 624 | name = "generic-array" 625 | version = "0.14.6" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 628 | dependencies = [ 629 | "typenum", 630 | "version_check", 631 | ] 632 | 633 | [[package]] 634 | name = "getrandom" 635 | version = "0.2.7" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 638 | dependencies = [ 639 | "cfg-if", 640 | "libc", 641 | "wasi", 642 | ] 643 | 644 | [[package]] 645 | name = "h2" 646 | version = "0.3.14" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" 649 | dependencies = [ 650 | "bytes", 651 | "fnv", 652 | "futures-core", 653 | "futures-sink", 654 | "futures-util", 655 | "http", 656 | "indexmap", 657 | "slab", 658 | "tokio", 659 | "tokio-util", 660 | "tracing", 661 | ] 662 | 663 | [[package]] 664 | name = "halfbrown" 665 | version = "0.1.15" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "ce69ed202df415a3d4a01e6f3341320ca88b9bd4f0bf37be6fa239cdea06d9bf" 668 | dependencies = [ 669 | "hashbrown", 670 | ] 671 | 672 | [[package]] 673 | name = "hashbrown" 674 | version = "0.12.3" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 677 | dependencies = [ 678 | "ahash", 679 | ] 680 | 681 | [[package]] 682 | name = "heck" 683 | version = "0.4.0" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 686 | 687 | [[package]] 688 | name = "hermit-abi" 689 | version = "0.1.19" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 692 | dependencies = [ 693 | "libc", 694 | ] 695 | 696 | [[package]] 697 | name = "http" 698 | version = "0.2.8" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 701 | dependencies = [ 702 | "bytes", 703 | "fnv", 704 | "itoa", 705 | ] 706 | 707 | [[package]] 708 | name = "http-body" 709 | version = "0.4.5" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 712 | dependencies = [ 713 | "bytes", 714 | "http", 715 | "pin-project-lite", 716 | ] 717 | 718 | [[package]] 719 | name = "httparse" 720 | version = "1.8.0" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 723 | 724 | [[package]] 725 | name = "httpdate" 726 | version = "1.0.2" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 729 | 730 | [[package]] 731 | name = "hyper" 732 | version = "0.14.20" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" 735 | dependencies = [ 736 | "bytes", 737 | "futures-channel", 738 | "futures-core", 739 | "futures-util", 740 | "h2", 741 | "http", 742 | "http-body", 743 | "httparse", 744 | "httpdate", 745 | "itoa", 746 | "pin-project-lite", 747 | "socket2", 748 | "tokio", 749 | "tower-service", 750 | "tracing", 751 | "want", 752 | ] 753 | 754 | [[package]] 755 | name = "hyper-tls" 756 | version = "0.5.0" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 759 | dependencies = [ 760 | "bytes", 761 | "hyper", 762 | "native-tls", 763 | "tokio", 764 | "tokio-native-tls", 765 | ] 766 | 767 | [[package]] 768 | name = "idna" 769 | version = "0.3.0" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 772 | dependencies = [ 773 | "unicode-bidi", 774 | "unicode-normalization", 775 | ] 776 | 777 | [[package]] 778 | name = "indexmap" 779 | version = "1.9.1" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 782 | dependencies = [ 783 | "autocfg", 784 | "hashbrown", 785 | ] 786 | 787 | [[package]] 788 | name = "instant" 789 | version = "0.1.12" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 792 | dependencies = [ 793 | "cfg-if", 794 | ] 795 | 796 | [[package]] 797 | name = "ipnet" 798 | version = "2.5.0" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" 801 | 802 | [[package]] 803 | name = "itertools" 804 | version = "0.10.5" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 807 | dependencies = [ 808 | "either", 809 | ] 810 | 811 | [[package]] 812 | name = "itoa" 813 | version = "1.0.4" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" 816 | 817 | [[package]] 818 | name = "jobserver" 819 | version = "0.1.25" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" 822 | dependencies = [ 823 | "libc", 824 | ] 825 | 826 | [[package]] 827 | name = "js-sys" 828 | version = "0.3.60" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 831 | dependencies = [ 832 | "wasm-bindgen", 833 | ] 834 | 835 | [[package]] 836 | name = "language-tags" 837 | version = "0.3.2" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" 840 | 841 | [[package]] 842 | name = "lazy_static" 843 | version = "1.4.0" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 846 | 847 | [[package]] 848 | name = "libc" 849 | version = "0.2.135" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" 852 | 853 | [[package]] 854 | name = "local-channel" 855 | version = "0.1.3" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" 858 | dependencies = [ 859 | "futures-core", 860 | "futures-sink", 861 | "futures-util", 862 | "local-waker", 863 | ] 864 | 865 | [[package]] 866 | name = "local-waker" 867 | version = "0.1.3" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" 870 | 871 | [[package]] 872 | name = "lock_api" 873 | version = "0.4.9" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 876 | dependencies = [ 877 | "autocfg", 878 | "scopeguard", 879 | ] 880 | 881 | [[package]] 882 | name = "log" 883 | version = "0.4.17" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 886 | dependencies = [ 887 | "cfg-if", 888 | ] 889 | 890 | [[package]] 891 | name = "memchr" 892 | version = "2.5.0" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 895 | 896 | [[package]] 897 | name = "mime" 898 | version = "0.3.16" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 901 | 902 | [[package]] 903 | name = "miniz_oxide" 904 | version = "0.5.4" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" 907 | dependencies = [ 908 | "adler", 909 | ] 910 | 911 | [[package]] 912 | name = "mio" 913 | version = "0.8.4" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" 916 | dependencies = [ 917 | "libc", 918 | "log", 919 | "wasi", 920 | "windows-sys", 921 | ] 922 | 923 | [[package]] 924 | name = "native-tls" 925 | version = "0.2.10" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" 928 | dependencies = [ 929 | "lazy_static", 930 | "libc", 931 | "log", 932 | "openssl", 933 | "openssl-probe", 934 | "openssl-sys", 935 | "schannel", 936 | "security-framework", 937 | "security-framework-sys", 938 | "tempfile", 939 | ] 940 | 941 | [[package]] 942 | name = "num_cpus" 943 | version = "1.13.1" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 946 | dependencies = [ 947 | "hermit-abi", 948 | "libc", 949 | ] 950 | 951 | [[package]] 952 | name = "num_threads" 953 | version = "0.1.6" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" 956 | dependencies = [ 957 | "libc", 958 | ] 959 | 960 | [[package]] 961 | name = "once_cell" 962 | version = "1.15.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" 965 | 966 | [[package]] 967 | name = "openssl" 968 | version = "0.10.42" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" 971 | dependencies = [ 972 | "bitflags", 973 | "cfg-if", 974 | "foreign-types", 975 | "libc", 976 | "once_cell", 977 | "openssl-macros", 978 | "openssl-sys", 979 | ] 980 | 981 | [[package]] 982 | name = "openssl-macros" 983 | version = "0.1.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 986 | dependencies = [ 987 | "proc-macro2", 988 | "quote", 989 | "syn", 990 | ] 991 | 992 | [[package]] 993 | name = "openssl-probe" 994 | version = "0.1.5" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 997 | 998 | [[package]] 999 | name = "openssl-sys" 1000 | version = "0.9.76" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" 1003 | dependencies = [ 1004 | "autocfg", 1005 | "cc", 1006 | "libc", 1007 | "pkg-config", 1008 | "vcpkg", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "os_str_bytes" 1013 | version = "6.3.0" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" 1016 | 1017 | [[package]] 1018 | name = "ouroboros" 1019 | version = "0.15.5" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "dfbb50b356159620db6ac971c6d5c9ab788c9cc38a6f49619fca2a27acb062ca" 1022 | dependencies = [ 1023 | "aliasable", 1024 | "ouroboros_macro", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "ouroboros_macro" 1029 | version = "0.15.5" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "4a0d9d1a6191c4f391f87219d1ea42b23f09ee84d64763cd05ee6ea88d9f384d" 1032 | dependencies = [ 1033 | "Inflector", 1034 | "proc-macro-error", 1035 | "proc-macro2", 1036 | "quote", 1037 | "syn", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "parking_lot" 1042 | version = "0.12.1" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1045 | dependencies = [ 1046 | "lock_api", 1047 | "parking_lot_core", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "parking_lot_core" 1052 | version = "0.9.3" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 1055 | dependencies = [ 1056 | "cfg-if", 1057 | "libc", 1058 | "redox_syscall", 1059 | "smallvec", 1060 | "windows-sys", 1061 | ] 1062 | 1063 | [[package]] 1064 | name = "paste" 1065 | version = "1.0.9" 1066 | source = "registry+https://github.com/rust-lang/crates.io-index" 1067 | checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" 1068 | 1069 | [[package]] 1070 | name = "percent-encoding" 1071 | version = "2.2.0" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1074 | 1075 | [[package]] 1076 | name = "pin-project" 1077 | version = "1.0.12" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 1080 | dependencies = [ 1081 | "pin-project-internal", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "pin-project-internal" 1086 | version = "1.0.12" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 1089 | dependencies = [ 1090 | "proc-macro2", 1091 | "quote", 1092 | "syn", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "pin-project-lite" 1097 | version = "0.2.9" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1100 | 1101 | [[package]] 1102 | name = "pin-utils" 1103 | version = "0.1.0" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1106 | 1107 | [[package]] 1108 | name = "pkg-config" 1109 | version = "0.3.25" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 1112 | 1113 | [[package]] 1114 | name = "ppv-lite86" 1115 | version = "0.2.16" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 1118 | 1119 | [[package]] 1120 | name = "proc-macro-error" 1121 | version = "1.0.4" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1124 | dependencies = [ 1125 | "proc-macro-error-attr", 1126 | "proc-macro2", 1127 | "quote", 1128 | "syn", 1129 | "version_check", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "proc-macro-error-attr" 1134 | version = "1.0.4" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1137 | dependencies = [ 1138 | "proc-macro2", 1139 | "quote", 1140 | "version_check", 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "proc-macro2" 1145 | version = "1.0.46" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" 1148 | dependencies = [ 1149 | "unicode-ident", 1150 | ] 1151 | 1152 | [[package]] 1153 | name = "quote" 1154 | version = "1.0.21" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 1157 | dependencies = [ 1158 | "proc-macro2", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "rand" 1163 | version = "0.8.5" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1166 | dependencies = [ 1167 | "libc", 1168 | "rand_chacha", 1169 | "rand_core", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "rand_chacha" 1174 | version = "0.3.1" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1177 | dependencies = [ 1178 | "ppv-lite86", 1179 | "rand_core", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "rand_core" 1184 | version = "0.6.4" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1187 | dependencies = [ 1188 | "getrandom", 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "redox_syscall" 1193 | version = "0.2.16" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1196 | dependencies = [ 1197 | "bitflags", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "regex" 1202 | version = "1.6.0" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 1205 | dependencies = [ 1206 | "aho-corasick", 1207 | "memchr", 1208 | "regex-syntax", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "regex-syntax" 1213 | version = "0.6.27" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 1216 | 1217 | [[package]] 1218 | name = "remove_dir_all" 1219 | version = "0.5.3" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1222 | dependencies = [ 1223 | "winapi", 1224 | ] 1225 | 1226 | [[package]] 1227 | name = "reqwest" 1228 | version = "0.11.12" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" 1231 | dependencies = [ 1232 | "base64", 1233 | "bytes", 1234 | "encoding_rs", 1235 | "futures-core", 1236 | "futures-util", 1237 | "h2", 1238 | "http", 1239 | "http-body", 1240 | "hyper", 1241 | "hyper-tls", 1242 | "ipnet", 1243 | "js-sys", 1244 | "log", 1245 | "mime", 1246 | "native-tls", 1247 | "once_cell", 1248 | "percent-encoding", 1249 | "pin-project-lite", 1250 | "serde", 1251 | "serde_json", 1252 | "serde_urlencoded", 1253 | "tokio", 1254 | "tokio-native-tls", 1255 | "tokio-util", 1256 | "tower-service", 1257 | "url", 1258 | "wasm-bindgen", 1259 | "wasm-bindgen-futures", 1260 | "web-sys", 1261 | "winreg", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "rustc_version" 1266 | version = "0.4.0" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1269 | dependencies = [ 1270 | "semver", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "ryu" 1275 | version = "1.0.11" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 1278 | 1279 | [[package]] 1280 | name = "schannel" 1281 | version = "0.1.20" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" 1284 | dependencies = [ 1285 | "lazy_static", 1286 | "windows-sys", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "scopeguard" 1291 | version = "1.1.0" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1294 | 1295 | [[package]] 1296 | name = "security-framework" 1297 | version = "2.7.0" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" 1300 | dependencies = [ 1301 | "bitflags", 1302 | "core-foundation", 1303 | "core-foundation-sys", 1304 | "libc", 1305 | "security-framework-sys", 1306 | ] 1307 | 1308 | [[package]] 1309 | name = "security-framework-sys" 1310 | version = "2.6.1" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 1313 | dependencies = [ 1314 | "core-foundation-sys", 1315 | "libc", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "semver" 1320 | version = "1.0.14" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" 1323 | 1324 | [[package]] 1325 | name = "serde" 1326 | version = "1.0.145" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" 1329 | 1330 | [[package]] 1331 | name = "serde_json" 1332 | version = "1.0.86" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" 1335 | dependencies = [ 1336 | "itoa", 1337 | "ryu", 1338 | "serde", 1339 | ] 1340 | 1341 | [[package]] 1342 | name = "serde_urlencoded" 1343 | version = "0.7.1" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1346 | dependencies = [ 1347 | "form_urlencoded", 1348 | "itoa", 1349 | "ryu", 1350 | "serde", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "sha1" 1355 | version = "0.10.5" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" 1358 | dependencies = [ 1359 | "cfg-if", 1360 | "cpufeatures", 1361 | "digest", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "signal-hook-registry" 1366 | version = "1.4.0" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 1369 | dependencies = [ 1370 | "libc", 1371 | ] 1372 | 1373 | [[package]] 1374 | name = "slab" 1375 | version = "0.4.7" 1376 | source = "registry+https://github.com/rust-lang/crates.io-index" 1377 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 1378 | dependencies = [ 1379 | "autocfg", 1380 | ] 1381 | 1382 | [[package]] 1383 | name = "smallvec" 1384 | version = "1.10.0" 1385 | source = "registry+https://github.com/rust-lang/crates.io-index" 1386 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1387 | 1388 | [[package]] 1389 | name = "socket2" 1390 | version = "0.4.7" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 1393 | dependencies = [ 1394 | "libc", 1395 | "winapi", 1396 | ] 1397 | 1398 | [[package]] 1399 | name = "stream-cancel" 1400 | version = "0.8.1" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "7b0a9eb2715209fb8cc0d942fcdff45674bfc9f0090a0d897e85a22955ad159b" 1403 | dependencies = [ 1404 | "futures-core", 1405 | "pin-project", 1406 | "tokio", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "strsim" 1411 | version = "0.10.0" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1414 | 1415 | [[package]] 1416 | name = "syn" 1417 | version = "1.0.102" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" 1420 | dependencies = [ 1421 | "proc-macro2", 1422 | "quote", 1423 | "unicode-ident", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "tcp-over-http" 1428 | version = "0.1.0" 1429 | dependencies = [ 1430 | "actix-web", 1431 | "anyhow", 1432 | "bytes", 1433 | "clap", 1434 | "derivative", 1435 | "futures", 1436 | "halfbrown", 1437 | "itertools", 1438 | "lazy_static", 1439 | "ouroboros", 1440 | "rand", 1441 | "reqwest", 1442 | "stream-cancel", 1443 | "tokio", 1444 | "tokio-stream", 1445 | "tokio-util", 1446 | "uuid", 1447 | ] 1448 | 1449 | [[package]] 1450 | name = "tempfile" 1451 | version = "3.3.0" 1452 | source = "registry+https://github.com/rust-lang/crates.io-index" 1453 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 1454 | dependencies = [ 1455 | "cfg-if", 1456 | "fastrand", 1457 | "libc", 1458 | "redox_syscall", 1459 | "remove_dir_all", 1460 | "winapi", 1461 | ] 1462 | 1463 | [[package]] 1464 | name = "termcolor" 1465 | version = "1.1.3" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1468 | dependencies = [ 1469 | "winapi-util", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "time" 1474 | version = "0.3.15" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" 1477 | dependencies = [ 1478 | "itoa", 1479 | "libc", 1480 | "num_threads", 1481 | "time-macros", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "time-macros" 1486 | version = "0.2.4" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" 1489 | 1490 | [[package]] 1491 | name = "tinyvec" 1492 | version = "1.6.0" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1495 | dependencies = [ 1496 | "tinyvec_macros", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "tinyvec_macros" 1501 | version = "0.1.0" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1504 | 1505 | [[package]] 1506 | name = "tokio" 1507 | version = "1.21.2" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" 1510 | dependencies = [ 1511 | "autocfg", 1512 | "bytes", 1513 | "libc", 1514 | "memchr", 1515 | "mio", 1516 | "num_cpus", 1517 | "parking_lot", 1518 | "pin-project-lite", 1519 | "signal-hook-registry", 1520 | "socket2", 1521 | "tokio-macros", 1522 | "winapi", 1523 | ] 1524 | 1525 | [[package]] 1526 | name = "tokio-macros" 1527 | version = "1.8.0" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" 1530 | dependencies = [ 1531 | "proc-macro2", 1532 | "quote", 1533 | "syn", 1534 | ] 1535 | 1536 | [[package]] 1537 | name = "tokio-native-tls" 1538 | version = "0.3.0" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 1541 | dependencies = [ 1542 | "native-tls", 1543 | "tokio", 1544 | ] 1545 | 1546 | [[package]] 1547 | name = "tokio-stream" 1548 | version = "0.1.11" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" 1551 | dependencies = [ 1552 | "futures-core", 1553 | "pin-project-lite", 1554 | "tokio", 1555 | ] 1556 | 1557 | [[package]] 1558 | name = "tokio-util" 1559 | version = "0.7.4" 1560 | source = "registry+https://github.com/rust-lang/crates.io-index" 1561 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 1562 | dependencies = [ 1563 | "bytes", 1564 | "futures-core", 1565 | "futures-io", 1566 | "futures-sink", 1567 | "pin-project-lite", 1568 | "tokio", 1569 | "tracing", 1570 | ] 1571 | 1572 | [[package]] 1573 | name = "tower-service" 1574 | version = "0.3.2" 1575 | source = "registry+https://github.com/rust-lang/crates.io-index" 1576 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1577 | 1578 | [[package]] 1579 | name = "tracing" 1580 | version = "0.1.37" 1581 | source = "registry+https://github.com/rust-lang/crates.io-index" 1582 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1583 | dependencies = [ 1584 | "cfg-if", 1585 | "log", 1586 | "pin-project-lite", 1587 | "tracing-core", 1588 | ] 1589 | 1590 | [[package]] 1591 | name = "tracing-core" 1592 | version = "0.1.30" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1595 | dependencies = [ 1596 | "once_cell", 1597 | ] 1598 | 1599 | [[package]] 1600 | name = "try-lock" 1601 | version = "0.2.3" 1602 | source = "registry+https://github.com/rust-lang/crates.io-index" 1603 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1604 | 1605 | [[package]] 1606 | name = "typenum" 1607 | version = "1.15.0" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1610 | 1611 | [[package]] 1612 | name = "unicode-bidi" 1613 | version = "0.3.8" 1614 | source = "registry+https://github.com/rust-lang/crates.io-index" 1615 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 1616 | 1617 | [[package]] 1618 | name = "unicode-ident" 1619 | version = "1.0.5" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 1622 | 1623 | [[package]] 1624 | name = "unicode-normalization" 1625 | version = "0.1.22" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1628 | dependencies = [ 1629 | "tinyvec", 1630 | ] 1631 | 1632 | [[package]] 1633 | name = "url" 1634 | version = "2.3.1" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1637 | dependencies = [ 1638 | "form_urlencoded", 1639 | "idna", 1640 | "percent-encoding", 1641 | ] 1642 | 1643 | [[package]] 1644 | name = "uuid" 1645 | version = "1.2.1" 1646 | source = "registry+https://github.com/rust-lang/crates.io-index" 1647 | checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" 1648 | dependencies = [ 1649 | "getrandom", 1650 | ] 1651 | 1652 | [[package]] 1653 | name = "vcpkg" 1654 | version = "0.2.15" 1655 | source = "registry+https://github.com/rust-lang/crates.io-index" 1656 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1657 | 1658 | [[package]] 1659 | name = "version_check" 1660 | version = "0.9.4" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1663 | 1664 | [[package]] 1665 | name = "want" 1666 | version = "0.3.0" 1667 | source = "registry+https://github.com/rust-lang/crates.io-index" 1668 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1669 | dependencies = [ 1670 | "log", 1671 | "try-lock", 1672 | ] 1673 | 1674 | [[package]] 1675 | name = "wasi" 1676 | version = "0.11.0+wasi-snapshot-preview1" 1677 | source = "registry+https://github.com/rust-lang/crates.io-index" 1678 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1679 | 1680 | [[package]] 1681 | name = "wasm-bindgen" 1682 | version = "0.2.83" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 1685 | dependencies = [ 1686 | "cfg-if", 1687 | "wasm-bindgen-macro", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "wasm-bindgen-backend" 1692 | version = "0.2.83" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 1695 | dependencies = [ 1696 | "bumpalo", 1697 | "log", 1698 | "once_cell", 1699 | "proc-macro2", 1700 | "quote", 1701 | "syn", 1702 | "wasm-bindgen-shared", 1703 | ] 1704 | 1705 | [[package]] 1706 | name = "wasm-bindgen-futures" 1707 | version = "0.4.33" 1708 | source = "registry+https://github.com/rust-lang/crates.io-index" 1709 | checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" 1710 | dependencies = [ 1711 | "cfg-if", 1712 | "js-sys", 1713 | "wasm-bindgen", 1714 | "web-sys", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "wasm-bindgen-macro" 1719 | version = "0.2.83" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 1722 | dependencies = [ 1723 | "quote", 1724 | "wasm-bindgen-macro-support", 1725 | ] 1726 | 1727 | [[package]] 1728 | name = "wasm-bindgen-macro-support" 1729 | version = "0.2.83" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 1732 | dependencies = [ 1733 | "proc-macro2", 1734 | "quote", 1735 | "syn", 1736 | "wasm-bindgen-backend", 1737 | "wasm-bindgen-shared", 1738 | ] 1739 | 1740 | [[package]] 1741 | name = "wasm-bindgen-shared" 1742 | version = "0.2.83" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 1745 | 1746 | [[package]] 1747 | name = "web-sys" 1748 | version = "0.3.60" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 1751 | dependencies = [ 1752 | "js-sys", 1753 | "wasm-bindgen", 1754 | ] 1755 | 1756 | [[package]] 1757 | name = "winapi" 1758 | version = "0.3.9" 1759 | source = "registry+https://github.com/rust-lang/crates.io-index" 1760 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1761 | dependencies = [ 1762 | "winapi-i686-pc-windows-gnu", 1763 | "winapi-x86_64-pc-windows-gnu", 1764 | ] 1765 | 1766 | [[package]] 1767 | name = "winapi-i686-pc-windows-gnu" 1768 | version = "0.4.0" 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" 1770 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1771 | 1772 | [[package]] 1773 | name = "winapi-util" 1774 | version = "0.1.5" 1775 | source = "registry+https://github.com/rust-lang/crates.io-index" 1776 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1777 | dependencies = [ 1778 | "winapi", 1779 | ] 1780 | 1781 | [[package]] 1782 | name = "winapi-x86_64-pc-windows-gnu" 1783 | version = "0.4.0" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1786 | 1787 | [[package]] 1788 | name = "windows-sys" 1789 | version = "0.36.1" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1792 | dependencies = [ 1793 | "windows_aarch64_msvc", 1794 | "windows_i686_gnu", 1795 | "windows_i686_msvc", 1796 | "windows_x86_64_gnu", 1797 | "windows_x86_64_msvc", 1798 | ] 1799 | 1800 | [[package]] 1801 | name = "windows_aarch64_msvc" 1802 | version = "0.36.1" 1803 | source = "registry+https://github.com/rust-lang/crates.io-index" 1804 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1805 | 1806 | [[package]] 1807 | name = "windows_i686_gnu" 1808 | version = "0.36.1" 1809 | source = "registry+https://github.com/rust-lang/crates.io-index" 1810 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1811 | 1812 | [[package]] 1813 | name = "windows_i686_msvc" 1814 | version = "0.36.1" 1815 | source = "registry+https://github.com/rust-lang/crates.io-index" 1816 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1817 | 1818 | [[package]] 1819 | name = "windows_x86_64_gnu" 1820 | version = "0.36.1" 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" 1822 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1823 | 1824 | [[package]] 1825 | name = "windows_x86_64_msvc" 1826 | version = "0.36.1" 1827 | source = "registry+https://github.com/rust-lang/crates.io-index" 1828 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1829 | 1830 | [[package]] 1831 | name = "winreg" 1832 | version = "0.10.1" 1833 | source = "registry+https://github.com/rust-lang/crates.io-index" 1834 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 1835 | dependencies = [ 1836 | "winapi", 1837 | ] 1838 | 1839 | [[package]] 1840 | name = "zstd" 1841 | version = "0.11.2+zstd.1.5.2" 1842 | source = "registry+https://github.com/rust-lang/crates.io-index" 1843 | checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" 1844 | dependencies = [ 1845 | "zstd-safe", 1846 | ] 1847 | 1848 | [[package]] 1849 | name = "zstd-safe" 1850 | version = "5.0.2+zstd.1.5.2" 1851 | source = "registry+https://github.com/rust-lang/crates.io-index" 1852 | checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" 1853 | dependencies = [ 1854 | "libc", 1855 | "zstd-sys", 1856 | ] 1857 | 1858 | [[package]] 1859 | name = "zstd-sys" 1860 | version = "2.0.1+zstd.1.5.2" 1861 | source = "registry+https://github.com/rust-lang/crates.io-index" 1862 | checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" 1863 | dependencies = [ 1864 | "cc", 1865 | "libc", 1866 | ] 1867 | --------------------------------------------------------------------------------