├── .gitignore ├── Cargo.toml ├── README.md ├── LICENSE ├── src └── main.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "email" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | axum = "0.6.20" 10 | tokio = { version = "1.32", features = ["full"] } 11 | base64 = "0.21.4" 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Email Tracker 2 | Simple server written in Rust that can be used to track how many times an email has been read. 3 | 4 | ## How it works 5 | 1. Making a `GET` request to any route (e.g. `localhost:3030/email-1`, `localhost:3030:/email-2`) return a transparent 1x1 image 6 | 2. Additionally, every time a `GET` request is serviced, it is logged to count the total number of views 7 | 3. By embedding a url (e.g. `localhost:3030/email-1`) as an image in an email, the image is loaded every time the email is read and is thus logged 8 | 9 | Note that email tracking blockers exist and hinder the efficacy of using this approach to track emails. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 David Mo 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/main.rs: -------------------------------------------------------------------------------- 1 | use axum::{ 2 | extract::{ConnectInfo, Path, State}, 3 | http::{header, HeaderValue}, 4 | response::IntoResponse, 5 | routing::get, 6 | Router, 7 | }; 8 | use base64::{engine::general_purpose, Engine as _}; 9 | use std::{ 10 | collections::HashMap, 11 | env, 12 | net::SocketAddr, 13 | sync::{Arc, Mutex}, 14 | }; 15 | 16 | type SharedState = Arc>; 17 | 18 | #[derive(Default)] 19 | struct AppState { 20 | view_counts: HashMap, 21 | } 22 | 23 | #[tokio::main] 24 | async fn main() { 25 | let state = SharedState::default(); 26 | 27 | let app = Router::new() 28 | .route("/tracker/*path", get(tracker)) 29 | .route("/views/*path", get(views)) 30 | .with_state(state); 31 | 32 | let host = env::var("HOST").unwrap_or("127.0.0.1".to_string()); 33 | let port = env::var("PORT").unwrap_or("3030".to_string()); 34 | let addr = format!("{host}:{port}"); 35 | println!("Server started, listening on http://{addr}"); 36 | 37 | axum::Server::bind(&addr.parse().unwrap()) 38 | .serve(app.into_make_service_with_connect_info::()) 39 | .await 40 | .expect("Failed to start server"); 41 | } 42 | 43 | async fn tracker( 44 | ConnectInfo(addr): ConnectInfo, 45 | Path(path): Path, 46 | State(state): State, 47 | ) -> impl IntoResponse { 48 | let mut lock = state.lock().unwrap(); 49 | let new_view_count = *lock.view_counts.get(&path).unwrap_or(&0) + 1; 50 | lock.view_counts.insert(path.clone(), new_view_count); 51 | 52 | println!("Request from {addr} to /{path} ({new_view_count} views)"); 53 | 54 | let one_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mPk+89QDwADvgGOSHzRgAAAAABJRU5ErkJggg=="; 55 | let one_pixel = general_purpose::STANDARD.decode(one_pixel_base64).unwrap(); 56 | ( 57 | [(header::CONTENT_TYPE, HeaderValue::from_static("image/png"))], 58 | one_pixel, 59 | ) 60 | } 61 | 62 | async fn views(Path(path): Path, State(state): State) -> impl IntoResponse { 63 | let lock = &state.lock().unwrap(); 64 | let view_count = lock.view_counts.get(&path).unwrap_or(&0); 65 | format!("{view_count}") 66 | } 67 | -------------------------------------------------------------------------------- /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 = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "async-trait" 22 | version = "0.1.73" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" 25 | dependencies = [ 26 | "proc-macro2", 27 | "quote", 28 | "syn", 29 | ] 30 | 31 | [[package]] 32 | name = "autocfg" 33 | version = "1.1.0" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 36 | 37 | [[package]] 38 | name = "axum" 39 | version = "0.6.20" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" 42 | dependencies = [ 43 | "async-trait", 44 | "axum-core", 45 | "bitflags", 46 | "bytes", 47 | "futures-util", 48 | "http", 49 | "http-body", 50 | "hyper", 51 | "itoa", 52 | "matchit", 53 | "memchr", 54 | "mime", 55 | "percent-encoding", 56 | "pin-project-lite", 57 | "rustversion", 58 | "serde", 59 | "serde_json", 60 | "serde_path_to_error", 61 | "serde_urlencoded", 62 | "sync_wrapper", 63 | "tokio", 64 | "tower", 65 | "tower-layer", 66 | "tower-service", 67 | ] 68 | 69 | [[package]] 70 | name = "axum-core" 71 | version = "0.3.4" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" 74 | dependencies = [ 75 | "async-trait", 76 | "bytes", 77 | "futures-util", 78 | "http", 79 | "http-body", 80 | "mime", 81 | "rustversion", 82 | "tower-layer", 83 | "tower-service", 84 | ] 85 | 86 | [[package]] 87 | name = "backtrace" 88 | version = "0.3.69" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 91 | dependencies = [ 92 | "addr2line", 93 | "cc", 94 | "cfg-if", 95 | "libc", 96 | "miniz_oxide", 97 | "object", 98 | "rustc-demangle", 99 | ] 100 | 101 | [[package]] 102 | name = "base64" 103 | version = "0.21.4" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" 106 | 107 | [[package]] 108 | name = "bitflags" 109 | version = "1.3.2" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 112 | 113 | [[package]] 114 | name = "bytes" 115 | version = "1.5.0" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 118 | 119 | [[package]] 120 | name = "cc" 121 | version = "1.0.83" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 124 | dependencies = [ 125 | "libc", 126 | ] 127 | 128 | [[package]] 129 | name = "cfg-if" 130 | version = "1.0.0" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 133 | 134 | [[package]] 135 | name = "email" 136 | version = "0.1.0" 137 | dependencies = [ 138 | "axum", 139 | "base64", 140 | "tokio", 141 | ] 142 | 143 | [[package]] 144 | name = "fnv" 145 | version = "1.0.7" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 148 | 149 | [[package]] 150 | name = "form_urlencoded" 151 | version = "1.2.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 154 | dependencies = [ 155 | "percent-encoding", 156 | ] 157 | 158 | [[package]] 159 | name = "futures-channel" 160 | version = "0.3.28" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 163 | dependencies = [ 164 | "futures-core", 165 | ] 166 | 167 | [[package]] 168 | name = "futures-core" 169 | version = "0.3.28" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 172 | 173 | [[package]] 174 | name = "futures-task" 175 | version = "0.3.28" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 178 | 179 | [[package]] 180 | name = "futures-util" 181 | version = "0.3.28" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 184 | dependencies = [ 185 | "futures-core", 186 | "futures-task", 187 | "pin-project-lite", 188 | "pin-utils", 189 | ] 190 | 191 | [[package]] 192 | name = "gimli" 193 | version = "0.28.0" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 196 | 197 | [[package]] 198 | name = "hermit-abi" 199 | version = "0.3.3" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" 202 | 203 | [[package]] 204 | name = "http" 205 | version = "0.2.9" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 208 | dependencies = [ 209 | "bytes", 210 | "fnv", 211 | "itoa", 212 | ] 213 | 214 | [[package]] 215 | name = "http-body" 216 | version = "0.4.5" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 219 | dependencies = [ 220 | "bytes", 221 | "http", 222 | "pin-project-lite", 223 | ] 224 | 225 | [[package]] 226 | name = "httparse" 227 | version = "1.8.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 230 | 231 | [[package]] 232 | name = "httpdate" 233 | version = "1.0.3" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 236 | 237 | [[package]] 238 | name = "hyper" 239 | version = "0.14.27" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 242 | dependencies = [ 243 | "bytes", 244 | "futures-channel", 245 | "futures-core", 246 | "futures-util", 247 | "http", 248 | "http-body", 249 | "httparse", 250 | "httpdate", 251 | "itoa", 252 | "pin-project-lite", 253 | "socket2 0.4.9", 254 | "tokio", 255 | "tower-service", 256 | "tracing", 257 | "want", 258 | ] 259 | 260 | [[package]] 261 | name = "itoa" 262 | version = "1.0.9" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 265 | 266 | [[package]] 267 | name = "libc" 268 | version = "0.2.148" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" 271 | 272 | [[package]] 273 | name = "lock_api" 274 | version = "0.4.10" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 277 | dependencies = [ 278 | "autocfg", 279 | "scopeguard", 280 | ] 281 | 282 | [[package]] 283 | name = "log" 284 | version = "0.4.20" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 287 | 288 | [[package]] 289 | name = "matchit" 290 | version = "0.7.3" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 293 | 294 | [[package]] 295 | name = "memchr" 296 | version = "2.6.3" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" 299 | 300 | [[package]] 301 | name = "mime" 302 | version = "0.3.17" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 305 | 306 | [[package]] 307 | name = "miniz_oxide" 308 | version = "0.7.1" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 311 | dependencies = [ 312 | "adler", 313 | ] 314 | 315 | [[package]] 316 | name = "mio" 317 | version = "0.8.8" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 320 | dependencies = [ 321 | "libc", 322 | "wasi", 323 | "windows-sys", 324 | ] 325 | 326 | [[package]] 327 | name = "num_cpus" 328 | version = "1.16.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 331 | dependencies = [ 332 | "hermit-abi", 333 | "libc", 334 | ] 335 | 336 | [[package]] 337 | name = "object" 338 | version = "0.32.1" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 341 | dependencies = [ 342 | "memchr", 343 | ] 344 | 345 | [[package]] 346 | name = "once_cell" 347 | version = "1.18.0" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 350 | 351 | [[package]] 352 | name = "parking_lot" 353 | version = "0.12.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 356 | dependencies = [ 357 | "lock_api", 358 | "parking_lot_core", 359 | ] 360 | 361 | [[package]] 362 | name = "parking_lot_core" 363 | version = "0.9.8" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 366 | dependencies = [ 367 | "cfg-if", 368 | "libc", 369 | "redox_syscall", 370 | "smallvec", 371 | "windows-targets", 372 | ] 373 | 374 | [[package]] 375 | name = "percent-encoding" 376 | version = "2.3.0" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 379 | 380 | [[package]] 381 | name = "pin-project" 382 | version = "1.1.3" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" 385 | dependencies = [ 386 | "pin-project-internal", 387 | ] 388 | 389 | [[package]] 390 | name = "pin-project-internal" 391 | version = "1.1.3" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" 394 | dependencies = [ 395 | "proc-macro2", 396 | "quote", 397 | "syn", 398 | ] 399 | 400 | [[package]] 401 | name = "pin-project-lite" 402 | version = "0.2.13" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 405 | 406 | [[package]] 407 | name = "pin-utils" 408 | version = "0.1.0" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 411 | 412 | [[package]] 413 | name = "proc-macro2" 414 | version = "1.0.67" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" 417 | dependencies = [ 418 | "unicode-ident", 419 | ] 420 | 421 | [[package]] 422 | name = "quote" 423 | version = "1.0.33" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 426 | dependencies = [ 427 | "proc-macro2", 428 | ] 429 | 430 | [[package]] 431 | name = "redox_syscall" 432 | version = "0.3.5" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 435 | dependencies = [ 436 | "bitflags", 437 | ] 438 | 439 | [[package]] 440 | name = "rustc-demangle" 441 | version = "0.1.23" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 444 | 445 | [[package]] 446 | name = "rustversion" 447 | version = "1.0.14" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 450 | 451 | [[package]] 452 | name = "ryu" 453 | version = "1.0.15" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 456 | 457 | [[package]] 458 | name = "scopeguard" 459 | version = "1.2.0" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 462 | 463 | [[package]] 464 | name = "serde" 465 | version = "1.0.188" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 468 | dependencies = [ 469 | "serde_derive", 470 | ] 471 | 472 | [[package]] 473 | name = "serde_derive" 474 | version = "1.0.188" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 477 | dependencies = [ 478 | "proc-macro2", 479 | "quote", 480 | "syn", 481 | ] 482 | 483 | [[package]] 484 | name = "serde_json" 485 | version = "1.0.107" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" 488 | dependencies = [ 489 | "itoa", 490 | "ryu", 491 | "serde", 492 | ] 493 | 494 | [[package]] 495 | name = "serde_path_to_error" 496 | version = "0.1.14" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" 499 | dependencies = [ 500 | "itoa", 501 | "serde", 502 | ] 503 | 504 | [[package]] 505 | name = "serde_urlencoded" 506 | version = "0.7.1" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 509 | dependencies = [ 510 | "form_urlencoded", 511 | "itoa", 512 | "ryu", 513 | "serde", 514 | ] 515 | 516 | [[package]] 517 | name = "signal-hook-registry" 518 | version = "1.4.1" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 521 | dependencies = [ 522 | "libc", 523 | ] 524 | 525 | [[package]] 526 | name = "smallvec" 527 | version = "1.11.1" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" 530 | 531 | [[package]] 532 | name = "socket2" 533 | version = "0.4.9" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 536 | dependencies = [ 537 | "libc", 538 | "winapi", 539 | ] 540 | 541 | [[package]] 542 | name = "socket2" 543 | version = "0.5.4" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" 546 | dependencies = [ 547 | "libc", 548 | "windows-sys", 549 | ] 550 | 551 | [[package]] 552 | name = "syn" 553 | version = "2.0.37" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" 556 | dependencies = [ 557 | "proc-macro2", 558 | "quote", 559 | "unicode-ident", 560 | ] 561 | 562 | [[package]] 563 | name = "sync_wrapper" 564 | version = "0.1.2" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 567 | 568 | [[package]] 569 | name = "tokio" 570 | version = "1.32.0" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 573 | dependencies = [ 574 | "backtrace", 575 | "bytes", 576 | "libc", 577 | "mio", 578 | "num_cpus", 579 | "parking_lot", 580 | "pin-project-lite", 581 | "signal-hook-registry", 582 | "socket2 0.5.4", 583 | "tokio-macros", 584 | "windows-sys", 585 | ] 586 | 587 | [[package]] 588 | name = "tokio-macros" 589 | version = "2.1.0" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 592 | dependencies = [ 593 | "proc-macro2", 594 | "quote", 595 | "syn", 596 | ] 597 | 598 | [[package]] 599 | name = "tower" 600 | version = "0.4.13" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 603 | dependencies = [ 604 | "futures-core", 605 | "futures-util", 606 | "pin-project", 607 | "pin-project-lite", 608 | "tokio", 609 | "tower-layer", 610 | "tower-service", 611 | "tracing", 612 | ] 613 | 614 | [[package]] 615 | name = "tower-layer" 616 | version = "0.3.2" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 619 | 620 | [[package]] 621 | name = "tower-service" 622 | version = "0.3.2" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 625 | 626 | [[package]] 627 | name = "tracing" 628 | version = "0.1.37" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 631 | dependencies = [ 632 | "cfg-if", 633 | "log", 634 | "pin-project-lite", 635 | "tracing-core", 636 | ] 637 | 638 | [[package]] 639 | name = "tracing-core" 640 | version = "0.1.31" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 643 | dependencies = [ 644 | "once_cell", 645 | ] 646 | 647 | [[package]] 648 | name = "try-lock" 649 | version = "0.2.4" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 652 | 653 | [[package]] 654 | name = "unicode-ident" 655 | version = "1.0.12" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 658 | 659 | [[package]] 660 | name = "want" 661 | version = "0.3.1" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 664 | dependencies = [ 665 | "try-lock", 666 | ] 667 | 668 | [[package]] 669 | name = "wasi" 670 | version = "0.11.0+wasi-snapshot-preview1" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 673 | 674 | [[package]] 675 | name = "winapi" 676 | version = "0.3.9" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 679 | dependencies = [ 680 | "winapi-i686-pc-windows-gnu", 681 | "winapi-x86_64-pc-windows-gnu", 682 | ] 683 | 684 | [[package]] 685 | name = "winapi-i686-pc-windows-gnu" 686 | version = "0.4.0" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 689 | 690 | [[package]] 691 | name = "winapi-x86_64-pc-windows-gnu" 692 | version = "0.4.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 695 | 696 | [[package]] 697 | name = "windows-sys" 698 | version = "0.48.0" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 701 | dependencies = [ 702 | "windows-targets", 703 | ] 704 | 705 | [[package]] 706 | name = "windows-targets" 707 | version = "0.48.5" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 710 | dependencies = [ 711 | "windows_aarch64_gnullvm", 712 | "windows_aarch64_msvc", 713 | "windows_i686_gnu", 714 | "windows_i686_msvc", 715 | "windows_x86_64_gnu", 716 | "windows_x86_64_gnullvm", 717 | "windows_x86_64_msvc", 718 | ] 719 | 720 | [[package]] 721 | name = "windows_aarch64_gnullvm" 722 | version = "0.48.5" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 725 | 726 | [[package]] 727 | name = "windows_aarch64_msvc" 728 | version = "0.48.5" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 731 | 732 | [[package]] 733 | name = "windows_i686_gnu" 734 | version = "0.48.5" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 737 | 738 | [[package]] 739 | name = "windows_i686_msvc" 740 | version = "0.48.5" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 743 | 744 | [[package]] 745 | name = "windows_x86_64_gnu" 746 | version = "0.48.5" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 749 | 750 | [[package]] 751 | name = "windows_x86_64_gnullvm" 752 | version = "0.48.5" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 755 | 756 | [[package]] 757 | name = "windows_x86_64_msvc" 758 | version = "0.48.5" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 761 | --------------------------------------------------------------------------------