From 60f2e330a4c4daff12549db12df3a38026d4a372 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Mon, 13 Jan 2020 23:04:05 -0800 Subject: [PATCH 01/32] Moved rocket stuff into its own module --- src/main.rs | 13 +++---------- src/service/mod.rs | 3 +++ src/{ => service/rocket}/api.rs | 2 +- src/{ => service/rocket}/api_tests.rs | 4 ++-- src/service/rocket/mod.rs | 13 +++++++++++++ src/{ => service/rocket}/serve.rs | 0 src/{ => service/rocket}/server.rs | 3 ++- src/{ => service/rocket}/swagger.rs | 4 ++-- src/{ => service/rocket}/test.rs | 2 +- src/{ => service/rocket}/web.rs | 6 +++--- 10 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 src/service/mod.rs rename src/{ => service/rocket}/api.rs (99%) rename src/{ => service/rocket}/api_tests.rs (99%) create mode 100644 src/service/rocket/mod.rs rename src/{ => service/rocket}/serve.rs (100%) rename src/{ => service/rocket}/server.rs (95%) rename src/{ => service/rocket}/swagger.rs (86%) rename src/{ => service/rocket}/test.rs (98%) rename src/{ => service/rocket}/web.rs (74%) diff --git a/src/main.rs b/src/main.rs index 0060d97..55da3e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,9 +28,6 @@ use simplelog::{LevelFilter, SimpleLogger, TermLogger, TerminalMode}; use std::path::Path; use std::sync::Arc; -mod api; -#[cfg(test)] -mod api_tests; mod config; mod db; mod ddns; @@ -38,17 +35,13 @@ mod index; mod lastfm; mod metadata; mod playlist; -mod serve; -mod server; -mod swagger; -#[cfg(test)] -mod test; +mod service; + mod thumbnails; mod ui; mod user; mod utils; mod vfs; -mod web; fn log_config() -> simplelog::Config { simplelog::ConfigBuilder::new() @@ -227,7 +220,7 @@ fn main() -> Result<()> { .parse() .with_context(|| "Invalid port number")?; - let server = server::get_server( + let server = service::server::get_server( port, Some(auth_secret.as_slice()), &api_url, diff --git a/src/service/mod.rs b/src/service/mod.rs new file mode 100644 index 0000000..5a2fb6e --- /dev/null +++ b/src/service/mod.rs @@ -0,0 +1,3 @@ +mod rocket; + +pub use self::rocket::*; diff --git a/src/api.rs b/src/service/rocket/api.rs similarity index 99% rename from src/api.rs rename to src/service/rocket/api.rs index 1546150..64c7b3d 100644 --- a/src/api.rs +++ b/src/service/rocket/api.rs @@ -14,12 +14,12 @@ use std::sync::Arc; use thiserror::Error; use time::Duration; +use super::serve; use crate::config::{self, Config, Preferences}; use crate::db::DB; use crate::index; use crate::lastfm; use crate::playlist; -use crate::serve; use crate::thumbnails; use crate::user; use crate::utils; diff --git a/src/api_tests.rs b/src/service/rocket/api_tests.rs similarity index 99% rename from src/api_tests.rs rename to src/service/rocket/api_tests.rs index f39f6a1..f792563 100644 --- a/src/api_tests.rs +++ b/src/service/rocket/api_tests.rs @@ -4,13 +4,13 @@ use rocket::http::Status; use rocket::local::Client; use std::{thread, time}; -use crate::api; +use super::api; use crate::config; use crate::ddns; use crate::index; use crate::vfs; -use crate::test::get_test_environment; +use super::test::get_test_environment; const TEST_USERNAME: &str = "test_user"; const TEST_PASSWORD: &str = "test_password"; diff --git a/src/service/rocket/mod.rs b/src/service/rocket/mod.rs new file mode 100644 index 0000000..d335ee8 --- /dev/null +++ b/src/service/rocket/mod.rs @@ -0,0 +1,13 @@ +mod api; +mod serve; + +pub mod server; + +#[cfg(test)] +mod api_tests; +#[cfg(test)] +mod swagger; +#[cfg(test)] +mod test; +#[cfg(test)] +mod web; diff --git a/src/serve.rs b/src/service/rocket/serve.rs similarity index 100% rename from src/serve.rs rename to src/service/rocket/serve.rs diff --git a/src/server.rs b/src/service/rocket/server.rs similarity index 95% rename from src/server.rs rename to src/service/rocket/server.rs index 2898ae9..771b5f1 100644 --- a/src/server.rs +++ b/src/service/rocket/server.rs @@ -5,6 +5,7 @@ use rocket_contrib::serve::StaticFiles; use std::path::PathBuf; use std::sync::Arc; +use super::api; use crate::db::DB; use crate::index::CommandSender; @@ -36,7 +37,7 @@ pub fn get_server( Ok(rocket::custom(config) .manage(db) .manage(command_sender) - .mount(&api_url, crate::api::get_routes()) + .mount(&api_url, api::get_routes()) .mount( &swagger_url, StaticFiles::from(swagger_dir_path).rank(swagger_routes_rank), diff --git a/src/swagger.rs b/src/service/rocket/swagger.rs similarity index 86% rename from src/swagger.rs rename to src/service/rocket/swagger.rs index 8183c72..6eeafe5 100644 --- a/src/swagger.rs +++ b/src/service/rocket/swagger.rs @@ -1,6 +1,7 @@ +use super::test::get_test_environment; + #[test] fn test_index() { - use crate::test::get_test_environment; use rocket::http::Status; let env = get_test_environment("swagger_index.sqlite"); let client = &env.client; @@ -10,7 +11,6 @@ fn test_index() { #[test] fn test_index_with_trailing_slash() { - use crate::test::get_test_environment; use rocket::http::Status; let env = get_test_environment("swagger_index_with_trailing_slash.sqlite"); let client = &env.client; diff --git a/src/test.rs b/src/service/rocket/test.rs similarity index 98% rename from src/test.rs rename to src/service/rocket/test.rs index 72487ae..2705822 100644 --- a/src/test.rs +++ b/src/service/rocket/test.rs @@ -5,9 +5,9 @@ use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; +use super::server; use crate::db::DB; use crate::index; -use crate::server; pub struct TestEnvironment { pub client: Client, diff --git a/src/web.rs b/src/service/rocket/web.rs similarity index 74% rename from src/web.rs rename to src/service/rocket/web.rs index ffe7a3f..a9a46cf 100644 --- a/src/web.rs +++ b/src/service/rocket/web.rs @@ -1,8 +1,8 @@ +use super::test::get_test_environment; +use rocket::http::Status; + #[test] fn test_index() { - use crate::test::get_test_environment; - use rocket::http::Status; - let env = get_test_environment("web_index.sqlite"); let client = &env.client; let response = client.get("/").dispatch(); From ba901c78737c8efddeaef089b7ec896fccc1631f Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Mon, 13 Jan 2020 23:12:33 -0800 Subject: [PATCH 02/32] Optional rocket feature --- Cargo.toml | 6 +++++- src/service/mod.rs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2ac3737..38132db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,11 @@ authors = ["Antoine Gersant "] edition = "2018" [features] +default = ["service-rocket"] ui = [] profile-index = ["flame", "flamer"] +service-actix = [] +service-rocket = ["rocket", "rocket_contrib"] [dependencies] anyhow = "1.0" @@ -30,7 +33,7 @@ pbkdf2 = "0.3" rand = "0.7" regex = "1.2" reqwest = "0.9.2" -rocket = "0.4.2" +rocket = { version = "0.4.2", optional = true } rust-crypto = "0.2.36" serde = { version = "1.0", features = ["derive"] } serde_derive = "1.0" @@ -44,6 +47,7 @@ toml = "0.5" version = "0.4.2" default_features = false features = ["json", "serve"] +optional = true [target.'cfg(windows)'.dependencies] uuid = "0.8" diff --git a/src/service/mod.rs b/src/service/mod.rs index 5a2fb6e..6df3dba 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,3 +1,4 @@ mod rocket; +#[cfg(feature = "service-rocket")] pub use self::rocket::*; From 0a4d05cdc8830da7cd696e0621125557a9416db5 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Mon, 13 Jan 2020 23:56:46 -0800 Subject: [PATCH 03/32] Actix hello world --- Cargo.lock | 783 +++++++++++++++++++++++++++++ Cargo.toml | 6 +- src/main.rs | 5 +- src/service/actix/mod.rs | 4 + src/service/actix/server.rs | 32 ++ src/service/actix/tests/api.rs | 0 src/service/actix/tests/mod.rs | 1 + src/service/actix/tests/swagger.rs | 0 src/service/actix/tests/web.rs | 0 src/service/mod.rs | 7 +- src/service/rocket/server.rs | 28 ++ 11 files changed, 859 insertions(+), 7 deletions(-) create mode 100644 src/service/actix/mod.rs create mode 100644 src/service/actix/server.rs create mode 100644 src/service/actix/tests/api.rs create mode 100644 src/service/actix/tests/mod.rs create mode 100644 src/service/actix/tests/swagger.rs create mode 100644 src/service/actix/tests/web.rs diff --git a/Cargo.lock b/Cargo.lock index a3c6229..76cadb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,248 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "actix-codec" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-connect" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-http" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-connect 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-router" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytestring 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-rt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-server" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-service" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-testing" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-threadpool" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-utils" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-web" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-testing 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-web-codegen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "adler32" version = "1.0.4" @@ -37,6 +280,11 @@ dependencies = [ "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arc-swap" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayref" version = "0.3.5" @@ -47,6 +295,16 @@ name = "arrayvec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "async-trait" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atty" version = "0.2.13" @@ -61,6 +319,28 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "awc" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "backtrace" version = "0.3.40" @@ -137,6 +417,24 @@ dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "byte-tools" version = "0.3.1" @@ -157,6 +455,19 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bytes" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytestring" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "c2-chacha" version = "0.2.3" @@ -240,6 +551,11 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "copyless" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "core-foundation" version = "0.6.4" @@ -392,6 +708,16 @@ dependencies = [ "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "derive_more" +version = "0.99.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "devise" version = "0.2.0" @@ -553,6 +879,17 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "enum-as-inner" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.12.1" @@ -689,6 +1026,34 @@ name = "futures" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "futures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-channel" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "futures-cpupool" version = "0.1.8" @@ -698,6 +1063,68 @@ dependencies = [ "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "futures-executor" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-io" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-macro" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-sink" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-task" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gcc" version = "0.3.55" @@ -755,6 +1182,32 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "h2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hermit-abi" version = "0.1.5" @@ -777,6 +1230,15 @@ dependencies = [ "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hostname" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http" version = "0.1.21" @@ -787,6 +1249,16 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http-body" version = "0.1.0" @@ -959,6 +1431,17 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipconfig" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" @@ -1027,6 +1510,11 @@ dependencies = [ "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "linked-hash-map" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lock_api" version = "0.3.2" @@ -1051,6 +1539,14 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lzw" version = "0.10.0" @@ -1168,6 +1664,16 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.2.1" @@ -1383,6 +1889,15 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.6.2" @@ -1397,6 +1912,19 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pbkdf2" version = "0.3.0" @@ -1441,6 +1969,34 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pin-project" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pin-utils" +version = "0.1.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pkg-config" version = "0.3.17" @@ -1461,6 +2017,8 @@ dependencies = [ name = "polaris" version = "0.11.0" dependencies = [ + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1503,6 +2061,21 @@ name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro-hack" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-nested" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -1531,6 +2104,11 @@ dependencies = [ "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.3.15" @@ -1821,6 +2399,15 @@ dependencies = [ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "resolv-conf" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ring" version = "0.13.5" @@ -2059,6 +2646,22 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_urlencoded" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "sha2" version = "0.8.0" @@ -2079,6 +2682,15 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "simplelog" version = "0.7.4" @@ -2107,6 +2719,17 @@ name = "smallvec" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "socket2" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "state" version = "0.4.1" @@ -2237,6 +2860,14 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "threadpool" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tiff" version = "0.3.1" @@ -2276,6 +2907,26 @@ dependencies = [ "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-buf" version = "0.1.1" @@ -2381,6 +3032,19 @@ dependencies = [ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-util" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.4.10" @@ -2402,6 +3066,43 @@ name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "trust-dns-proto" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "try-lock" version = "0.2.2" @@ -2457,6 +3158,11 @@ dependencies = [ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.7" @@ -2563,6 +3269,11 @@ name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "widestring" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.2.8" @@ -2608,6 +3319,14 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winutil" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wrapped-vec" version = "0.2.1" @@ -2642,15 +3361,32 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" +"checksum actix-connect 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2b61480a8d30c94d5c883d79ef026b02ad6809931b0a4bb703f9545cd8c986" +"checksum actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" +"checksum actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" +"checksum actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" +"checksum actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6a0a55507046441a496b2f0d26a84a65e67c8cafffe279072412f624b5fb6d" +"checksum actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51d3455eaac03ca3e49d7b822eb35c884b861f715627254ccbe4309d08f1841a" +"checksum actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9fba4171f1952aa15f3cf410facac388d18110b1e8754f84a407ab7f9d5ac7ee" +"checksum actix-testing 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48494745b72d0ea8ff0cf874aaf9b622a3ee03d7081ee0c04edea4f26d32c911" +"checksum actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4082192601de5f303013709ff84d81ca6a1bc4af7fb24f367a500a23c6e84e" +"checksum actix-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8" +"checksum actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" +"checksum actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635" +"checksum actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de0878b30e62623770a4713a6338329fd0119703bafc211d3e4144f4d4a7bdd5" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "890eeb3dc52632a4b762e3ea6ac37475a35577f22fce09bb6e758c2aaf38a229" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" +"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" @@ -2660,9 +3396,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +"checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +"checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum bytestring 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b24c107a4432e408d2caa58d3f5e763b219236221406ea58a4076b62343a039d" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" @@ -2673,6 +3413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cookie 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99be24cfcf40d56ed37fd11c2123be833959bbc5bddecb46e1c2e442e15fa3e0" "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" "checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" +"checksum copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" @@ -2689,6 +3430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" "checksum derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4" "checksum derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37" +"checksum derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" "checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" "checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" "checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" @@ -2708,6 +3450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" +"checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -2725,17 +3468,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" +"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" +"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" +"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" +"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" +"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" +"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" +"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" +"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" "checksum gif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" +"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +"checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" @@ -2751,6 +3508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jpeg-decoder 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -2761,9 +3519,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lewton 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8d542c1a317036c45c2aa1cf10cc9d403ca91eb2d333ef1a4917e5cb10628bd0" "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5b95e89c330291768dc840238db7f9e204fd208511ab6319b56193a7f2ae25" +"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" @@ -2778,6 +3538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mp3-duration 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7cc3eebd1d49a86505733254d1dfd53fbefe4ab65d86afd6f84d3245cd604f" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" @@ -2798,19 +3559,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" +"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" "checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25" "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" +"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" +"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" +"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum png 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "247cb804bd7fc86d0c2b153d1374265e67945875720136ca8fe451f11c6aed52" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" +"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" @@ -2840,6 +3610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" +"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" "checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" "checksum rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7" "checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4" @@ -2866,12 +3637,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" +"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" +"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "05a3e303ace6adb0a60a9e9e2fbc6a33e1749d1e43587e2125f7efa9c5e107c5" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" +"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" @@ -2887,9 +3662,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef" "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" +"checksum tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa2fdcfa937b20cb3c822a635ceecd5fc1a27a6a474527e5516aa24b8c8820a" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" @@ -2899,9 +3676,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" "checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" +"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +"checksum trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" +"checksum trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" @@ -2910,6 +3690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" +"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" @@ -2926,6 +3707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -2933,6 +3715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum wrapped-vec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "06c29bb4abe93d1c8ef79b60f270d0efcaa6c5c97aaaaaaa0d477ea72f5f9e45" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/Cargo.toml b/Cargo.toml index 38132db..8d02554 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,15 @@ authors = ["Antoine Gersant "] edition = "2018" [features] -default = ["service-rocket"] +default = ["service-actix"] ui = [] profile-index = ["flame", "flamer"] -service-actix = [] +service-actix = ["actix-rt", "actix-web"] service-rocket = ["rocket", "rocket_contrib"] [dependencies] +actix-web = { version = "2.0", optional = true } +actix-rt = { version = "1.0", optional = true } anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" diff --git a/src/main.rs b/src/main.rs index 55da3e9..9689ec2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -220,7 +220,7 @@ fn main() -> Result<()> { .parse() .with_context(|| "Invalid port number")?; - let server = service::server::get_server( + service::server::run( port, Some(auth_secret.as_slice()), &api_url, @@ -231,9 +231,6 @@ fn main() -> Result<()> { db.clone(), command_sender, )?; - std::thread::spawn(move || { - server.launch(); - }); // Start DDNS updates let db_ddns = db.clone(); diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs new file mode 100644 index 0000000..6f99944 --- /dev/null +++ b/src/service/actix/mod.rs @@ -0,0 +1,4 @@ +pub mod server; + +#[cfg(test)] +mod tests; diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs new file mode 100644 index 0000000..dc393b6 --- /dev/null +++ b/src/service/actix/server.rs @@ -0,0 +1,32 @@ +use actix_web::{web, App, HttpResponse, HttpServer, Responder}; +use anyhow::*; +use std::path::PathBuf; +use std::sync::Arc; + +use crate::db::DB; +use crate::index::CommandSender; + +async fn index() -> impl Responder { + HttpResponse::Ok().body("hello world!") +} + +#[actix_rt::main] +pub async fn run( + port: u16, + auth_secret: Option<&[u8]>, + api_url: &str, + web_url: &str, + web_dir_path: &PathBuf, + swagger_url: &str, + swagger_dir_path: &PathBuf, + db: Arc, + command_sender: Arc, +) -> Result<()> { + let app = App::new(); + + HttpServer::new(|| App::new().route("/", web::get().to(index))) + .bind(format!("127.0.0.1:{}", port))? + .run(); + + Ok(()) +} diff --git a/src/service/actix/tests/api.rs b/src/service/actix/tests/api.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/service/actix/tests/mod.rs b/src/service/actix/tests/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/service/actix/tests/mod.rs @@ -0,0 +1 @@ + diff --git a/src/service/actix/tests/swagger.rs b/src/service/actix/tests/swagger.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/service/actix/tests/web.rs b/src/service/actix/tests/web.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/service/mod.rs b/src/service/mod.rs index 6df3dba..dde4ec6 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,4 +1,9 @@ -mod rocket; +#[cfg(feature = "service-actix")] +mod actix; +#[cfg(feature = "service-actix")] +pub use self::actix::*; +#[cfg(feature = "service-rocket")] +mod rocket; #[cfg(feature = "service-rocket")] pub use self::rocket::*; diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index 771b5f1..0a07c73 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -47,3 +47,31 @@ pub fn get_server( StaticFiles::from(web_dir_path).rank(web_routes_rank), )) } + +pub fn run( + port: u16, + auth_secret: Option<&[u8]>, + api_url: &str, + web_url: &str, + web_dir_path: &PathBuf, + swagger_url: &str, + swagger_dir_path: &PathBuf, + db: Arc, + command_sender: Arc, +) -> Result<()> { + let server = get_server( + port, + auth_secret, + api_url, + web_url, + web_dir_path, + swagger_url, + swagger_dir_path, + db, + command_sender, + )?; + std::thread::spawn(move || { + server.launch(); + }); + Ok(()) +} From e248f3b983cd2968206ead48fbc2c9a986ca5e91 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Tue, 14 Jan 2020 01:33:14 -0800 Subject: [PATCH 04/32] Serve web and swagger static files --- Cargo.lock | 63 ++++++++++++++++++++++++++++++ Cargo.toml | 4 +- src/main.rs | 10 ++--- src/service/actix/mod.rs | 16 ++++++++ src/service/actix/server.rs | 34 +++++++++------- src/service/actix/tests/mod.rs | 20 ++++++++++ src/service/actix/tests/swagger.rs | 21 ++++++++++ src/service/actix/tests/web.rs | 12 ++++++ src/service/rocket/server.rs | 20 +++++----- 9 files changed, 169 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76cadb3..bf17dae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,25 @@ dependencies = [ "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "actix-files" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "v_htmlescape 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "actix-http" version = "1.0.1" @@ -1720,6 +1739,15 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "notify" version = "4.0.14" @@ -2017,6 +2045,8 @@ dependencies = [ name = "polaris" version = "0.11.0" dependencies = [ + "actix-files 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3229,6 +3259,34 @@ name = "uuid" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "v_escape" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "v_escape_derive 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "v_escape_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "v_htmlescape" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "v_escape 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vcpkg" version = "0.2.8" @@ -3363,6 +3421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" "checksum actix-connect 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2b61480a8d30c94d5c883d79ef026b02ad6809931b0a4bb703f9545cd8c986" +"checksum actix-files 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "301482841d3d74483a446ead63cb7d362e187d2c8b603f13d91995621ea53c46" "checksum actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" "checksum actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" "checksum actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" @@ -3543,6 +3602,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum mp3-duration 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7cc3eebd1d49a86505733254d1dfd53fbefe4ab65d86afd6f84d3245cd604f" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b" "checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" "checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" @@ -3701,6 +3761,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +"checksum v_escape 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6" +"checksum v_escape_derive 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae" +"checksum v_htmlescape 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" diff --git a/Cargo.toml b/Cargo.toml index 8d02554..0d36348 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,12 @@ edition = "2018" default = ["service-actix"] ui = [] profile-index = ["flame", "flamer"] -service-actix = ["actix-rt", "actix-web"] +service-actix = ["actix-files", "actix-http", "actix-rt", "actix-web"] service-rocket = ["rocket", "rocket_contrib"] [dependencies] +actix-files = { version = "0.2", optional = true } +actix-http = { version = "1.0", optional = true } actix-web = { version = "2.0", optional = true } actix-rt = { version = "1.0", optional = true } anyhow = "1.0" diff --git a/src/main.rs b/src/main.rs index 9689ec2..88f1a62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -223,11 +223,11 @@ fn main() -> Result<()> { service::server::run( port, Some(auth_secret.as_slice()), - &api_url, - &web_url, - &web_dir_path, - &swagger_url, - &swagger_dir_path, + api_url, + web_url, + web_dir_path, + swagger_url, + swagger_dir_path, db.clone(), command_sender, )?; diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs index 6f99944..39540f4 100644 --- a/src/service/actix/mod.rs +++ b/src/service/actix/mod.rs @@ -1,4 +1,20 @@ +use actix_files as fs; +use actix_web::web; +use std::path::Path; + pub mod server; #[cfg(test)] mod tests; + +fn configure_app( + cfg: &mut web::ServiceConfig, + web_url: &str, + web_dir_path: &Path, + swagger_url: &str, + swagger_dir_path: &Path, +) { + // TODO logging + cfg.service(fs::Files::new(swagger_url, swagger_dir_path).index_file("index.html")) + .service(fs::Files::new(web_url, web_dir_path).index_file("index.html")); +} diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs index dc393b6..9b82631 100644 --- a/src/service/actix/server.rs +++ b/src/service/actix/server.rs @@ -1,4 +1,4 @@ -use actix_web::{web, App, HttpResponse, HttpServer, Responder}; +use actix_web::{App, HttpServer}; use anyhow::*; use std::path::PathBuf; use std::sync::Arc; @@ -6,27 +6,31 @@ use std::sync::Arc; use crate::db::DB; use crate::index::CommandSender; -async fn index() -> impl Responder { - HttpResponse::Ok().body("hello world!") -} - #[actix_rt::main] pub async fn run( port: u16, auth_secret: Option<&[u8]>, - api_url: &str, - web_url: &str, - web_dir_path: &PathBuf, - swagger_url: &str, - swagger_dir_path: &PathBuf, + api_url: String, + web_url: String, + web_dir_path: PathBuf, + swagger_url: String, + swagger_dir_path: PathBuf, db: Arc, command_sender: Arc, ) -> Result<()> { - let app = App::new(); - - HttpServer::new(|| App::new().route("/", web::get().to(index))) - .bind(format!("127.0.0.1:{}", port))? - .run(); + HttpServer::new(move || { + App::new().configure(|cfg| { + super::configure_app( + cfg, + &web_url, + web_dir_path.as_path(), + &swagger_url, + swagger_dir_path.as_path(), + ) + }) + }) + .bind(format!("127.0.0.1:{}", port))? + .run(); Ok(()) } diff --git a/src/service/actix/tests/mod.rs b/src/service/actix/tests/mod.rs index 8b13789..d3b07a4 100644 --- a/src/service/actix/tests/mod.rs +++ b/src/service/actix/tests/mod.rs @@ -1 +1,21 @@ +use std::path::PathBuf; +mod swagger; +mod web; + +fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig) { + let web_url = "/"; + let web_dir_path = PathBuf::from("web"); + + let swagger_url = "swagger"; + let mut swagger_dir_path = PathBuf::from("docs"); + swagger_dir_path.push("swagger"); + + super::configure_app( + cfg, + web_url, + web_dir_path.as_path(), + swagger_url, + swagger_dir_path.as_path(), + ); +} diff --git a/src/service/actix/tests/swagger.rs b/src/service/actix/tests/swagger.rs index e69de29..f717ae8 100644 --- a/src/service/actix/tests/swagger.rs +++ b/src/service/actix/tests/swagger.rs @@ -0,0 +1,21 @@ +use actix_web::dev::Service; +use actix_web::test::TestRequest; +use actix_web::{test, App}; + +#[actix_rt::test] +async fn test_index() { + let app = App::new().configure(super::configure_test_app); + let mut service = test::init_service(app).await; + let req = TestRequest::get().uri("/swagger").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); +} + +#[actix_rt::test] +async fn test_index_with_trailing_slash() { + let app = App::new().configure(super::configure_test_app); + let mut service = test::init_service(app).await; + let req = TestRequest::get().uri("/swagger/").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); +} diff --git a/src/service/actix/tests/web.rs b/src/service/actix/tests/web.rs index e69de29..898e9d1 100644 --- a/src/service/actix/tests/web.rs +++ b/src/service/actix/tests/web.rs @@ -0,0 +1,12 @@ +use actix_web::dev::Service; +use actix_web::test::TestRequest; +use actix_web::{test, App}; + +#[actix_rt::test] +async fn test_index() { + let app = App::new().configure(super::configure_test_app); + let mut service = test::init_service(app).await; + let req = TestRequest::get().uri("/").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); +} diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index 0a07c73..05dbda7 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -51,22 +51,22 @@ pub fn get_server( pub fn run( port: u16, auth_secret: Option<&[u8]>, - api_url: &str, - web_url: &str, - web_dir_path: &PathBuf, - swagger_url: &str, - swagger_dir_path: &PathBuf, + api_url: String, + web_url: String, + web_dir_path: PathBuf, + swagger_url: String, + swagger_dir_path: PathBuf, db: Arc, command_sender: Arc, ) -> Result<()> { let server = get_server( port, auth_secret, - api_url, - web_url, - web_dir_path, - swagger_url, - swagger_dir_path, + &api_url, + &web_url, + &web_dir_path, + &swagger_url, + &swagger_dir_path, db, command_sender, )?; From 052dc88f140e9888462c57d3c56a011e08185d28 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Tue, 14 Jan 2020 22:40:36 -0800 Subject: [PATCH 05/32] Implemented version endpoint --- src/service/actix/api.rs | 13 +++++++++++++ src/service/actix/mod.rs | 4 +++- src/service/actix/tests/api.rs | 23 +++++++++++++++++++++++ src/service/actix/tests/mod.rs | 1 + src/service/constants.rs | 5 +++++ src/service/dto.rs | 7 +++++++ src/service/mod.rs | 3 +++ src/service/rocket/api.rs | 18 ++++-------------- src/service/rocket/api_tests.rs | 5 +++-- 9 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 src/service/actix/api.rs create mode 100644 src/service/constants.rs create mode 100644 src/service/dto.rs diff --git a/src/service/actix/api.rs b/src/service/actix/api.rs new file mode 100644 index 0000000..34bd807 --- /dev/null +++ b/src/service/actix/api.rs @@ -0,0 +1,13 @@ +use actix_web::{get, HttpResponse}; + +use crate::service::constants::*; +use crate::service::dto; + +#[get("/version")] +pub async fn get_version() -> Result { + let current_version = dto::Version { + major: CURRENT_MAJOR_VERSION, + minor: CURRENT_MINOR_VERSION, + }; + Ok(HttpResponse::Ok().json(current_version)) +} diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs index 39540f4..f8e7365 100644 --- a/src/service/actix/mod.rs +++ b/src/service/actix/mod.rs @@ -4,6 +4,7 @@ use std::path::Path; pub mod server; +mod api; #[cfg(test)] mod tests; @@ -15,6 +16,7 @@ fn configure_app( swagger_dir_path: &Path, ) { // TODO logging - cfg.service(fs::Files::new(swagger_url, swagger_dir_path).index_file("index.html")) + cfg.service(web::scope("/api").service(api::get_version)) + .service(fs::Files::new(swagger_url, swagger_dir_path).index_file("index.html")) .service(fs::Files::new(web_url, web_dir_path).index_file("index.html")); } diff --git a/src/service/actix/tests/api.rs b/src/service/actix/tests/api.rs index e69de29..6564f1f 100644 --- a/src/service/actix/tests/api.rs +++ b/src/service/actix/tests/api.rs @@ -0,0 +1,23 @@ +use actix_web::body::Body::Bytes; +use actix_web::dev::*; +use actix_web::test::TestRequest; +use actix_web::{test, App}; + +use crate::service::dto; + +#[actix_rt::test] +async fn test_version() { + let app = App::new().configure(super::configure_test_app); + let mut service = test::init_service(app).await; + let req = TestRequest::get().uri("/api/version").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); + + let body = match resp.response().body().as_ref() { + Some(Bytes(bytes)) => bytes, + _ => panic!("Response error"), + }; + + let response_json: dto::Version = serde_json::from_slice(body).unwrap(); + assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); +} diff --git a/src/service/actix/tests/mod.rs b/src/service/actix/tests/mod.rs index d3b07a4..ea62291 100644 --- a/src/service/actix/tests/mod.rs +++ b/src/service/actix/tests/mod.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +mod api; mod swagger; mod web; diff --git a/src/service/constants.rs b/src/service/constants.rs new file mode 100644 index 0000000..e222d58 --- /dev/null +++ b/src/service/constants.rs @@ -0,0 +1,5 @@ +pub const CURRENT_MAJOR_VERSION: i32 = 4; +pub const CURRENT_MINOR_VERSION: i32 = 0; +pub const COOKIE_SESSION: &str = "session"; +pub const COOKIE_USERNAME: &str = "username"; +pub const COOKIE_ADMIN: &str = "admin"; diff --git a/src/service/dto.rs b/src/service/dto.rs new file mode 100644 index 0000000..51973f1 --- /dev/null +++ b/src/service/dto.rs @@ -0,0 +1,7 @@ +use serde::{Deserialize, Serialize}; + +#[derive(PartialEq, Debug, Serialize, Deserialize)] +pub struct Version { + pub major: i32, + pub minor: i32, +} diff --git a/src/service/mod.rs b/src/service/mod.rs index dde4ec6..fe22d69 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,3 +1,6 @@ +mod constants; +mod dto; + #[cfg(feature = "service-actix")] mod actix; #[cfg(feature = "service-actix")] diff --git a/src/service/rocket/api.rs b/src/service/rocket/api.rs index 64c7b3d..538f02f 100644 --- a/src/service/rocket/api.rs +++ b/src/service/rocket/api.rs @@ -20,17 +20,13 @@ use crate::db::DB; use crate::index; use crate::lastfm; use crate::playlist; +use crate::service::constants::*; +use crate::service::dto; use crate::thumbnails; use crate::user; use crate::utils; use crate::vfs::VFSSource; -const CURRENT_MAJOR_VERSION: i32 = 4; -const CURRENT_MINOR_VERSION: i32 = 0; -const COOKIE_SESSION: &str = "session"; -const COOKIE_USERNAME: &str = "username"; -const COOKIE_ADMIN: &str = "admin"; - pub fn get_routes() -> Vec { routes![ version, @@ -207,15 +203,9 @@ impl From for PathBuf { } } -#[derive(PartialEq, Debug, Serialize, Deserialize)] -pub struct Version { - pub major: i32, - pub minor: i32, -} - #[get("/version")] -fn version() -> Json { - let current_version = Version { +fn version() -> Json { + let current_version = dto::Version { major: CURRENT_MAJOR_VERSION, minor: CURRENT_MINOR_VERSION, }; diff --git a/src/service/rocket/api_tests.rs b/src/service/rocket/api_tests.rs index f792563..bd3dcac 100644 --- a/src/service/rocket/api_tests.rs +++ b/src/service/rocket/api_tests.rs @@ -8,6 +8,7 @@ use super::api; use crate::config; use crate::ddns; use crate::index; +use crate::service::dto; use crate::vfs; use super::test::get_test_environment; @@ -57,8 +58,8 @@ fn version() { assert_eq!(response.status(), Status::Ok); let response_body = response.body_string().unwrap(); - let response_json: api::Version = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json, api::Version { major: 4, minor: 0 }); + let response_json: dto::Version = serde_json::from_str(&response_body).unwrap(); + assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); } #[test] From 9e48dc408ecfe585ce61d2ed76f8d999b1413ca7 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Wed, 15 Jan 2020 21:58:37 -0800 Subject: [PATCH 06/32] DB interactions for actix version --- Cargo.lock | 21 +++++ Cargo.toml | 2 +- src/config.rs | 117 ++++++++++------------- src/db/mod.rs | 55 ++++------- src/ddns.rs | 14 +-- src/index.rs | 145 +++++++++++------------------ src/lastfm.rs | 28 ++---- src/main.rs | 14 ++- src/playlist.rs | 68 ++++++-------- src/service/actix/api.rs | 47 +++++++++- src/service/actix/mod.rs | 11 ++- src/service/actix/server.rs | 3 +- src/service/actix/tests/api.rs | 105 +++++++++++++++++++-- src/service/actix/tests/mod.rs | 14 ++- src/service/actix/tests/swagger.rs | 11 ++- src/service/actix/tests/web.rs | 4 +- src/service/dto.rs | 5 + src/service/error.rs | 15 +++ src/service/mod.rs | 1 + src/service/rocket/api.rs | 112 +++++++--------------- src/service/rocket/api_tests.rs | 8 +- src/service/rocket/server.rs | 4 +- src/service/rocket/test.rs | 7 +- src/user.rs | 71 +++++--------- src/vfs.rs | 4 +- 25 files changed, 449 insertions(+), 437 deletions(-) create mode 100644 src/service/error.rs diff --git a/Cargo.lock b/Cargo.lock index bf17dae..88b64d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -774,6 +774,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2160,6 +2161,16 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "r2d2" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scheduled-thread-pool 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.23" @@ -2590,6 +2601,14 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scoped_threadpool" version = "0.1.9" @@ -3644,6 +3663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1497e40855348e4a8a40767d8e55174bce1e445a3ac9254ad44ad468ee0485af" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" @@ -3686,6 +3706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +"checksum scheduled-thread-pool 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f5de7bc31f28f8e6c28df5e1bf3d10610f5fdc14cc95f272853512c70a2bd779" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sd-notify 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aef40838bbb143707f8309b1e92e6ba3225287592968ba6f6e3b6de4a9816486" diff --git a/Cargo.toml b/Cargo.toml index 0d36348..304f6e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" base64 = "0.11.0" -diesel = { version = "1.4", features = ["sqlite"] } +diesel = { version = "1.4", features = ["sqlite", "r2d2"] } diesel_migrations = { version = "1.4", features = ["sqlite"] } flame = { version = "0.2.2", optional = true } flamer = { version = "0.4", optional = true } diff --git a/src/config.rs b/src/config.rs index de141b5..6af5520 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,8 +10,7 @@ use std::io::Read; use std::path; use toml; -use crate::db::ConnectionSource; -use crate::db::{ddns_config, misc_settings, mount_points, users}; +use crate::db::{ddns_config, misc_settings, mount_points, users, DB}; use crate::ddns::DDNSConfig; use crate::user::*; use crate::vfs::MountPoint; @@ -73,14 +72,11 @@ pub fn parse_toml_file(path: &path::Path) -> Result { Ok(config) } -pub fn read(db: &T) -> Result -where - T: ConnectionSource, -{ +pub fn read(db: &DB) -> Result { use self::ddns_config::dsl::*; use self::misc_settings::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; let mut config = Config { album_art_pattern: None, @@ -97,7 +93,7 @@ where index_sleep_duration_seconds, prefix_url, )) - .get_result(connection.deref())?; + .get_result(&connection)?; config.album_art_pattern = Some(art_pattern); config.reindex_every_n_seconds = Some(sleep_duration); @@ -108,13 +104,13 @@ where use self::mount_points::dsl::*; mount_dirs = mount_points .select((source, name)) - .get_results(connection.deref())?; + .get_results(&connection)?; config.mount_dirs = Some(mount_dirs); } let found_users: Vec<(String, i32)> = users::table .select((users::columns::name, users::columns::admin)) - .get_results(connection.deref())?; + .get_results(&connection)?; config.users = Some( found_users .into_iter() @@ -128,46 +124,39 @@ where let ydns = ddns_config .select((host, username, password)) - .get_result(connection.deref())?; + .get_result(&connection)?; config.ydns = Some(ydns); Ok(config) } #[cfg(test)] -pub fn reset(db: &T) -> Result<()> -where - T: ConnectionSource, -{ +pub fn reset(db: &DB) -> Result<()> { use self::ddns_config::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; - diesel::delete(mount_points::table).execute(connection.deref())?; - diesel::delete(users::table).execute(connection.deref())?; + diesel::delete(mount_points::table).execute(&connection)?; + diesel::delete(users::table).execute(&connection)?; diesel::update(ddns_config) .set((host.eq(""), username.eq(""), password.eq(""))) - .execute(connection.deref())?; + .execute(&connection)?; Ok(()) } -pub fn amend(db: &T, new_config: &Config) -> Result<()> -where - T: ConnectionSource, -{ - let connection = db.get_connection(); +pub fn amend(db: &DB, new_config: &Config) -> Result<()> { + let connection = db.connect()?; if let Some(ref mount_dirs) = new_config.mount_dirs { - diesel::delete(mount_points::table).execute(connection.deref())?; + diesel::delete(mount_points::table).execute(&connection)?; diesel::insert_into(mount_points::table) .values(mount_dirs) - .execute(connection.deref())?; + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 } if let Some(ref config_users) = new_config.users { - let old_usernames: Vec = users::table - .select(users::name) - .get_results(connection.deref())?; + let old_usernames: Vec = + users::table.select(users::name).get_results(&connection)?; // Delete users that are not in new list let delete_usernames: Vec = old_usernames @@ -176,7 +165,7 @@ where .filter(|old_name| config_users.iter().find(|u| &u.name == old_name).is_none()) .collect::<_>(); diesel::delete(users::table.filter(users::name.eq_any(&delete_usernames))) - .execute(connection.deref())?; + .execute(&connection)?; // Insert new users let insert_users: Vec<&ConfigUser> = config_users @@ -194,7 +183,7 @@ where let new_user = User::new(&config_user.name, &config_user.password)?; diesel::insert_into(users::table) .values(&new_user) - .execute(connection.deref())?; + .execute(&connection)?; } // Update users @@ -204,26 +193,26 @@ where let hash = hash_password(&user.password)?; diesel::update(users::table.filter(users::name.eq(&user.name))) .set(users::password_hash.eq(hash)) - .execute(connection.deref())?; + .execute(&connection)?; } // Update admin rights diesel::update(users::table.filter(users::name.eq(&user.name))) .set(users::admin.eq(user.admin as i32)) - .execute(connection.deref())?; + .execute(&connection)?; } } if let Some(sleep_duration) = new_config.reindex_every_n_seconds { diesel::update(misc_settings::table) .set(misc_settings::index_sleep_duration_seconds.eq(sleep_duration as i32)) - .execute(connection.deref())?; + .execute(&connection)?; } if let Some(ref album_art_pattern) = new_config.album_art_pattern { diesel::update(misc_settings::table) .set(misc_settings::index_album_art_pattern.eq(album_art_pattern)) - .execute(connection.deref())?; + .execute(&connection)?; } if let Some(ref ydns) = new_config.ydns { @@ -234,28 +223,25 @@ where username.eq(ydns.username.clone()), password.eq(ydns.password.clone()), )) - .execute(connection.deref())?; + .execute(&connection)?; } if let Some(ref prefix_url) = new_config.prefix_url { diesel::update(misc_settings::table) .set(misc_settings::prefix_url.eq(prefix_url)) - .execute(connection.deref())?; + .execute(&connection)?; } Ok(()) } -pub fn read_preferences(db: &T, username: &str) -> Result -where - T: ConnectionSource, -{ +pub fn read_preferences(db: &DB, username: &str) -> Result { use self::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; let (theme_base, theme_accent, read_lastfm_username) = users .select((web_theme_base, web_theme_accent, lastfm_username)) .filter(name.eq(username)) - .get_result(connection.deref())?; + .get_result(&connection)?; Ok(Preferences { web_theme_base: theme_base, web_theme_accent: theme_accent, @@ -263,33 +249,24 @@ where }) } -pub fn write_preferences(db: &T, username: &str, preferences: &Preferences) -> Result<()> -where - T: ConnectionSource, -{ +pub fn write_preferences(db: &DB, username: &str, preferences: &Preferences) -> Result<()> { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; diesel::update(users.filter(name.eq(username))) .set(( web_theme_base.eq(&preferences.web_theme_base), web_theme_accent.eq(&preferences.web_theme_accent), )) - .execute(connection.deref())?; + .execute(&connection)?; Ok(()) } -pub fn get_auth_secret(db: &T) -> Result> -where - T: ConnectionSource, -{ +pub fn get_auth_secret(db: &DB) -> Result> { use self::misc_settings::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; - match misc_settings - .select(auth_secret) - .get_result(connection.deref()) - { + match misc_settings.select(auth_secret).get_result(&connection) { Err(diesel::result::Error::NotFound) => bail!("Cannot find authentication secret"), Ok(secret) => Ok(secret), Err(e) => Err(e.into()), @@ -391,11 +368,11 @@ fn test_amend_preserve_password_hashes() { amend(&db, &initial_config).unwrap(); { - let connection = db.get_connection(); + let connection = db.connect().unwrap(); initial_hash = users .select(password_hash) .filter(name.eq("Teddy🐻")) - .get_result(connection.deref()) + .get_result(&connection) .unwrap(); } @@ -421,11 +398,11 @@ fn test_amend_preserve_password_hashes() { amend(&db, &new_config).unwrap(); { - let connection = db.get_connection(); + let connection = db.connect().unwrap(); new_hash = users .select(password_hash) .filter(name.eq("Teddy🐻")) - .get_result(connection.deref()) + .get_result(&connection) .unwrap(); } @@ -453,8 +430,8 @@ fn test_amend_ignore_blank_users() { }; amend(&db, &config).unwrap(); - let connection = db.get_connection(); - let user_count: i64 = users.count().get_result(connection.deref()).unwrap(); + let connection = db.connect().unwrap(); + let user_count: i64 = users.count().get_result(&connection).unwrap(); assert_eq!(user_count, 0); } @@ -473,8 +450,8 @@ fn test_amend_ignore_blank_users() { }; amend(&db, &config).unwrap(); - let connection = db.get_connection(); - let user_count: i64 = users.count().get_result(connection.deref()).unwrap(); + let connection = db.connect().unwrap(); + let user_count: i64 = users.count().get_result(&connection).unwrap(); assert_eq!(user_count, 0); } } @@ -500,8 +477,8 @@ fn test_toggle_admin() { amend(&db, &initial_config).unwrap(); { - let connection = db.get_connection(); - let is_admin: i32 = users.select(admin).get_result(connection.deref()).unwrap(); + let connection = db.connect().unwrap(); + let is_admin: i32 = users.select(admin).get_result(&connection).unwrap(); assert_eq!(is_admin, 1); } @@ -520,8 +497,8 @@ fn test_toggle_admin() { amend(&db, &new_config).unwrap(); { - let connection = db.get_connection(); - let is_admin: i32 = users.select(admin).get_result(connection.deref()).unwrap(); + let connection = db.connect().unwrap(); + let is_admin: i32 = users.select(admin).get_result(&connection).unwrap(); assert_eq!(is_admin, 0); } } diff --git a/src/db/mod.rs b/src/db/mod.rs index 17e5ea3..6f923af 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,11 +1,9 @@ use anyhow::*; -use core::ops::Deref; -use diesel::prelude::*; +use diesel::r2d2::{self, ConnectionManager, PooledConnection}; use diesel::sqlite::SqliteConnection; use diesel_migrations; use log::info; use std::path::Path; -use std::sync::{Arc, Mutex, MutexGuard}; mod schema; @@ -15,44 +13,34 @@ pub use self::schema::*; const DB_MIGRATIONS_PATH: &str = "migrations"; embed_migrations!("migrations"); -pub trait ConnectionSource { - fn get_connection(&self) -> MutexGuard<'_, SqliteConnection>; - fn get_connection_mutex(&self) -> Arc>; -} - +#[derive(Clone)] pub struct DB { - connection: Arc>, + pool: r2d2::Pool>, } impl DB { pub fn new(path: &Path) -> Result { info!("Database file path: {}", path.to_string_lossy()); - let connection = Arc::new(Mutex::new(SqliteConnection::establish( - &path.to_string_lossy(), - )?)); - let db = DB { - connection: connection.clone(), - }; - db.init()?; + let manager = ConnectionManager::::new(path.to_string_lossy()); + let pool = r2d2::Pool::builder() + .build(manager) + .expect("Failed to create pool."); // TODO handle error + + let db = DB { pool: pool }; + db.migrate_up()?; Ok(db) } - fn init(&self) -> Result<()> { - { - let connection = self.connection.lock().unwrap(); - connection.execute("PRAGMA synchronous = NORMAL")?; - } - self.migrate_up()?; - Ok(()) + pub fn connect(&self) -> Result>> { + self.pool.get().map_err(Error::new) } #[allow(dead_code)] fn migrate_down(&self) -> Result<()> { - let connection = self.connection.lock().unwrap(); - let connection = connection.deref(); + let connection = self.connect().unwrap(); loop { match diesel_migrations::revert_latest_migration_in_directory( - connection, + &connection, Path::new(DB_MIGRATIONS_PATH), ) { Ok(_) => (), @@ -66,23 +54,12 @@ impl DB { } fn migrate_up(&self) -> Result<()> { - let connection = self.connection.lock().unwrap(); - let connection = connection.deref(); - embedded_migrations::run(connection)?; + let connection = self.connect().unwrap(); + embedded_migrations::run(&connection)?; Ok(()) } } -impl ConnectionSource for DB { - fn get_connection(&self) -> MutexGuard<'_, SqliteConnection> { - self.connection.lock().unwrap() - } - - fn get_connection_mutex(&self) -> Arc> { - self.connection.clone() - } -} - #[cfg(test)] pub fn get_test_db(name: &str) -> DB { use crate::config; diff --git a/src/ddns.rs b/src/ddns.rs index c5f5e4e..8eda3bd 100644 --- a/src/ddns.rs +++ b/src/ddns.rs @@ -8,7 +8,7 @@ use std::thread; use std::time; use crate::db::ddns_config; -use crate::db::{ConnectionSource, DB}; +use crate::db::DB; #[derive(Clone, Debug, Deserialize, Insertable, PartialEq, Queryable, Serialize)] #[table_name = "ddns_config"] @@ -25,7 +25,7 @@ pub trait DDNSConfigSource { impl DDNSConfigSource for DB { fn get_ddns_config(&self) -> Result { use self::ddns_config::dsl::*; - let connection = self.get_connection(); + let connection = self.connect()?; Ok(ddns_config .select((host, username, password)) .get_result(connection.deref())?) @@ -34,10 +34,7 @@ impl DDNSConfigSource for DB { const DDNS_UPDATE_URL: &str = "https://ydns.io/api/v1/update/"; -fn update_my_ip(config_source: &T) -> Result<()> -where - T: DDNSConfigSource, -{ +fn update_my_ip(config_source: &DB) -> Result<()> { let config = config_source.get_ddns_config()?; if config.host.is_empty() || config.username.is_empty() { info!("Skipping DDNS update because credentials are missing"); @@ -59,10 +56,7 @@ where Ok(()) } -pub fn run(config_source: &T) -where - T: DDNSConfigSource, -{ +pub fn run(config_source: &DB) { loop { if let Err(e) = update_my_ip(config_source) { error!("Dynamic DNS update error: {:?}", e); diff --git a/src/index.rs b/src/index.rs index d41cc98..70b80a6 100644 --- a/src/index.rs +++ b/src/index.rs @@ -4,7 +4,6 @@ use diesel; use diesel::dsl::sql; use diesel::prelude::*; use diesel::sql_types; -use diesel::sqlite::SqliteConnection; #[cfg(feature = "profile-index")] use flame; use log::{error, info}; @@ -22,8 +21,7 @@ use std::time; use crate::config::MiscSettings; #[cfg(test)] use crate::db; -use crate::db::{directories, misc_settings, songs}; -use crate::db::{ConnectionSource, DB}; +use crate::db::{directories, misc_settings, songs, DB}; use crate::metadata; use crate::vfs::{VFSSource, VFS}; @@ -80,16 +78,14 @@ impl CommandSender { } } -pub fn init(db: Arc) -> Arc { +pub fn init(db: DB) -> Arc { let (index_sender, index_receiver) = channel(); let command_sender = Arc::new(CommandSender::new(index_sender)); let command_receiver = CommandReceiver::new(index_receiver); // Start update loop - let db_ref = db.clone(); std::thread::spawn(move || { - let db = db_ref.deref(); - update_loop(db, &command_receiver); + update_loop(&db, &command_receiver); }); command_sender @@ -162,19 +158,16 @@ struct NewDirectory { date_added: i32, } -struct IndexBuilder<'conn> { +struct IndexBuilder { new_songs: Vec, new_directories: Vec, - connection: &'conn Mutex, + db: DB, album_art_pattern: Regex, } -impl<'conn> IndexBuilder<'conn> { +impl IndexBuilder { #[cfg_attr(feature = "profile-index", flame)] - fn new( - connection: &Mutex, - album_art_pattern: Regex, - ) -> Result> { + fn new(db: DB, album_art_pattern: Regex) -> Result { let mut new_songs = Vec::new(); let mut new_directories = Vec::new(); new_songs.reserve_exact(INDEX_BUILDING_INSERT_BUFFER_SIZE); @@ -182,19 +175,18 @@ impl<'conn> IndexBuilder<'conn> { Ok(IndexBuilder { new_songs, new_directories, - connection, + db, album_art_pattern, }) } #[cfg_attr(feature = "profile-index", flame)] fn flush_songs(&mut self) -> Result<()> { - let connection = self.connection.lock().unwrap(); - let connection = connection.deref(); + let connection = self.db.connect()?; connection.transaction::<_, anyhow::Error, _>(|| { diesel::insert_into(songs::table) .values(&self.new_songs) - .execute(connection)?; + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 Ok(()) })?; self.new_songs.clear(); @@ -203,12 +195,11 @@ impl<'conn> IndexBuilder<'conn> { #[cfg_attr(feature = "profile-index", flame)] fn flush_directories(&mut self) -> Result<()> { - let connection = self.connection.lock().unwrap(); - let connection = connection.deref(); + let connection = self.db.connect()?; connection.transaction::<_, anyhow::Error, _>(|| { diesel::insert_into(directories::table) .values(&self.new_directories) - .execute(connection)?; + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 Ok(()) })?; self.new_directories.clear(); @@ -364,17 +355,14 @@ impl<'conn> IndexBuilder<'conn> { } #[cfg_attr(feature = "profile-index", flame)] -fn clean(db: &T) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +fn clean(db: &DB) -> Result<()> { let vfs = db.get_vfs()?; { let all_songs: Vec; { - let connection = db.get_connection(); - all_songs = songs::table.select(songs::path).load(connection.deref())?; + let connection = db.connect()?; + all_songs = songs::table.select(songs::path).load(&connection)?; } let missing_songs = all_songs @@ -386,7 +374,7 @@ where .collect::>(); { - let connection = db.get_connection(); + let connection = db.connect()?; for chunk in missing_songs[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) { diesel::delete(songs::table.filter(songs::path.eq_any(chunk))) .execute(connection.deref())?; @@ -397,7 +385,7 @@ where { let all_directories: Vec; { - let connection = db.get_connection(); + let connection = db.connect()?; all_directories = directories::table .select(directories::path) .load(connection.deref())?; @@ -412,7 +400,7 @@ where .collect::>(); { - let connection = db.get_connection(); + let connection = db.connect()?; for chunk in missing_directories[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) { diesel::delete(directories::table.filter(directories::path.eq_any(chunk))) .execute(connection.deref())?; @@ -424,22 +412,18 @@ where } #[cfg_attr(feature = "profile-index", flame)] -fn populate(db: &T) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +fn populate(db: &DB) -> Result<()> { let vfs = db.get_vfs()?; let mount_points = vfs.get_mount_points(); let album_art_pattern; { - let connection = db.get_connection(); - let settings: MiscSettings = misc_settings::table.get_result(connection.deref())?; + let connection = db.connect()?; + let settings: MiscSettings = misc_settings::table.get_result(&connection)?; album_art_pattern = Regex::new(&settings.index_album_art_pattern)?; } - let connection_mutex = db.get_connection_mutex(); - let mut builder = IndexBuilder::new(connection_mutex.deref(), album_art_pattern)?; + let mut builder = IndexBuilder::new(db.clone(), album_art_pattern)?; for target in mount_points.values() { builder.populate_directory(None, target.as_path())?; } @@ -448,10 +432,7 @@ where Ok(()) } -pub fn update(db: &T) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn update(db: &DB) -> Result<()> { let start = time::Instant::now(); info!("Beginning library index update"); clean(db)?; @@ -465,10 +446,7 @@ where Ok(()) } -fn update_loop(db: &T, command_buffer: &CommandReceiver) -where - T: ConnectionSource + VFSSource, -{ +fn update_loop(db: &DB, command_buffer: &CommandReceiver) { loop { // Wait for a command if command_buffer.receiver.recv().is_err() { @@ -492,10 +470,7 @@ where } } -pub fn self_trigger(db: &T, command_buffer: &Arc) -where - T: ConnectionSource, -{ +pub fn self_trigger(db: &DB, command_buffer: &Arc) { loop { { let command_buffer = command_buffer.deref(); @@ -504,19 +479,17 @@ where return; } } - let sleep_duration; - { - let connection = db.get_connection(); - let settings: Result = misc_settings::table - .get_result(connection.deref()) - .map_err(|e| e.into()); - if let Err(ref e) = settings { - error!("Could not retrieve index sleep duration: {}", e); - } - sleep_duration = settings - .map(|s| s.index_sleep_duration_seconds) - .unwrap_or(1800); - } + let sleep_duration = { + let connection = db.connect(); + connection + .and_then(|c| { + misc_settings::table + .get_result(&c) + .map_err(|e| Error::new(e)) + }) + .map(|s: MiscSettings| s.index_sleep_duration_seconds) + .unwrap_or(1800) // TODO log error + }; thread::sleep(time::Duration::from_secs(sleep_duration as u64)); } } @@ -551,14 +524,13 @@ fn virtualize_directory(vfs: &VFS, mut directory: Directory) -> Option(db: &T, virtual_path: P) -> Result> +pub fn browse

(db: &DB, virtual_path: P) -> Result> where - T: ConnectionSource + VFSSource, P: AsRef, { let mut output = Vec::new(); let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; if virtual_path.as_ref().components().count() == 0 { // Browse top-level @@ -596,14 +568,13 @@ where Ok(output) } -pub fn flatten(db: &T, virtual_path: P) -> Result> +pub fn flatten

(db: &DB, virtual_path: P) -> Result> where - T: ConnectionSource + VFSSource, P: AsRef, { use self::songs::dsl::*; let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; let real_songs: Vec = if virtual_path.as_ref().parent() != None { let real_path = vfs.virtual_to_real(virtual_path)?; @@ -622,13 +593,10 @@ where Ok(virtual_songs.collect::>()) } -pub fn get_random_albums(db: &T, count: i64) -> Result> -where - T: ConnectionSource + VFSSource, -{ +pub fn get_random_albums(db: &DB, count: i64) -> Result> { use self::directories::dsl::*; let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; let real_directories = directories .filter(album.is_not_null()) .limit(count) @@ -640,13 +608,10 @@ where Ok(virtual_directories.collect::>()) } -pub fn get_recent_albums(db: &T, count: i64) -> Result> -where - T: ConnectionSource + VFSSource, -{ +pub fn get_recent_albums(db: &DB, count: i64) -> Result> { use self::directories::dsl::*; let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; let real_directories: Vec = directories .filter(album.is_not_null()) .order(date_added.desc()) @@ -658,12 +623,9 @@ where Ok(virtual_directories.collect::>()) } -pub fn search(db: &T, query: &str) -> Result> -where - T: ConnectionSource + VFSSource, -{ +pub fn search(db: &DB, query: &str) -> Result> { let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; let like_test = format!("%{}%", query); let mut output = Vec::new(); @@ -706,12 +668,9 @@ where Ok(output) } -pub fn get_song(db: &T, virtual_path: &Path) -> Result -where - T: ConnectionSource + VFSSource, -{ +pub fn get_song(db: &DB, virtual_path: &Path) -> Result { let vfs = db.get_vfs()?; - let connection = db.get_connection(); + let connection = db.connect()?; let real_path = vfs.virtual_to_real(virtual_path)?; let real_path_string = real_path.as_path().to_string_lossy(); @@ -732,9 +691,9 @@ fn test_populate() { update(&db).unwrap(); update(&db).unwrap(); // Check that subsequent updates don't run into conflicts - let connection = db.get_connection(); - let all_directories: Vec = directories::table.load(connection.deref()).unwrap(); - let all_songs: Vec = songs::table.load(connection.deref()).unwrap(); + let connection = db.connect().unwrap(); + let all_directories: Vec = directories::table.load(&connection).unwrap(); + let all_songs: Vec = songs::table.load(&connection).unwrap(); assert_eq!(all_directories.len(), 5); assert_eq!(all_songs.len(), 12); } @@ -756,7 +715,7 @@ fn test_metadata() { let db = db::get_test_db("metadata.sqlite"); update(&db).unwrap(); - let connection = db.get_connection(); + let connection = db.connect().unwrap(); let songs: Vec = songs::table .filter(songs::title.eq("シャーベット (Sherbet)")) .load(connection.deref()) diff --git a/src/lastfm.rs b/src/lastfm.rs index 843e8a6..5045f80 100644 --- a/src/lastfm.rs +++ b/src/lastfm.rs @@ -3,10 +3,9 @@ use rustfm_scrobble::{Scrobble, Scrobbler}; use serde::Deserialize; use std::path::Path; -use crate::db::ConnectionSource; +use crate::db::DB; use crate::index; use crate::user; -use crate::vfs::VFSSource; const LASTFM_API_KEY: &str = "02b96c939a2b451c31dfd67add1f696e"; const LASTFM_API_SECRET: &str = "0f25a80ceef4b470b5cb97d99d4b3420"; @@ -42,10 +41,7 @@ struct AuthResponse { pub session: AuthResponseSession, } -fn scrobble_from_path(db: &T, track: &Path) -> Result -where - T: ConnectionSource + VFSSource, -{ +fn scrobble_from_path(db: &DB, track: &Path) -> Result { let song = index::get_song(db, track)?; Ok(Scrobble::new( song.artist.unwrap_or_else(|| "".into()), @@ -54,27 +50,18 @@ where )) } -pub fn link(db: &T, username: &str, token: &str) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn link(db: &DB, username: &str, token: &str) -> Result<()> { let mut scrobbler = Scrobbler::new(LASTFM_API_KEY.into(), LASTFM_API_SECRET.into()); let auth_response = scrobbler.authenticate_with_token(token.to_string())?; user::lastfm_link(db, username, &auth_response.name, &auth_response.key) } -pub fn unlink(db: &T, username: &str) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn unlink(db: &DB, username: &str) -> Result<()> { user::lastfm_unlink(db, username) } -pub fn scrobble(db: &T, username: &str, track: &Path) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn scrobble(db: &DB, username: &str, track: &Path) -> Result<()> { let mut scrobbler = Scrobbler::new(LASTFM_API_KEY.into(), LASTFM_API_SECRET.into()); let scrobble = scrobble_from_path(db, track)?; let auth_token = user::get_lastfm_session_key(db, username)?; @@ -83,10 +70,7 @@ where Ok(()) } -pub fn now_playing(db: &T, username: &str, track: &Path) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn now_playing(db: &DB, username: &str, track: &Path) -> Result<()> { let mut scrobbler = Scrobbler::new(LASTFM_API_KEY.into(), LASTFM_API_SECRET.into()); let scrobble = scrobble_from_path(db, track)?; let auth_token = user::get_lastfm_session_key(db, username)?; diff --git a/src/main.rs b/src/main.rs index 88f1a62..ced7af9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,12 +21,10 @@ use std::io::prelude::*; use unix_daemonize::{daemonize_redirect, ChdirMode}; use anyhow::*; -use core::ops::Deref; use getopts::Options; use log::info; use simplelog::{LevelFilter, SimpleLogger, TermLogger, TerminalMode}; use std::path::Path; -use std::sync::Arc; mod config; mod db; @@ -160,7 +158,7 @@ fn main() -> Result<()> { let db_path = db_path .map(|n| Path::new(n.as_str()).to_path_buf()) .unwrap_or(default_db_path); - let db = Arc::new(db::DB::new(&db_path)?); + let db = db::DB::new(&db_path)?; // Parse config info!("Parsing configuration"); @@ -169,10 +167,10 @@ fn main() -> Result<()> { if let Some(path) = config_file_path { let config = config::parse_toml_file(&path)?; info!("Applying configuration"); - config::amend(db.deref(), &config)?; + config::amend(&db, &config)?; } - let config = config::read(db.deref())?; - let auth_secret = config::get_auth_secret(db.deref())?; + let config = config::read(&db)?; + let auth_secret = config::get_auth_secret(&db)?; // Init index info!("Initializing index"); @@ -182,7 +180,7 @@ fn main() -> Result<()> { let db_auto_index = db.clone(); let command_sender_auto_index = command_sender.clone(); std::thread::spawn(move || { - index::self_trigger(db_auto_index.deref(), &command_sender_auto_index); + index::self_trigger(&db_auto_index, &command_sender_auto_index); }); // API mount target @@ -235,7 +233,7 @@ fn main() -> Result<()> { // Start DDNS updates let db_ddns = db.clone(); std::thread::spawn(move || { - ddns::run(db_ddns.deref()); + ddns::run(&db_ddns); }); // Send readiness notification diff --git a/src/playlist.rs b/src/playlist.rs index 5d66843..39dfc77 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -9,7 +9,7 @@ use std::path::Path; #[cfg(test)] use crate::db; -use crate::db::ConnectionSource; +use crate::db::DB; use crate::db::{playlist_songs, playlists, users}; use crate::index::{self, Song}; use crate::vfs::VFSSource; @@ -48,11 +48,8 @@ pub struct NewPlaylistSong { ordering: i32, } -pub fn list_playlists(owner: &str, db: &T) -> Result> -where - T: ConnectionSource + VFSSource, -{ - let connection = db.get_connection(); +pub fn list_playlists(owner: &str, db: &DB) -> Result> { + let connection = db.connect()?; let user: User; { @@ -72,17 +69,14 @@ where } } -pub fn save_playlist(playlist_name: &str, owner: &str, content: &[String], db: &T) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ +pub fn save_playlist(playlist_name: &str, owner: &str, content: &[String], db: &DB) -> Result<()> { let user: User; let new_playlist: NewPlaylist; let playlist: Playlist; let vfs = db.get_vfs()?; { - let connection = db.get_connection(); + let connection = db.connect()?; // Find owner { @@ -90,7 +84,7 @@ where user = users .filter(name.eq(owner)) .select((id,)) - .get_result(connection.deref())?; + .get_result(&connection)?; } // Create playlist @@ -101,14 +95,14 @@ where diesel::insert_into(playlists::table) .values(&new_playlist) - .execute(connection.deref())?; + .execute(&connection)?; { use self::playlists::dsl::*; playlist = playlists .select((id, owner)) .filter(name.eq(playlist_name).and(owner.eq(user.id))) - .get_result(connection.deref())?; + .get_result(&connection)?; } } @@ -131,34 +125,29 @@ where } { - let connection = db.get_connection(); - connection - .deref() - .transaction::<_, diesel::result::Error, _>(|| { - // Delete old content (if any) - let old_songs = PlaylistSong::belonging_to(&playlist); - diesel::delete(old_songs).execute(connection.deref())?; + let connection = db.connect()?; + connection.transaction::<_, diesel::result::Error, _>(|| { + // Delete old content (if any) + let old_songs = PlaylistSong::belonging_to(&playlist); + diesel::delete(old_songs).execute(connection.deref())?; - // Insert content - diesel::insert_into(playlist_songs::table) - .values(&new_songs) - .execute(connection.deref())?; - Ok(()) - })?; + // Insert content + diesel::insert_into(playlist_songs::table) + .values(&new_songs) + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 + Ok(()) + })?; } Ok(()) } -pub fn read_playlist(playlist_name: &str, owner: &str, db: &T) -> Result> -where - T: ConnectionSource + VFSSource, -{ +pub fn read_playlist(playlist_name: &str, owner: &str, db: &DB) -> Result> { let vfs = db.get_vfs()?; let songs: Vec; { - let connection = db.get_connection(); + let connection = db.connect()?; let user: User; let playlist: Playlist; @@ -168,7 +157,7 @@ where user = users .filter(name.eq(owner)) .select((id,)) - .get_result(connection.deref())?; + .get_result(&connection)?; } // Find playlist @@ -177,7 +166,7 @@ where playlist = playlists .select((id, owner)) .filter(name.eq(playlist_name).and(owner.eq(user.id))) - .get_result(connection.deref())?; + .get_result(&connection)?; } // Select songs. Not using Diesel because we need to LEFT JOIN using a custom column @@ -191,7 +180,7 @@ where "#, ); let query = query.clone().bind::(playlist.id); - songs = query.get_results(connection.deref())?; + songs = query.get_results(&connection)?; } // Map real path to virtual paths @@ -203,11 +192,8 @@ where Ok(virtual_songs) } -pub fn delete_playlist(playlist_name: &str, owner: &str, db: &T) -> Result<()> -where - T: ConnectionSource + VFSSource, -{ - let connection = db.get_connection(); +pub fn delete_playlist(playlist_name: &str, owner: &str, db: &DB) -> Result<()> { + let connection = db.connect()?; let user: User; { @@ -215,7 +201,7 @@ where user = users .filter(name.eq(owner)) .select((id,)) - .first(connection.deref())?; + .first(&connection)?; } { diff --git a/src/service/actix/api.rs b/src/service/actix/api.rs index 34bd807..ef7e2e3 100644 --- a/src/service/actix/api.rs +++ b/src/service/actix/api.rs @@ -1,13 +1,56 @@ -use actix_web::{get, HttpResponse}; +use actix_http::ResponseBuilder; +use actix_web::{error, get, http::header, http::StatusCode, put, web, HttpResponse}; +use anyhow::*; +use crate::config::{self, Config, Preferences}; +use crate::db::DB; use crate::service::constants::*; use crate::service::dto; +use crate::service::error::APIError; +use crate::user; + +impl error::ResponseError for APIError { + fn error_response(&self) -> HttpResponse { + ResponseBuilder::new(self.status_code()) + .set_header(header::CONTENT_TYPE, "text/html; charset=utf-8") + .body(self.to_string()) + } + fn status_code(&self) -> StatusCode { + match *self { + APIError::IncorrectCredentials => StatusCode::UNAUTHORIZED, + APIError::Unspecified => StatusCode::INTERNAL_SERVER_ERROR, + } + } +} #[get("/version")] -pub async fn get_version() -> Result { +pub async fn get_version() -> Result { let current_version = dto::Version { major: CURRENT_MAJOR_VERSION, minor: CURRENT_MINOR_VERSION, }; Ok(HttpResponse::Ok().json(current_version)) } + +#[get("/initial_setup")] +pub async fn get_initial_setup(db: web::Data) -> Result { + let user_count = web::block(move || user::count(&db)) + .await + .map_err(|_| anyhow!("Could not count users"))?; + let initial_setup = dto::InitialSetup { + has_any_users: user_count > 0, + }; + Ok(HttpResponse::Ok().json(initial_setup)) +} + +#[put("/settings")] +pub async fn put_settings( + db: web::Data, + // _admin_rights: AdminRights, // TODO + config: web::Json, +) -> Result { + web::block(move || config::amend(&db, &config)) + .await + .map_err(|_| anyhow!("Could not amend config"))?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs index f8e7365..e420973 100644 --- a/src/service/actix/mod.rs +++ b/src/service/actix/mod.rs @@ -2,6 +2,8 @@ use actix_files as fs; use actix_web::web; use std::path::Path; +use crate::db::DB; + pub mod server; mod api; @@ -14,9 +16,16 @@ fn configure_app( web_dir_path: &Path, swagger_url: &str, swagger_dir_path: &Path, + db: &DB, ) { // TODO logging - cfg.service(web::scope("/api").service(api::get_version)) + cfg.data(db.clone()) + .service( + web::scope("/api") + .service(api::get_initial_setup) + .service(api::get_version) + .service(api::put_settings), + ) .service(fs::Files::new(swagger_url, swagger_dir_path).index_file("index.html")) .service(fs::Files::new(web_url, web_dir_path).index_file("index.html")); } diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs index 9b82631..2dcc699 100644 --- a/src/service/actix/server.rs +++ b/src/service/actix/server.rs @@ -15,7 +15,7 @@ pub async fn run( web_dir_path: PathBuf, swagger_url: String, swagger_dir_path: PathBuf, - db: Arc, + db: DB, command_sender: Arc, ) -> Result<()> { HttpServer::new(move || { @@ -26,6 +26,7 @@ pub async fn run( web_dir_path.as_path(), &swagger_url, swagger_dir_path.as_path(), + &db, ) }) }) diff --git a/src/service/actix/tests/api.rs b/src/service/actix/tests/api.rs index 6564f1f..e6b72c1 100644 --- a/src/service/actix/tests/api.rs +++ b/src/service/actix/tests/api.rs @@ -1,23 +1,114 @@ -use actix_web::body::Body::Bytes; +use actix_http::Request; use actix_web::dev::*; use actix_web::test::TestRequest; use actix_web::{test, App}; +use super::configure_test_app; +use crate::config; use crate::service::dto; +use crate::vfs; + +const TEST_USERNAME: &str = "test_user"; +const TEST_PASSWORD: &str = "test_password"; +const TEST_MOUNT_NAME: &str = "collection"; +const TEST_MOUNT_SOURCE: &str = "test/collection"; + +trait BodyTest { + fn as_u8(&self) -> &[u8]; +} + +impl BodyTest for ResponseBody { + fn as_u8(&self) -> &[u8] { + match self { + ResponseBody::Body(ref b) => match b { + Body::Bytes(ref by) => by.as_ref(), + _ => panic!(), + }, + ResponseBody::Other(ref b) => match b { + Body::Bytes(ref by) => by.as_ref(), + _ => panic!(), + }, + } + } +} + +fn initial_setup() -> Request { + let configuration = config::Config { + album_art_pattern: None, + prefix_url: None, + reindex_every_n_seconds: None, + ydns: None, + users: Some(vec![config::ConfigUser { + name: TEST_USERNAME.into(), + password: TEST_PASSWORD.into(), + admin: true, + }]), + mount_dirs: Some(vec![vfs::MountPoint { + name: TEST_MOUNT_NAME.into(), + source: TEST_MOUNT_SOURCE.into(), + }]), + }; + + TestRequest::put() + .uri("/api/settings") + .set_json(&configuration) + .to_request() +} #[actix_rt::test] async fn test_version() { - let app = App::new().configure(super::configure_test_app); + let app = App::new().configure(|cfg| configure_test_app(cfg, "test_version")); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/api/version").to_request(); let resp = service.call(req).await.unwrap(); assert!(resp.status().is_success()); - let body = match resp.response().body().as_ref() { - Some(Bytes(bytes)) => bytes, - _ => panic!("Response error"), - }; - + let body = resp.response().body().as_u8(); let response_json: dto::Version = serde_json::from_slice(body).unwrap(); assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); } + +#[actix_rt::test] +async fn test_initial_setup() { + let app = App::new().configure(|cfg| configure_test_app(cfg, "test_initial_setup")); + let mut service = test::init_service(app).await; + + { + let req = TestRequest::get().uri("/api/initial_setup").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); + + let body = resp.response().body().as_u8(); + let response_json: dto::InitialSetup = serde_json::from_slice(body).unwrap(); + + assert_eq!( + response_json, + dto::InitialSetup { + has_any_users: false + } + ); + } + + assert!(service + .call(initial_setup()) + .await + .unwrap() + .status() + .is_success()); + + { + let req = TestRequest::get().uri("/api/initial_setup").to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); + + let body = resp.response().body().as_u8(); + let response_json: dto::InitialSetup = serde_json::from_slice(body).unwrap(); + + assert_eq!( + response_json, + dto::InitialSetup { + has_any_users: true + } + ); + } +} diff --git a/src/service/actix/tests/mod.rs b/src/service/actix/tests/mod.rs index ea62291..897a9ea 100644 --- a/src/service/actix/tests/mod.rs +++ b/src/service/actix/tests/mod.rs @@ -1,10 +1,13 @@ +use std::fs; use std::path::PathBuf; +use crate::db::DB; + mod api; mod swagger; mod web; -fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig) { +fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig, db_name: &str) { let web_url = "/"; let web_dir_path = PathBuf::from("web"); @@ -12,11 +15,20 @@ fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig) { let mut swagger_dir_path = PathBuf::from("docs"); swagger_dir_path.push("swagger"); + let mut db_path = PathBuf::new(); + db_path.push("test"); + db_path.push(format!("{}.sqlite", db_name)); + if db_path.exists() { + fs::remove_file(&db_path).unwrap(); + } + let db = DB::new(&db_path).unwrap(); + super::configure_app( cfg, web_url, web_dir_path.as_path(), swagger_url, swagger_dir_path.as_path(), + &db, ); } diff --git a/src/service/actix/tests/swagger.rs b/src/service/actix/tests/swagger.rs index f717ae8..73f5ecd 100644 --- a/src/service/actix/tests/swagger.rs +++ b/src/service/actix/tests/swagger.rs @@ -2,9 +2,11 @@ use actix_web::dev::Service; use actix_web::test::TestRequest; use actix_web::{test, App}; +use super::configure_test_app; + #[actix_rt::test] -async fn test_index() { - let app = App::new().configure(super::configure_test_app); +async fn test_swagger_index() { + let app = App::new().configure(|cfg| configure_test_app(cfg, "test_swagger_index")); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/swagger").to_request(); let resp = service.call(req).await.unwrap(); @@ -12,8 +14,9 @@ async fn test_index() { } #[actix_rt::test] -async fn test_index_with_trailing_slash() { - let app = App::new().configure(super::configure_test_app); +async fn test_swagger_index_with_trailing_slash() { + let app = App::new() + .configure(|cfg| configure_test_app(cfg, "test_swagger_index_with_trailing_slash")); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/swagger/").to_request(); let resp = service.call(req).await.unwrap(); diff --git a/src/service/actix/tests/web.rs b/src/service/actix/tests/web.rs index 898e9d1..70b7a15 100644 --- a/src/service/actix/tests/web.rs +++ b/src/service/actix/tests/web.rs @@ -2,9 +2,11 @@ use actix_web::dev::Service; use actix_web::test::TestRequest; use actix_web::{test, App}; +use super::configure_test_app; + #[actix_rt::test] async fn test_index() { - let app = App::new().configure(super::configure_test_app); + let app = App::new().configure(|cfg| configure_test_app(cfg, "test_index")); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/").to_request(); let resp = service.call(req).await.unwrap(); diff --git a/src/service/dto.rs b/src/service/dto.rs index 51973f1..fb31e5c 100644 --- a/src/service/dto.rs +++ b/src/service/dto.rs @@ -5,3 +5,8 @@ pub struct Version { pub major: i32, pub minor: i32, } + +#[derive(PartialEq, Debug, Serialize, Deserialize)] +pub struct InitialSetup { + pub has_any_users: bool, +} diff --git a/src/service/error.rs b/src/service/error.rs new file mode 100644 index 0000000..0ff3340 --- /dev/null +++ b/src/service/error.rs @@ -0,0 +1,15 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum APIError { + #[error("Incorrect Credentials")] + IncorrectCredentials, + #[error("Unspecified")] + Unspecified, +} + +impl From for APIError { + fn from(_: anyhow::Error) -> Self { + APIError::Unspecified + } +} diff --git a/src/service/mod.rs b/src/service/mod.rs index fe22d69..6be9bb4 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,5 +1,6 @@ mod constants; mod dto; +mod error; #[cfg(feature = "service-actix")] mod actix; diff --git a/src/service/rocket/api.rs b/src/service/rocket/api.rs index 538f02f..a61e088 100644 --- a/src/service/rocket/api.rs +++ b/src/service/rocket/api.rs @@ -11,7 +11,6 @@ use std::path::PathBuf; use std::str; use std::str::FromStr; use std::sync::Arc; -use thiserror::Error; use time::Duration; use super::serve; @@ -22,6 +21,7 @@ use crate::lastfm; use crate::playlist; use crate::service::constants::*; use crate::service::dto; +use crate::service::error::APIError; use crate::thumbnails; use crate::user; use crate::utils; @@ -57,14 +57,6 @@ pub fn get_routes() -> Vec { ] } -#[derive(Error, Debug)] -enum APIError { - #[error("Incorrect Credentials")] - IncorrectCredentials, - #[error("Unspecified")] - Unspecified, -} - impl<'r> rocket::response::Responder<'r> for APIError { fn respond_to(self, _: &rocket::request::Request<'_>) -> rocket::response::Result<'r> { let status = match self { @@ -75,12 +67,6 @@ impl<'r> rocket::response::Responder<'r> for APIError { } } -impl From for APIError { - fn from(_: anyhow::Error) -> Self { - APIError::Unspecified - } -} - struct Auth { username: String, } @@ -118,7 +104,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Auth { fn from_request(request: &'a Request<'r>) -> request::Outcome { let mut cookies = request.guard::>().unwrap(); - let db = match request.guard::>>() { + let db = match request.guard::>() { Outcome::Success(d) => d, _ => return Outcome::Failure((Status::InternalServerError, ())), }; @@ -165,16 +151,16 @@ impl<'a, 'r> FromRequest<'a, 'r> for AdminRights { type Error = (); fn from_request(request: &'a Request<'r>) -> request::Outcome { - let db = request.guard::>>()?; + let db = request.guard::>()?; - match user::count::(&db) { + match user::count(&db) { Err(_) => return Outcome::Failure((Status::InternalServerError, ())), Ok(0) => return Outcome::Success(AdminRights {}), _ => (), }; let auth = request.guard::()?; - match user::is_admin::(&db, &auth.username) { + match user::is_admin(&db, &auth.username) { Err(_) => Outcome::Failure((Status::InternalServerError, ())), Ok(true) => Outcome::Success(AdminRights {}), Ok(false) => Outcome::Failure((Status::Forbidden, ())), @@ -212,48 +198,35 @@ fn version() -> Json { Json(current_version) } -#[derive(PartialEq, Debug, Serialize, Deserialize)] -pub struct InitialSetup { - pub has_any_users: bool, -} - #[get("/initial_setup")] -fn initial_setup(db: State<'_, Arc>) -> Result> { - let initial_setup = InitialSetup { - has_any_users: user::count::(&db)? > 0, +fn initial_setup(db: State<'_, DB>) -> Result> { + let initial_setup = dto::InitialSetup { + has_any_users: user::count(&db)? > 0, }; Ok(Json(initial_setup)) } #[get("/settings")] -fn get_settings(db: State<'_, Arc>, _admin_rights: AdminRights) -> Result> { - let config = config::read::(&db)?; +fn get_settings(db: State<'_, DB>, _admin_rights: AdminRights) -> Result> { + let config = config::read(&db)?; Ok(Json(config)) } #[put("/settings", data = "")] -fn put_settings( - db: State<'_, Arc>, - _admin_rights: AdminRights, - config: Json, -) -> Result<()> { - config::amend::(&db, &config)?; +fn put_settings(db: State<'_, DB>, _admin_rights: AdminRights, config: Json) -> Result<()> { + config::amend(&db, &config)?; Ok(()) } #[get("/preferences")] -fn get_preferences(db: State<'_, Arc>, auth: Auth) -> Result> { - let preferences = config::read_preferences::(&db, &auth.username)?; +fn get_preferences(db: State<'_, DB>, auth: Auth) -> Result> { + let preferences = config::read_preferences(&db, &auth.username)?; Ok(Json(preferences)) } #[put("/preferences", data = "")] -fn put_preferences( - db: State<'_, Arc>, - auth: Auth, - preferences: Json, -) -> Result<()> { - config::write_preferences::(&db, &auth.username, &preferences)?; +fn put_preferences(db: State<'_, DB>, auth: Auth, preferences: Json) -> Result<()> { + config::write_preferences(&db, &auth.username, &preferences)?; Ok(()) } @@ -279,27 +252,27 @@ struct AuthOutput { #[post("/auth", data = "")] fn auth( - db: State<'_, Arc>, + db: State<'_, DB>, credentials: Json, mut cookies: Cookies<'_>, ) -> std::result::Result<(), APIError> { - if !user::auth::(&db, &credentials.username, &credentials.password)? { + if !user::auth(&db, &credentials.username, &credentials.password)? { return Err(APIError::IncorrectCredentials); } - let is_admin = user::is_admin::(&db, &credentials.username)?; + let is_admin = user::is_admin(&db, &credentials.username)?; add_session_cookies(&mut cookies, &credentials.username, is_admin); Ok(()) } #[get("/browse")] -fn browse_root(db: State<'_, Arc>, _auth: Auth) -> Result>> { +fn browse_root(db: State<'_, DB>, _auth: Auth) -> Result>> { let result = index::browse(db.deref().deref(), &PathBuf::new())?; Ok(Json(result)) } #[get("/browse/")] fn browse( - db: State<'_, Arc>, + db: State<'_, DB>, _auth: Auth, path: VFSPathBuf, ) -> Result>> { @@ -308,42 +281,38 @@ fn browse( } #[get("/flatten")] -fn flatten_root(db: State<'_, Arc>, _auth: Auth) -> Result>> { +fn flatten_root(db: State<'_, DB>, _auth: Auth) -> Result>> { let result = index::flatten(db.deref().deref(), &PathBuf::new())?; Ok(Json(result)) } #[get("/flatten/")] -fn flatten( - db: State<'_, Arc>, - _auth: Auth, - path: VFSPathBuf, -) -> Result>> { +fn flatten(db: State<'_, DB>, _auth: Auth, path: VFSPathBuf) -> Result>> { let result = index::flatten(db.deref().deref(), &path.into() as &PathBuf)?; Ok(Json(result)) } #[get("/random")] -fn random(db: State<'_, Arc>, _auth: Auth) -> Result>> { +fn random(db: State<'_, DB>, _auth: Auth) -> Result>> { let result = index::get_random_albums(db.deref().deref(), 20)?; Ok(Json(result)) } #[get("/recent")] -fn recent(db: State<'_, Arc>, _auth: Auth) -> Result>> { +fn recent(db: State<'_, DB>, _auth: Auth) -> Result>> { let result = index::get_recent_albums(db.deref().deref(), 20)?; Ok(Json(result)) } #[get("/search")] -fn search_root(db: State<'_, Arc>, _auth: Auth) -> Result>> { +fn search_root(db: State<'_, DB>, _auth: Auth) -> Result>> { let result = index::search(db.deref().deref(), "")?; Ok(Json(result)) } #[get("/search/")] fn search( - db: State<'_, Arc>, + db: State<'_, DB>, _auth: Auth, query: String, ) -> Result>> { @@ -352,12 +321,7 @@ fn search( } #[get("/serve/")] -fn serve( - db: State<'_, Arc>, - _auth: Auth, - path: VFSPathBuf, -) -> Result> { - let db: &DB = db.deref().deref(); +fn serve(db: State<'_, DB>, _auth: Auth, path: VFSPathBuf) -> Result> { let vfs = db.get_vfs()?; let real_path = vfs.virtual_to_real(&path.into() as &PathBuf)?; @@ -377,7 +341,7 @@ pub struct ListPlaylistsEntry { } #[get("/playlists")] -fn list_playlists(db: State<'_, Arc>, auth: Auth) -> Result>> { +fn list_playlists(db: State<'_, DB>, auth: Auth) -> Result>> { let playlist_names = playlist::list_playlists(&auth.username, db.deref().deref())?; let playlists: Vec = playlist_names .into_iter() @@ -394,7 +358,7 @@ pub struct SavePlaylistInput { #[put("/playlist/", data = "")] fn save_playlist( - db: State<'_, Arc>, + db: State<'_, DB>, auth: Auth, name: String, playlist: Json, @@ -404,23 +368,19 @@ fn save_playlist( } #[get("/playlist/")] -fn read_playlist( - db: State<'_, Arc>, - auth: Auth, - name: String, -) -> Result>> { +fn read_playlist(db: State<'_, DB>, auth: Auth, name: String) -> Result>> { let songs = playlist::read_playlist(&name, &auth.username, db.deref().deref())?; Ok(Json(songs)) } #[delete("/playlist/")] -fn delete_playlist(db: State<'_, Arc>, auth: Auth, name: String) -> Result<()> { +fn delete_playlist(db: State<'_, DB>, auth: Auth, name: String) -> Result<()> { playlist::delete_playlist(&name, &auth.username, db.deref().deref())?; Ok(()) } #[put("/lastfm/now_playing/")] -fn lastfm_now_playing(db: State<'_, Arc>, auth: Auth, path: VFSPathBuf) -> Result<()> { +fn lastfm_now_playing(db: State<'_, DB>, auth: Auth, path: VFSPathBuf) -> Result<()> { if user::is_lastfm_linked(db.deref().deref(), &auth.username) { lastfm::now_playing(db.deref().deref(), &auth.username, &path.into() as &PathBuf)?; } @@ -428,7 +388,7 @@ fn lastfm_now_playing(db: State<'_, Arc>, auth: Auth, path: VFSPathBuf) -> R } #[post("/lastfm/scrobble/")] -fn lastfm_scrobble(db: State<'_, Arc>, auth: Auth, path: VFSPathBuf) -> Result<()> { +fn lastfm_scrobble(db: State<'_, DB>, auth: Auth, path: VFSPathBuf) -> Result<()> { if user::is_lastfm_linked(db.deref().deref(), &auth.username) { lastfm::scrobble(db.deref().deref(), &auth.username, &path.into() as &PathBuf)?; } @@ -437,7 +397,7 @@ fn lastfm_scrobble(db: State<'_, Arc>, auth: Auth, path: VFSPathBuf) -> Resu #[get("/lastfm/link?&")] fn lastfm_link( - db: State<'_, Arc>, + db: State<'_, DB>, auth: Auth, token: String, content: String, @@ -457,7 +417,7 @@ fn lastfm_link( } #[delete("/lastfm/link")] -fn lastfm_unlink(db: State<'_, Arc>, auth: Auth) -> Result<()> { +fn lastfm_unlink(db: State<'_, DB>, auth: Auth) -> Result<()> { lastfm::unlink(db.deref().deref(), &auth.username)?; Ok(()) } diff --git a/src/service/rocket/api_tests.rs b/src/service/rocket/api_tests.rs index bd3dcac..52914c5 100644 --- a/src/service/rocket/api_tests.rs +++ b/src/service/rocket/api_tests.rs @@ -71,10 +71,10 @@ fn initial_setup() { let mut response = client.get("/api/initial_setup").dispatch(); assert_eq!(response.status(), Status::Ok); let response_body = response.body_string().unwrap(); - let response_json: api::InitialSetup = serde_json::from_str(&response_body).unwrap(); + let response_json: dto::InitialSetup = serde_json::from_str(&response_body).unwrap(); assert_eq!( response_json, - api::InitialSetup { + dto::InitialSetup { has_any_users: false } ); @@ -86,10 +86,10 @@ fn initial_setup() { let mut response = client.get("/api/initial_setup").dispatch(); assert_eq!(response.status(), Status::Ok); let response_body = response.body_string().unwrap(); - let response_json: api::InitialSetup = serde_json::from_str(&response_body).unwrap(); + let response_json: dto::InitialSetup = serde_json::from_str(&response_body).unwrap(); assert_eq!( response_json, - api::InitialSetup { + dto::InitialSetup { has_any_users: true } ); diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index 05dbda7..84fca9d 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -17,7 +17,7 @@ pub fn get_server( web_dir_path: &PathBuf, swagger_url: &str, swagger_dir_path: &PathBuf, - db: Arc, + db: DB, command_sender: Arc, ) -> Result { let mut config = rocket::Config::build(Environment::Production) @@ -56,7 +56,7 @@ pub fn run( web_dir_path: PathBuf, swagger_url: String, swagger_dir_path: PathBuf, - db: Arc, + db: DB, command_sender: Arc, ) -> Result<()> { let server = get_server( diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index 2705822..a0072f8 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -12,12 +12,12 @@ use crate::index; pub struct TestEnvironment { pub client: Client, command_sender: Arc, - db: Arc, + db: DB, } impl TestEnvironment { pub fn update_index(&self) { - index::update(self.db.deref()).unwrap(); + index::update(&self.db).unwrap(); } } @@ -34,8 +34,7 @@ pub fn get_test_environment(db_name: &str) -> TestEnvironment { if db_path.exists() { fs::remove_file(&db_path).unwrap(); } - - let db = Arc::new(DB::new(&db_path).unwrap()); + let db = DB::new(&db_path).unwrap(); let web_dir_path = PathBuf::from("web"); let mut swagger_dir_path = PathBuf::from("docs"); diff --git a/src/user.rs b/src/user.rs index a4055f7..e0b4dbe 100644 --- a/src/user.rs +++ b/src/user.rs @@ -1,10 +1,9 @@ use anyhow::*; -use core::ops::Deref; use diesel; use diesel::prelude::*; use crate::db::users; -use crate::db::ConnectionSource; +use crate::db::DB; #[derive(Debug, Insertable, Queryable)] #[table_name = "users"] @@ -38,16 +37,13 @@ fn verify_password(password_hash: &str, attempted_password: &str) -> bool { pbkdf2::pbkdf2_check(attempted_password, password_hash).is_ok() } -pub fn auth(db: &T, username: &str, password: &str) -> Result -where - T: ConnectionSource, -{ +pub fn auth(db: &DB, username: &str, password: &str) -> Result { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; match users .select(password_hash) .filter(name.eq(username)) - .get_result(connection.deref()) + .get_result(&connection) { Err(diesel::result::Error::NotFound) => Ok(false), Ok(hash) => { @@ -58,88 +54,67 @@ where } } -pub fn count(db: &T) -> Result -where - T: ConnectionSource, -{ +pub fn count(db: &DB) -> Result { use crate::db::users::dsl::*; - let connection = db.get_connection(); - let count = users.count().get_result(connection.deref())?; + let connection = db.connect()?; + let count = users.count().get_result(&connection)?; Ok(count) } -pub fn exists(db: &T, username: &str) -> Result -where - T: ConnectionSource, -{ +pub fn exists(db: &DB, username: &str) -> Result { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; let results: Vec = users .select(name) .filter(name.eq(username)) - .get_results(connection.deref())?; + .get_results(&connection)?; Ok(results.len() > 0) } -pub fn is_admin(db: &T, username: &str) -> Result -where - T: ConnectionSource, -{ +pub fn is_admin(db: &DB, username: &str) -> Result { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; let is_admin: i32 = users .filter(name.eq(username)) .select(admin) - .get_result(connection.deref())?; + .get_result(&connection)?; Ok(is_admin != 0) } -pub fn lastfm_link(db: &T, username: &str, lastfm_login: &str, session_key: &str) -> Result<()> -where - T: ConnectionSource, -{ +pub fn lastfm_link(db: &DB, username: &str, lastfm_login: &str, session_key: &str) -> Result<()> { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; diesel::update(users.filter(name.eq(username))) .set(( lastfm_username.eq(lastfm_login), lastfm_session_key.eq(session_key), )) - .execute(connection.deref())?; + .execute(&connection)?; Ok(()) } -pub fn get_lastfm_session_key(db: &T, username: &str) -> Result -where - T: ConnectionSource, -{ +pub fn get_lastfm_session_key(db: &DB, username: &str) -> Result { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; let token = users .filter(name.eq(username)) .select(lastfm_session_key) - .get_result(connection.deref())?; + .get_result(&connection)?; match token { Some(t) => Ok(t), _ => Err(anyhow!("Missing LastFM credentials")), } } -pub fn is_lastfm_linked(db: &T, username: &str) -> bool -where - T: ConnectionSource, -{ +pub fn is_lastfm_linked(db: &DB, username: &str) -> bool { get_lastfm_session_key(db, username).is_ok() } -pub fn lastfm_unlink(db: &T, username: &str) -> Result<()> -where - T: ConnectionSource, -{ +pub fn lastfm_unlink(db: &DB, username: &str) -> Result<()> { use crate::db::users::dsl::*; - let connection = db.get_connection(); + let connection = db.connect()?; diesel::update(users.filter(name.eq(username))) .set((lastfm_session_key.eq(""), lastfm_username.eq(""))) - .execute(connection.deref())?; + .execute(&connection)?; Ok(()) } diff --git a/src/vfs.rs b/src/vfs.rs index 44f8584..d5b9280 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -7,7 +7,7 @@ use std::path::Path; use std::path::PathBuf; use crate::db::mount_points; -use crate::db::{ConnectionSource, DB}; +use crate::db::DB; pub trait VFSSource { fn get_vfs(&self) -> Result; @@ -17,7 +17,7 @@ impl VFSSource for DB { fn get_vfs(&self) -> Result { use self::mount_points::dsl::*; let mut vfs = VFS::new(); - let connection = self.get_connection(); + let connection = self.connect()?; let points: Vec = mount_points .select((source, name)) .get_results(connection.deref())?; From a83e1af69bed970f571a360b605fe749f2ce1ec0 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Wed, 15 Jan 2020 22:05:41 -0800 Subject: [PATCH 07/32] automatic db file names --- Cargo.lock | 30 ++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/service/actix/tests/api.rs | 7 +++++-- src/service/actix/tests/swagger.rs | 8 +++++--- src/service/actix/tests/web.rs | 4 +++- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88b64d8..990e659 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1041,6 +1041,24 @@ name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "function_name" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "function_name-proc-macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "function_name-proc-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "futures" version = "0.1.29" @@ -2058,6 +2076,7 @@ dependencies = [ "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "flame 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "flamer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "function_name 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "id3 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2092,6 +2111,14 @@ name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-hack" version = "0.5.11" @@ -3545,6 +3572,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum function_name 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88b2afa9b514dc3a75af6cf24d1914e1c7eb6f1b86de849147563548d5c0a0cd" +"checksum function_name-proc-macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6790a8d356d2f65d7972181e866b92a50a87c27d6a48cbe9dbb8be13ca784c7d" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" "checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" "checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" @@ -3654,6 +3683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum png 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "247cb804bd7fc86d0c2b153d1374265e67945875720136ca8fe451f11c6aed52" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" diff --git a/Cargo.toml b/Cargo.toml index 304f6e4..8f7eb28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ diesel = { version = "1.4", features = ["sqlite", "r2d2"] } diesel_migrations = { version = "1.4", features = ["sqlite"] } flame = { version = "0.2.2", optional = true } flamer = { version = "0.4", optional = true } +function_name = "0.2.0" getopts = "0.2.15" id3 = "0.3" image = "0.22" diff --git a/src/service/actix/tests/api.rs b/src/service/actix/tests/api.rs index e6b72c1..af27cd2 100644 --- a/src/service/actix/tests/api.rs +++ b/src/service/actix/tests/api.rs @@ -2,6 +2,7 @@ use actix_http::Request; use actix_web::dev::*; use actix_web::test::TestRequest; use actix_web::{test, App}; +use function_name::named; use super::configure_test_app; use crate::config; @@ -55,9 +56,10 @@ fn initial_setup() -> Request { .to_request() } +#[named] #[actix_rt::test] async fn test_version() { - let app = App::new().configure(|cfg| configure_test_app(cfg, "test_version")); + let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/api/version").to_request(); let resp = service.call(req).await.unwrap(); @@ -68,9 +70,10 @@ async fn test_version() { assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); } +#[named] #[actix_rt::test] async fn test_initial_setup() { - let app = App::new().configure(|cfg| configure_test_app(cfg, "test_initial_setup")); + let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); let mut service = test::init_service(app).await; { diff --git a/src/service/actix/tests/swagger.rs b/src/service/actix/tests/swagger.rs index 73f5ecd..e421ff1 100644 --- a/src/service/actix/tests/swagger.rs +++ b/src/service/actix/tests/swagger.rs @@ -1,22 +1,24 @@ use actix_web::dev::Service; use actix_web::test::TestRequest; use actix_web::{test, App}; +use function_name::named; use super::configure_test_app; +#[named] #[actix_rt::test] async fn test_swagger_index() { - let app = App::new().configure(|cfg| configure_test_app(cfg, "test_swagger_index")); + let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/swagger").to_request(); let resp = service.call(req).await.unwrap(); assert!(resp.status().is_success()); } +#[named] #[actix_rt::test] async fn test_swagger_index_with_trailing_slash() { - let app = App::new() - .configure(|cfg| configure_test_app(cfg, "test_swagger_index_with_trailing_slash")); + let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/swagger/").to_request(); let resp = service.call(req).await.unwrap(); diff --git a/src/service/actix/tests/web.rs b/src/service/actix/tests/web.rs index 70b7a15..1f890fe 100644 --- a/src/service/actix/tests/web.rs +++ b/src/service/actix/tests/web.rs @@ -1,12 +1,14 @@ use actix_web::dev::Service; use actix_web::test::TestRequest; use actix_web::{test, App}; +use function_name::named; use super::configure_test_app; +#[named] #[actix_rt::test] async fn test_index() { - let app = App::new().configure(|cfg| configure_test_app(cfg, "test_index")); + let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); let mut service = test::init_service(app).await; let req = TestRequest::get().uri("/").to_request(); let resp = service.call(req).await.unwrap(); From 61c221a2d22089069b695698b42691658e22b1e8 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 00:34:47 -0800 Subject: [PATCH 08/32] integration test sharing between backends --- Cargo.lock | 1 + Cargo.toml | 5 +- src/main.rs | 2 +- src/service/actix/api.rs | 4 +- src/service/actix/mod.rs | 2 +- src/service/actix/test.rs | 84 +++++++++++++++++++++ src/service/actix/tests/api.rs | 117 ----------------------------- src/service/actix/tests/mod.rs | 34 --------- src/service/actix/tests/swagger.rs | 26 ------- src/service/actix/tests/web.rs | 16 ---- src/service/mod.rs | 3 + src/service/rocket/api_tests.rs | 48 ------------ src/service/rocket/mod.rs | 6 +- src/service/rocket/swagger.rs | 19 ----- src/service/rocket/test.rs | 30 ++++++++ src/service/rocket/web.rs | 10 --- src/service/tests.rs | 95 +++++++++++++++++++++++ 17 files changed, 221 insertions(+), 281 deletions(-) create mode 100644 src/service/actix/test.rs delete mode 100644 src/service/actix/tests/api.rs delete mode 100644 src/service/actix/tests/mod.rs delete mode 100644 src/service/actix/tests/swagger.rs delete mode 100644 src/service/actix/tests/web.rs delete mode 100644 src/service/rocket/swagger.rs delete mode 100644 src/service/rocket/web.rs create mode 100644 src/service/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 990e659..cb80aa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,6 +2071,7 @@ dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 8f7eb28..c0a2f44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,17 +8,18 @@ edition = "2018" default = ["service-actix"] ui = [] profile-index = ["flame", "flamer"] -service-actix = ["actix-files", "actix-http", "actix-rt", "actix-web"] +service-actix = ["actix-files", "actix-http", "actix-web"] service-rocket = ["rocket", "rocket_contrib"] [dependencies] actix-files = { version = "0.2", optional = true } actix-http = { version = "1.0", optional = true } actix-web = { version = "2.0", optional = true } -actix-rt = { version = "1.0", optional = true } +actix-rt = { version = "1.0"} anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" +async-trait = "0.1.22" base64 = "0.11.0" diesel = { version = "1.4", features = ["sqlite", "r2d2"] } diesel_migrations = { version = "1.4", features = ["sqlite"] } diff --git a/src/main.rs b/src/main.rs index ced7af9..cb02cf8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ #![recursion_limit = "256"] -#![feature(proc_macro_hygiene, decl_macro)] +#![feature(proc_macro_hygiene, decl_macro, type_alias_impl_trait)] #[macro_use] extern crate diesel; diff --git a/src/service/actix/api.rs b/src/service/actix/api.rs index ef7e2e3..f7d5b32 100644 --- a/src/service/actix/api.rs +++ b/src/service/actix/api.rs @@ -2,7 +2,7 @@ use actix_http::ResponseBuilder; use actix_web::{error, get, http::header, http::StatusCode, put, web, HttpResponse}; use anyhow::*; -use crate::config::{self, Config, Preferences}; +use crate::config::{self, Config}; use crate::db::DB; use crate::service::constants::*; use crate::service::dto; @@ -46,7 +46,7 @@ pub async fn get_initial_setup(db: web::Data) -> Result, - // _admin_rights: AdminRights, // TODO + // _admin_rights: AdminRights, // TODO.important config: web::Json, ) -> Result { web::block(move || config::amend(&db, &config)) diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs index e420973..d2e41f7 100644 --- a/src/service/actix/mod.rs +++ b/src/service/actix/mod.rs @@ -8,7 +8,7 @@ pub mod server; mod api; #[cfg(test)] -mod tests; +pub mod test; fn configure_app( cfg: &mut web::ServiceConfig, diff --git a/src/service/actix/test.rs b/src/service/actix/test.rs new file mode 100644 index 0000000..a140bec --- /dev/null +++ b/src/service/actix/test.rs @@ -0,0 +1,84 @@ +use actix_http::{Error, Request}; +use actix_web::dev::{Body, ResponseBody, Service, ServiceResponse}; +use actix_web::test::TestRequest; +use actix_web::{test, App}; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::fs; +use std::path::PathBuf; + +use crate::db::DB; + +fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig, db_name: &str) { + let web_url = "/"; + let web_dir_path = PathBuf::from("web"); + + let swagger_url = "swagger"; + let mut swagger_dir_path = PathBuf::from("docs"); + swagger_dir_path.push("swagger"); + + let mut db_path = PathBuf::new(); + db_path.push("test"); + db_path.push(format!("{}.sqlite", db_name)); + if db_path.exists() { + fs::remove_file(&db_path).unwrap(); + } + let db = DB::new(&db_path).unwrap(); + + super::configure_app( + cfg, + web_url, + web_dir_path.as_path(), + swagger_url, + swagger_dir_path.as_path(), + &db, + ); +} + +pub type ServiceType = impl Service; + +pub async fn make_service(test_name: &str) -> ServiceType { + let app = App::new().configure(|cfg| configure_test_app(cfg, test_name)); + let service = test::init_service(app).await; + service +} + +pub async fn get(service: &mut ServiceType, url: &str) { + let req = TestRequest::get().uri(url).to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); +} + +pub async fn get_json(service: &mut ServiceType, url: &str) -> T { + let req = TestRequest::get().uri(url).to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); + let body = resp.response().body().as_u8(); + let response_json: T = serde_json::from_slice(body).unwrap(); + response_json +} + +pub async fn put_json(service: &mut ServiceType, url: &str, payload: &T) { + let req = TestRequest::put().uri(url).set_json(payload).to_request(); + let resp = service.call(req).await.unwrap(); + assert!(resp.status().is_success()); +} + +trait BodyToBytes { + fn as_u8(&self) -> &[u8]; +} + +impl BodyToBytes for ResponseBody { + fn as_u8(&self) -> &[u8] { + match self { + ResponseBody::Body(ref b) => match b { + Body::Bytes(ref by) => by.as_ref(), + _ => panic!(), + }, + ResponseBody::Other(ref b) => match b { + Body::Bytes(ref by) => by.as_ref(), + _ => panic!(), + }, + } + } +} diff --git a/src/service/actix/tests/api.rs b/src/service/actix/tests/api.rs deleted file mode 100644 index af27cd2..0000000 --- a/src/service/actix/tests/api.rs +++ /dev/null @@ -1,117 +0,0 @@ -use actix_http::Request; -use actix_web::dev::*; -use actix_web::test::TestRequest; -use actix_web::{test, App}; -use function_name::named; - -use super::configure_test_app; -use crate::config; -use crate::service::dto; -use crate::vfs; - -const TEST_USERNAME: &str = "test_user"; -const TEST_PASSWORD: &str = "test_password"; -const TEST_MOUNT_NAME: &str = "collection"; -const TEST_MOUNT_SOURCE: &str = "test/collection"; - -trait BodyTest { - fn as_u8(&self) -> &[u8]; -} - -impl BodyTest for ResponseBody { - fn as_u8(&self) -> &[u8] { - match self { - ResponseBody::Body(ref b) => match b { - Body::Bytes(ref by) => by.as_ref(), - _ => panic!(), - }, - ResponseBody::Other(ref b) => match b { - Body::Bytes(ref by) => by.as_ref(), - _ => panic!(), - }, - } - } -} - -fn initial_setup() -> Request { - let configuration = config::Config { - album_art_pattern: None, - prefix_url: None, - reindex_every_n_seconds: None, - ydns: None, - users: Some(vec![config::ConfigUser { - name: TEST_USERNAME.into(), - password: TEST_PASSWORD.into(), - admin: true, - }]), - mount_dirs: Some(vec![vfs::MountPoint { - name: TEST_MOUNT_NAME.into(), - source: TEST_MOUNT_SOURCE.into(), - }]), - }; - - TestRequest::put() - .uri("/api/settings") - .set_json(&configuration) - .to_request() -} - -#[named] -#[actix_rt::test] -async fn test_version() { - let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); - let mut service = test::init_service(app).await; - let req = TestRequest::get().uri("/api/version").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); - - let body = resp.response().body().as_u8(); - let response_json: dto::Version = serde_json::from_slice(body).unwrap(); - assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); -} - -#[named] -#[actix_rt::test] -async fn test_initial_setup() { - let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); - let mut service = test::init_service(app).await; - - { - let req = TestRequest::get().uri("/api/initial_setup").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); - - let body = resp.response().body().as_u8(); - let response_json: dto::InitialSetup = serde_json::from_slice(body).unwrap(); - - assert_eq!( - response_json, - dto::InitialSetup { - has_any_users: false - } - ); - } - - assert!(service - .call(initial_setup()) - .await - .unwrap() - .status() - .is_success()); - - { - let req = TestRequest::get().uri("/api/initial_setup").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); - - let body = resp.response().body().as_u8(); - let response_json: dto::InitialSetup = serde_json::from_slice(body).unwrap(); - - assert_eq!( - response_json, - dto::InitialSetup { - has_any_users: true - } - ); - } -} diff --git a/src/service/actix/tests/mod.rs b/src/service/actix/tests/mod.rs deleted file mode 100644 index 897a9ea..0000000 --- a/src/service/actix/tests/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::fs; -use std::path::PathBuf; - -use crate::db::DB; - -mod api; -mod swagger; -mod web; - -fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig, db_name: &str) { - let web_url = "/"; - let web_dir_path = PathBuf::from("web"); - - let swagger_url = "swagger"; - let mut swagger_dir_path = PathBuf::from("docs"); - swagger_dir_path.push("swagger"); - - let mut db_path = PathBuf::new(); - db_path.push("test"); - db_path.push(format!("{}.sqlite", db_name)); - if db_path.exists() { - fs::remove_file(&db_path).unwrap(); - } - let db = DB::new(&db_path).unwrap(); - - super::configure_app( - cfg, - web_url, - web_dir_path.as_path(), - swagger_url, - swagger_dir_path.as_path(), - &db, - ); -} diff --git a/src/service/actix/tests/swagger.rs b/src/service/actix/tests/swagger.rs deleted file mode 100644 index e421ff1..0000000 --- a/src/service/actix/tests/swagger.rs +++ /dev/null @@ -1,26 +0,0 @@ -use actix_web::dev::Service; -use actix_web::test::TestRequest; -use actix_web::{test, App}; -use function_name::named; - -use super::configure_test_app; - -#[named] -#[actix_rt::test] -async fn test_swagger_index() { - let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); - let mut service = test::init_service(app).await; - let req = TestRequest::get().uri("/swagger").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); -} - -#[named] -#[actix_rt::test] -async fn test_swagger_index_with_trailing_slash() { - let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); - let mut service = test::init_service(app).await; - let req = TestRequest::get().uri("/swagger/").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); -} diff --git a/src/service/actix/tests/web.rs b/src/service/actix/tests/web.rs deleted file mode 100644 index 1f890fe..0000000 --- a/src/service/actix/tests/web.rs +++ /dev/null @@ -1,16 +0,0 @@ -use actix_web::dev::Service; -use actix_web::test::TestRequest; -use actix_web::{test, App}; -use function_name::named; - -use super::configure_test_app; - -#[named] -#[actix_rt::test] -async fn test_index() { - let app = App::new().configure(|cfg| configure_test_app(cfg, function_name!())); - let mut service = test::init_service(app).await; - let req = TestRequest::get().uri("/").to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); -} diff --git a/src/service/mod.rs b/src/service/mod.rs index 6be9bb4..0896149 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -2,6 +2,9 @@ mod constants; mod dto; mod error; +#[cfg(test)] +mod tests; + #[cfg(feature = "service-actix")] mod actix; #[cfg(feature = "service-actix")] diff --git a/src/service/rocket/api_tests.rs b/src/service/rocket/api_tests.rs index 52914c5..5fdf362 100644 --- a/src/service/rocket/api_tests.rs +++ b/src/service/rocket/api_tests.rs @@ -8,7 +8,6 @@ use super::api; use crate::config; use crate::ddns; use crate::index; -use crate::service::dto; use crate::vfs; use super::test::get_test_environment; @@ -49,53 +48,6 @@ fn do_auth(client: &Client) { assert_eq!(response.status(), Status::Ok); } -#[test] -fn version() { - let env = get_test_environment("api_version.sqlite"); - let client = &env.client; - let mut response = client.get("/api/version").dispatch(); - - assert_eq!(response.status(), Status::Ok); - - let response_body = response.body_string().unwrap(); - let response_json: dto::Version = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json, dto::Version { major: 4, minor: 0 }); -} - -#[test] -fn initial_setup() { - let env = get_test_environment("api_initial_setup.sqlite"); - let client = &env.client; - - { - let mut response = client.get("/api/initial_setup").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: dto::InitialSetup = serde_json::from_str(&response_body).unwrap(); - assert_eq!( - response_json, - dto::InitialSetup { - has_any_users: false - } - ); - } - - complete_initial_setup(client); - - { - let mut response = client.get("/api/initial_setup").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: dto::InitialSetup = serde_json::from_str(&response_body).unwrap(); - assert_eq!( - response_json, - dto::InitialSetup { - has_any_users: true - } - ); - } -} - #[test] fn settings() { let env = get_test_environment("api_settings.sqlite"); diff --git a/src/service/rocket/mod.rs b/src/service/rocket/mod.rs index d335ee8..00ea1d8 100644 --- a/src/service/rocket/mod.rs +++ b/src/service/rocket/mod.rs @@ -6,8 +6,4 @@ pub mod server; #[cfg(test)] mod api_tests; #[cfg(test)] -mod swagger; -#[cfg(test)] -mod test; -#[cfg(test)] -mod web; +pub mod test; diff --git a/src/service/rocket/swagger.rs b/src/service/rocket/swagger.rs deleted file mode 100644 index 6eeafe5..0000000 --- a/src/service/rocket/swagger.rs +++ /dev/null @@ -1,19 +0,0 @@ -use super::test::get_test_environment; - -#[test] -fn test_index() { - use rocket::http::Status; - let env = get_test_environment("swagger_index.sqlite"); - let client = &env.client; - let response = client.get("/swagger").dispatch(); - assert_eq!(response.status(), Status::Ok); -} - -#[test] -fn test_index_with_trailing_slash() { - use rocket::http::Status; - let env = get_test_environment("swagger_index_with_trailing_slash.sqlite"); - let client = &env.client; - let response = client.get("/swagger/").dispatch(); - assert_eq!(response.status(), Status::Ok); -} diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index a0072f8..f72022b 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -1,5 +1,8 @@ use rocket; +use rocket::http::Status; use rocket::local::Client; +use serde::de::DeserializeOwned; +use serde::Serialize; use std::fs; use std::ops::Deref; use std::path::PathBuf; @@ -60,3 +63,30 @@ pub fn get_test_environment(db_name: &str) -> TestEnvironment { db, } } + +pub type ServiceType = TestEnvironment; + +pub async fn make_service(test_name: &str) -> TestEnvironment { + get_test_environment(&format!("{}.sqlite", test_name)) +} + +pub async fn get(service: &mut TestEnvironment, url: &str) { + let client = &service.client; + let response = client.get(url).dispatch(); + assert_eq!(response.status(), Status::Ok); +} + +pub async fn get_json(service: &mut TestEnvironment, url: &str) -> T { + let client = &service.client; + let mut response = client.get(url).dispatch(); + assert_eq!(response.status(), Status::Ok); + let response_body = response.body_string().unwrap(); + serde_json::from_str(&response_body).unwrap() +} + +pub async fn put_json(service: &mut TestEnvironment, url: &str, payload: &T) { + let client = &service.client; + let body = serde_json::to_string(payload).unwrap(); + let response = client.put(url).body(&body).dispatch(); + assert_eq!(response.status(), Status::Ok); +} diff --git a/src/service/rocket/web.rs b/src/service/rocket/web.rs deleted file mode 100644 index a9a46cf..0000000 --- a/src/service/rocket/web.rs +++ /dev/null @@ -1,10 +0,0 @@ -use super::test::get_test_environment; -use rocket::http::Status; - -#[test] -fn test_index() { - let env = get_test_environment("web_index.sqlite"); - let client = &env.client; - let response = client.get("/").dispatch(); - assert_eq!(response.status(), Status::Ok); -} diff --git a/src/service/tests.rs b/src/service/tests.rs new file mode 100644 index 0000000..8f4ccb0 --- /dev/null +++ b/src/service/tests.rs @@ -0,0 +1,95 @@ +use function_name::named; + +mod api; +mod static_files; + +use crate::config; +use crate::service::dto; +use crate::vfs; + +#[cfg(feature = "service-actix")] +pub use crate::service::actix::test::*; + +#[cfg(feature = "service-rocket")] +pub use crate::service::rocket::test::*; + +const TEST_USERNAME: &str = "test_user"; +const TEST_PASSWORD: &str = "test_password"; +const TEST_MOUNT_NAME: &str = "collection"; +const TEST_MOUNT_SOURCE: &str = "test/collection"; + +#[named] +#[actix_rt::test] +async fn test_index() { + let mut service = make_service(function_name!()).await; + get(&mut service, "/").await; +} + +#[named] +#[actix_rt::test] +async fn test_swagger_index() { + let mut service = make_service(function_name!()).await; + get(&mut service, "/swagger").await; +} + +#[named] +#[actix_rt::test] +async fn test_swagger_index_with_trailing_slash() { + let mut service = make_service(function_name!()).await; + get(&mut service, "/swagger/").await; +} + +async fn complete_initial_setup(service: &mut ServiceType) { + let configuration = config::Config { + album_art_pattern: None, + prefix_url: None, + reindex_every_n_seconds: None, + ydns: None, + users: Some(vec![config::ConfigUser { + name: TEST_USERNAME.into(), + password: TEST_PASSWORD.into(), + admin: true, + }]), + mount_dirs: Some(vec![vfs::MountPoint { + name: TEST_MOUNT_NAME.into(), + source: TEST_MOUNT_SOURCE.into(), + }]), + }; + put_json(service, "/api/settings", &configuration).await; +} + +#[named] +#[actix_rt::test] +async fn test_version() { + let mut service = make_service(function_name!()).await; + let version: dto::Version = get_json(&mut service, "/api/version").await; + assert_eq!(version, dto::Version { major: 4, minor: 0 }); +} + +#[named] +#[actix_rt::test] +async fn test_initial_setup() { + let mut service = make_service(function_name!()).await; + + { + let initial_setup: dto::InitialSetup = get_json(&mut service, "/api/initial_setup").await; + assert_eq!( + initial_setup, + dto::InitialSetup { + has_any_users: false + } + ); + } + + complete_initial_setup(&mut service).await; + + { + let initial_setup: dto::InitialSetup = get_json(&mut service, "/api/initial_setup").await; + assert_eq!( + initial_setup, + dto::InitialSetup { + has_any_users: true + } + ); + } +} From 1c84cde1584118a3a991108c414e41c06f266aaf Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 00:35:30 -0800 Subject: [PATCH 09/32] Fixed compile error --- src/service/tests.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/service/tests.rs b/src/service/tests.rs index 8f4ccb0..53d4583 100644 --- a/src/service/tests.rs +++ b/src/service/tests.rs @@ -1,8 +1,5 @@ use function_name::named; -mod api; -mod static_files; - use crate::config; use crate::service::dto; use crate::vfs; From 289827d6a399e42521a8062dc78f87abc2d3ed3c Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 00:41:26 -0800 Subject: [PATCH 10/32] Explicitely start async executor --- src/main.rs | 26 ++++++++++++++------------ src/service/actix/server.rs | 12 +++++++----- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index cb02cf8..b0487c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -217,18 +217,20 @@ fn main() -> Result<()> { .unwrap_or_else(|| "5050".to_owned()) .parse() .with_context(|| "Invalid port number")?; - - service::server::run( - port, - Some(auth_secret.as_slice()), - api_url, - web_url, - web_dir_path, - swagger_url, - swagger_dir_path, - db.clone(), - command_sender, - )?; + let db_server = db.clone(); + std::thread::spawn(move || { + let _ = service::server::run( + port, + Some(auth_secret.as_slice()), + api_url, + web_url, + web_dir_path, + swagger_url, + swagger_dir_path, + db_server, + command_sender, + ); + }); // Start DDNS updates let db_ddns = db.clone(); diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs index 2dcc699..58f457c 100644 --- a/src/service/actix/server.rs +++ b/src/service/actix/server.rs @@ -1,3 +1,4 @@ +use actix_rt::System; use actix_web::{App, HttpServer}; use anyhow::*; use std::path::PathBuf; @@ -6,8 +7,7 @@ use std::sync::Arc; use crate::db::DB; use crate::index::CommandSender; -#[actix_rt::main] -pub async fn run( +pub fn run( port: u16, auth_secret: Option<&[u8]>, api_url: String, @@ -18,7 +18,9 @@ pub async fn run( db: DB, command_sender: Arc, ) -> Result<()> { - HttpServer::new(move || { + let mut sys = System::new("polaris_service_executor"); + + let server = HttpServer::new(move || { App::new().configure(|cfg| { super::configure_app( cfg, @@ -30,8 +32,8 @@ pub async fn run( ) }) }) - .bind(format!("127.0.0.1:{}", port))? + .bind(format!("0.0.0.0:{}", port))? .run(); - Ok(()) + sys.block_on(server).map_err(Error::new) } From 4194509f45863c46c59c1674f13700b28708fce4 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 01:03:39 -0800 Subject: [PATCH 11/32] Use tokio runtime for tests and actix version --- Cargo.lock | 14 +++++++++++++- Cargo.toml | 9 ++++++--- src/service/actix/server.rs | 7 ++++--- src/service/tests.rs | 10 +++++----- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb80aa3..6f6f104 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,7 +2071,6 @@ dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2101,6 +2100,7 @@ dependencies = [ "simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2998,9 +2998,11 @@ dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3042,6 +3044,15 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-reactor" version = "0.1.11" @@ -3783,6 +3794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" +"checksum tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "50a61f268a3db2acee8dcab514efc813dc6dbe8a00e86076f935f94304b59a7a" "checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" diff --git a/Cargo.toml b/Cargo.toml index c0a2f44..458e7cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,18 +8,17 @@ edition = "2018" default = ["service-actix"] ui = [] profile-index = ["flame", "flamer"] -service-actix = ["actix-files", "actix-http", "actix-web"] +service-actix = ["actix-files", "actix-http", "actix-rt", "actix-web"] service-rocket = ["rocket", "rocket_contrib"] [dependencies] actix-files = { version = "0.2", optional = true } actix-http = { version = "1.0", optional = true } actix-web = { version = "2.0", optional = true } -actix-rt = { version = "1.0"} +actix-rt = { version = "1.0", optional = true} anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" -async-trait = "0.1.22" base64 = "0.11.0" diesel = { version = "1.4", features = ["sqlite", "r2d2"] } diesel_migrations = { version = "1.4", features = ["sqlite"] } @@ -55,6 +54,10 @@ default_features = false features = ["json", "serve"] optional = true +[dependencies.tokio] +version = "0.2" +features = ["macros", "rt-threaded"] + [target.'cfg(windows)'.dependencies] uuid = "0.8" diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs index 58f457c..fc1ed5d 100644 --- a/src/service/actix/server.rs +++ b/src/service/actix/server.rs @@ -1,4 +1,3 @@ -use actix_rt::System; use actix_web::{App, HttpServer}; use anyhow::*; use std::path::PathBuf; @@ -18,7 +17,9 @@ pub fn run( db: DB, command_sender: Arc, ) -> Result<()> { - let mut sys = System::new("polaris_service_executor"); + let mut runtime = tokio::runtime::Runtime::new()?; + let local_set = tokio::task::LocalSet::new(); + let _ = actix_rt::System::run_in_tokio("polaris_service_executor", &local_set); let server = HttpServer::new(move || { App::new().configure(|cfg| { @@ -35,5 +36,5 @@ pub fn run( .bind(format!("0.0.0.0:{}", port))? .run(); - sys.block_on(server).map_err(Error::new) + runtime.block_on(server).map_err(Error::new) } diff --git a/src/service/tests.rs b/src/service/tests.rs index 53d4583..9e5357e 100644 --- a/src/service/tests.rs +++ b/src/service/tests.rs @@ -16,21 +16,21 @@ const TEST_MOUNT_NAME: &str = "collection"; const TEST_MOUNT_SOURCE: &str = "test/collection"; #[named] -#[actix_rt::test] +#[tokio::test] async fn test_index() { let mut service = make_service(function_name!()).await; get(&mut service, "/").await; } #[named] -#[actix_rt::test] +#[tokio::test] async fn test_swagger_index() { let mut service = make_service(function_name!()).await; get(&mut service, "/swagger").await; } #[named] -#[actix_rt::test] +#[tokio::test] async fn test_swagger_index_with_trailing_slash() { let mut service = make_service(function_name!()).await; get(&mut service, "/swagger/").await; @@ -56,7 +56,7 @@ async fn complete_initial_setup(service: &mut ServiceType) { } #[named] -#[actix_rt::test] +#[tokio::test] async fn test_version() { let mut service = make_service(function_name!()).await; let version: dto::Version = get_json(&mut service, "/api/version").await; @@ -64,7 +64,7 @@ async fn test_version() { } #[named] -#[actix_rt::test] +#[tokio::test] async fn test_initial_setup() { let mut service = make_service(function_name!()).await; From f7efeef6538e16a5944fc94097232039fc22cdf7 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 01:22:13 -0800 Subject: [PATCH 12/32] Added doc reference --- src/service/actix/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/actix/api.rs b/src/service/actix/api.rs index f7d5b32..5ae80c4 100644 --- a/src/service/actix/api.rs +++ b/src/service/actix/api.rs @@ -46,7 +46,7 @@ pub async fn get_initial_setup(db: web::Data) -> Result, - // _admin_rights: AdminRights, // TODO.important + // _admin_rights: AdminRights, // TODO.important https://docs.rs/actix-web/2.0.0/actix_web/trait.FromRequest.html config: web::Json, ) -> Result { web::block(move || config::amend(&db, &config)) From 6f642c34e2d1154f279b6846e3f859033e25b0ce Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 01:58:51 -0800 Subject: [PATCH 13/32] Non-optional auth secret --- src/main.rs | 2 +- src/service/actix/server.rs | 2 +- src/service/rocket/server.rs | 10 ++++------ src/service/rocket/test.rs | 4 +++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index b0487c3..30c763c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -221,7 +221,7 @@ fn main() -> Result<()> { std::thread::spawn(move || { let _ = service::server::run( port, - Some(auth_secret.as_slice()), + &auth_secret, api_url, web_url, web_dir_path, diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs index fc1ed5d..29ebf48 100644 --- a/src/service/actix/server.rs +++ b/src/service/actix/server.rs @@ -8,7 +8,7 @@ use crate::index::CommandSender; pub fn run( port: u16, - auth_secret: Option<&[u8]>, + auth_secret: &[u8], api_url: String, web_url: String, web_dir_path: PathBuf, diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index 84fca9d..db44396 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -11,7 +11,7 @@ use crate::index::CommandSender; pub fn get_server( port: u16, - auth_secret: Option<&[u8]>, + auth_secret: &[u8], api_url: &str, web_url: &str, web_dir_path: &PathBuf, @@ -26,10 +26,8 @@ pub fn get_server( .keep_alive(0) .finalize()?; - if let Some(secret) = auth_secret { - let encoded = base64::encode(secret); - config.set_secret_key(encoded)?; - } + let encoded = base64::encode(auth_secret); + config.set_secret_key(encoded)?; let swagger_routes_rank = 0; let web_routes_rank = swagger_routes_rank + 1; @@ -50,7 +48,7 @@ pub fn get_server( pub fn run( port: u16, - auth_secret: Option<&[u8]>, + auth_secret: &[u8], api_url: String, web_url: String, web_dir_path: PathBuf, diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index f72022b..f1de84a 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -44,9 +44,11 @@ pub fn get_test_environment(db_name: &str) -> TestEnvironment { swagger_dir_path.push("swagger"); let command_sender = index::init(db.clone()); + let auth_secret: [u8; 32] = [0; 32]; + let server = server::get_server( 5050, - None, + &auth_secret, "/api", "/", &web_dir_path, From 0dba7e2e4f2c0897e83ebb22104ba05cdb140634 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 23:37:36 -0800 Subject: [PATCH 14/32] Removed actix --- Cargo.lock | 800 ------------------------------------ Cargo.toml | 7 +- src/service/actix/api.rs | 56 --- src/service/actix/mod.rs | 31 -- src/service/actix/server.rs | 40 -- src/service/actix/test.rs | 84 ---- 6 files changed, 1 insertion(+), 1017 deletions(-) delete mode 100644 src/service/actix/api.rs delete mode 100644 src/service/actix/mod.rs delete mode 100644 src/service/actix/server.rs delete mode 100644 src/service/actix/test.rs diff --git a/Cargo.lock b/Cargo.lock index 6f6f104..ac06477 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,267 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "actix-codec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-connect" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-files" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "v_htmlescape 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-http" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-connect 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-router" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytestring 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-rt" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-server" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-service" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-testing" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-threadpool" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-utils" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-web" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-testing 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-web-codegen" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "adler32" version = "1.0.4" @@ -299,11 +37,6 @@ dependencies = [ "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "arc-swap" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "arrayref" version = "0.3.5" @@ -314,16 +47,6 @@ name = "arrayvec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "async-trait" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "atty" version = "0.2.13" @@ -338,28 +61,6 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "awc" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "backtrace" version = "0.3.40" @@ -436,24 +137,6 @@ dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "byte-tools" version = "0.3.1" @@ -479,14 +162,6 @@ name = "bytes" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bytestring" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "c2-chacha" version = "0.2.3" @@ -570,11 +245,6 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "copyless" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "core-foundation" version = "0.6.4" @@ -727,16 +397,6 @@ dependencies = [ "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "derive_more" -version = "0.99.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "devise" version = "0.2.0" @@ -899,17 +559,6 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "enum-as-inner" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "error-chain" version = "0.12.1" @@ -1064,34 +713,6 @@ name = "futures" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "futures" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-channel" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "futures-cpupool" version = "0.1.8" @@ -1101,68 +722,6 @@ dependencies = [ "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "futures-executor" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-io" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-macro" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-sink" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-task" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "gcc" version = "0.3.55" @@ -1220,32 +779,6 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "h2" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hermit-abi" version = "0.1.5" @@ -1268,15 +801,6 @@ dependencies = [ "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hostname" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "http" version = "0.1.21" @@ -1287,16 +811,6 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "http" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "http-body" version = "0.1.0" @@ -1469,17 +983,6 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ipconfig" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.4.4" @@ -1548,11 +1051,6 @@ dependencies = [ "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "linked-hash-map" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lock_api" version = "0.3.2" @@ -1577,14 +1075,6 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lzw" version = "0.10.0" @@ -1702,16 +1192,6 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "mio-uds" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "miow" version = "0.2.1" @@ -1758,15 +1238,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "notify" version = "4.0.14" @@ -2016,34 +1487,11 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "pin-project" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pin-project-lite" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "pin-utils" -version = "0.1.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "pkg-config" version = "0.3.17" @@ -2064,10 +1512,6 @@ dependencies = [ name = "polaris" version = "0.11.0" dependencies = [ - "actix-files 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2120,21 +1564,6 @@ dependencies = [ "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-nested" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "proc-macro2" version = "0.4.30" @@ -2163,11 +1592,6 @@ dependencies = [ "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.3.15" @@ -2468,15 +1892,6 @@ dependencies = [ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "resolv-conf" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ring" version = "0.13.5" @@ -2723,22 +2138,6 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "serde_urlencoded" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "sha2" version = "0.8.0" @@ -2759,15 +2158,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "signal-hook-registry" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "simplelog" version = "0.7.4" @@ -2796,17 +2186,6 @@ name = "smallvec" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "socket2" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "state" version = "0.4.1" @@ -2937,14 +2316,6 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "threadpool" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tiff" version = "0.3.1" @@ -2990,20 +2361,9 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3120,19 +2480,6 @@ dependencies = [ "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-util" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml" version = "0.4.10" @@ -3154,43 +2501,6 @@ name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "trust-dns-proto" -version = "0.18.0-alpha.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.18.0-alpha.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "try-lock" version = "0.2.2" @@ -3246,11 +2556,6 @@ dependencies = [ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "unicode-segmentation" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-width" version = "0.1.7" @@ -3317,34 +2622,6 @@ name = "uuid" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "v_escape" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "v_escape_derive 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "v_escape_derive" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "v_htmlescape" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "v_escape 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "vcpkg" version = "0.2.8" @@ -3385,11 +2662,6 @@ name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "widestring" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "winapi" version = "0.2.8" @@ -3435,14 +2707,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "winutil" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wrapped-vec" version = "0.2.1" @@ -3477,33 +2741,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" -"checksum actix-connect 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2b61480a8d30c94d5c883d79ef026b02ad6809931b0a4bb703f9545cd8c986" -"checksum actix-files 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "301482841d3d74483a446ead63cb7d362e187d2c8b603f13d91995621ea53c46" -"checksum actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" -"checksum actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" -"checksum actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" -"checksum actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6a0a55507046441a496b2f0d26a84a65e67c8cafffe279072412f624b5fb6d" -"checksum actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51d3455eaac03ca3e49d7b822eb35c884b861f715627254ccbe4309d08f1841a" -"checksum actix-service 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9fba4171f1952aa15f3cf410facac388d18110b1e8754f84a407ab7f9d5ac7ee" -"checksum actix-testing 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48494745b72d0ea8ff0cf874aaf9b622a3ee03d7081ee0c04edea4f26d32c911" -"checksum actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4082192601de5f303013709ff84d81ca6a1bc4af7fb24f367a500a23c6e84e" -"checksum actix-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8" -"checksum actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" -"checksum actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635" -"checksum actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de0878b30e62623770a4713a6338329fd0119703bafc211d3e4144f4d4a7bdd5" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "890eeb3dc52632a4b762e3ea6ac37475a35577f22fce09bb6e758c2aaf38a229" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" -"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" @@ -3513,13 +2759,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -"checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -"checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" -"checksum bytestring 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b24c107a4432e408d2caa58d3f5e763b219236221406ea58a4076b62343a039d" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" @@ -3530,7 +2773,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cookie 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99be24cfcf40d56ed37fd11c2123be833959bbc5bddecb46e1c2e442e15fa3e0" "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" "checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" -"checksum copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" @@ -3547,7 +2789,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" "checksum derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4" "checksum derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37" -"checksum derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" "checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" "checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" "checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" @@ -3567,7 +2808,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" -"checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -3587,31 +2827,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum function_name 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88b2afa9b514dc3a75af6cf24d1914e1c7eb6f1b86de849147563548d5c0a0cd" "checksum function_name-proc-macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6790a8d356d2f65d7972181e866b92a50a87c27d6a48cbe9dbb8be13ca784c7d" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" -"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" "checksum gif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -"checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" @@ -3627,7 +2853,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jpeg-decoder 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -3638,11 +2863,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lewton 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8d542c1a317036c45c2aa1cf10cc9d403ca91eb2d333ef1a4917e5cb10628bd0" "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5b95e89c330291768dc840238db7f9e204fd208511ab6319b56193a7f2ae25" -"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" @@ -3657,12 +2880,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mp3-duration 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7cc3eebd1d49a86505733254d1dfd53fbefe4ab65d86afd6f84d3245cd604f" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b" "checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" "checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" @@ -3688,20 +2909,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" -"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" "checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum png 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "247cb804bd7fc86d0c2b153d1374265e67945875720136ca8fe451f11c6aed52" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" @@ -3732,7 +2947,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" -"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" "checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" "checksum rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7" "checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4" @@ -3760,16 +2974,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" -"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" -"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "05a3e303ace6adb0a60a9e9e2fbc6a33e1749d1e43587e2125f7efa9c5e107c5" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" -"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" @@ -3785,7 +2995,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef" "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" @@ -3800,12 +3009,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" "checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" -"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" -"checksum trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" @@ -3814,7 +3020,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" -"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" @@ -3825,16 +3030,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" -"checksum v_escape 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6" -"checksum v_escape_derive 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae" -"checksum v_htmlescape 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -3842,7 +3043,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum wrapped-vec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "06c29bb4abe93d1c8ef79b60f270d0efcaa6c5c97aaaaaaa0d477ea72f5f9e45" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/Cargo.toml b/Cargo.toml index 458e7cc..df7d6a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,17 +5,12 @@ authors = ["Antoine Gersant "] edition = "2018" [features] -default = ["service-actix"] +default = ["service-rocket"] ui = [] profile-index = ["flame", "flamer"] -service-actix = ["actix-files", "actix-http", "actix-rt", "actix-web"] service-rocket = ["rocket", "rocket_contrib"] [dependencies] -actix-files = { version = "0.2", optional = true } -actix-http = { version = "1.0", optional = true } -actix-web = { version = "2.0", optional = true } -actix-rt = { version = "1.0", optional = true} anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" diff --git a/src/service/actix/api.rs b/src/service/actix/api.rs deleted file mode 100644 index 5ae80c4..0000000 --- a/src/service/actix/api.rs +++ /dev/null @@ -1,56 +0,0 @@ -use actix_http::ResponseBuilder; -use actix_web::{error, get, http::header, http::StatusCode, put, web, HttpResponse}; -use anyhow::*; - -use crate::config::{self, Config}; -use crate::db::DB; -use crate::service::constants::*; -use crate::service::dto; -use crate::service::error::APIError; -use crate::user; - -impl error::ResponseError for APIError { - fn error_response(&self) -> HttpResponse { - ResponseBuilder::new(self.status_code()) - .set_header(header::CONTENT_TYPE, "text/html; charset=utf-8") - .body(self.to_string()) - } - fn status_code(&self) -> StatusCode { - match *self { - APIError::IncorrectCredentials => StatusCode::UNAUTHORIZED, - APIError::Unspecified => StatusCode::INTERNAL_SERVER_ERROR, - } - } -} - -#[get("/version")] -pub async fn get_version() -> Result { - let current_version = dto::Version { - major: CURRENT_MAJOR_VERSION, - minor: CURRENT_MINOR_VERSION, - }; - Ok(HttpResponse::Ok().json(current_version)) -} - -#[get("/initial_setup")] -pub async fn get_initial_setup(db: web::Data) -> Result { - let user_count = web::block(move || user::count(&db)) - .await - .map_err(|_| anyhow!("Could not count users"))?; - let initial_setup = dto::InitialSetup { - has_any_users: user_count > 0, - }; - Ok(HttpResponse::Ok().json(initial_setup)) -} - -#[put("/settings")] -pub async fn put_settings( - db: web::Data, - // _admin_rights: AdminRights, // TODO.important https://docs.rs/actix-web/2.0.0/actix_web/trait.FromRequest.html - config: web::Json, -) -> Result { - web::block(move || config::amend(&db, &config)) - .await - .map_err(|_| anyhow!("Could not amend config"))?; - Ok(HttpResponse::Ok().finish()) -} diff --git a/src/service/actix/mod.rs b/src/service/actix/mod.rs deleted file mode 100644 index d2e41f7..0000000 --- a/src/service/actix/mod.rs +++ /dev/null @@ -1,31 +0,0 @@ -use actix_files as fs; -use actix_web::web; -use std::path::Path; - -use crate::db::DB; - -pub mod server; - -mod api; -#[cfg(test)] -pub mod test; - -fn configure_app( - cfg: &mut web::ServiceConfig, - web_url: &str, - web_dir_path: &Path, - swagger_url: &str, - swagger_dir_path: &Path, - db: &DB, -) { - // TODO logging - cfg.data(db.clone()) - .service( - web::scope("/api") - .service(api::get_initial_setup) - .service(api::get_version) - .service(api::put_settings), - ) - .service(fs::Files::new(swagger_url, swagger_dir_path).index_file("index.html")) - .service(fs::Files::new(web_url, web_dir_path).index_file("index.html")); -} diff --git a/src/service/actix/server.rs b/src/service/actix/server.rs deleted file mode 100644 index 29ebf48..0000000 --- a/src/service/actix/server.rs +++ /dev/null @@ -1,40 +0,0 @@ -use actix_web::{App, HttpServer}; -use anyhow::*; -use std::path::PathBuf; -use std::sync::Arc; - -use crate::db::DB; -use crate::index::CommandSender; - -pub fn run( - port: u16, - auth_secret: &[u8], - api_url: String, - web_url: String, - web_dir_path: PathBuf, - swagger_url: String, - swagger_dir_path: PathBuf, - db: DB, - command_sender: Arc, -) -> Result<()> { - let mut runtime = tokio::runtime::Runtime::new()?; - let local_set = tokio::task::LocalSet::new(); - let _ = actix_rt::System::run_in_tokio("polaris_service_executor", &local_set); - - let server = HttpServer::new(move || { - App::new().configure(|cfg| { - super::configure_app( - cfg, - &web_url, - web_dir_path.as_path(), - &swagger_url, - swagger_dir_path.as_path(), - &db, - ) - }) - }) - .bind(format!("0.0.0.0:{}", port))? - .run(); - - runtime.block_on(server).map_err(Error::new) -} diff --git a/src/service/actix/test.rs b/src/service/actix/test.rs deleted file mode 100644 index a140bec..0000000 --- a/src/service/actix/test.rs +++ /dev/null @@ -1,84 +0,0 @@ -use actix_http::{Error, Request}; -use actix_web::dev::{Body, ResponseBody, Service, ServiceResponse}; -use actix_web::test::TestRequest; -use actix_web::{test, App}; -use serde::de::DeserializeOwned; -use serde::Serialize; -use std::fs; -use std::path::PathBuf; - -use crate::db::DB; - -fn configure_test_app(cfg: &mut actix_web::web::ServiceConfig, db_name: &str) { - let web_url = "/"; - let web_dir_path = PathBuf::from("web"); - - let swagger_url = "swagger"; - let mut swagger_dir_path = PathBuf::from("docs"); - swagger_dir_path.push("swagger"); - - let mut db_path = PathBuf::new(); - db_path.push("test"); - db_path.push(format!("{}.sqlite", db_name)); - if db_path.exists() { - fs::remove_file(&db_path).unwrap(); - } - let db = DB::new(&db_path).unwrap(); - - super::configure_app( - cfg, - web_url, - web_dir_path.as_path(), - swagger_url, - swagger_dir_path.as_path(), - &db, - ); -} - -pub type ServiceType = impl Service; - -pub async fn make_service(test_name: &str) -> ServiceType { - let app = App::new().configure(|cfg| configure_test_app(cfg, test_name)); - let service = test::init_service(app).await; - service -} - -pub async fn get(service: &mut ServiceType, url: &str) { - let req = TestRequest::get().uri(url).to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); -} - -pub async fn get_json(service: &mut ServiceType, url: &str) -> T { - let req = TestRequest::get().uri(url).to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); - let body = resp.response().body().as_u8(); - let response_json: T = serde_json::from_slice(body).unwrap(); - response_json -} - -pub async fn put_json(service: &mut ServiceType, url: &str, payload: &T) { - let req = TestRequest::put().uri(url).set_json(payload).to_request(); - let resp = service.call(req).await.unwrap(); - assert!(resp.status().is_success()); -} - -trait BodyToBytes { - fn as_u8(&self) -> &[u8]; -} - -impl BodyToBytes for ResponseBody { - fn as_u8(&self) -> &[u8] { - match self { - ResponseBody::Body(ref b) => match b { - Body::Bytes(ref by) => by.as_ref(), - _ => panic!(), - }, - ResponseBody::Other(ref b) => match b { - Body::Bytes(ref by) => by.as_ref(), - _ => panic!(), - }, - } - } -} From acffa576e21e8338d5aaa25eba713143429cd39f Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 23:38:10 -0800 Subject: [PATCH 15/32] Removed more actix --- src/service/mod.rs | 5 ----- src/service/tests.rs | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/service/mod.rs b/src/service/mod.rs index 0896149..176de4f 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -5,11 +5,6 @@ mod error; #[cfg(test)] mod tests; -#[cfg(feature = "service-actix")] -mod actix; -#[cfg(feature = "service-actix")] -pub use self::actix::*; - #[cfg(feature = "service-rocket")] mod rocket; #[cfg(feature = "service-rocket")] diff --git a/src/service/tests.rs b/src/service/tests.rs index 9e5357e..9083443 100644 --- a/src/service/tests.rs +++ b/src/service/tests.rs @@ -4,9 +4,6 @@ use crate::config; use crate::service::dto; use crate::vfs; -#[cfg(feature = "service-actix")] -pub use crate::service::actix::test::*; - #[cfg(feature = "service-rocket")] pub use crate::service::rocket::test::*; From 76118756b92f0d7d51975802833fe257bd79c40f Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 23:38:46 -0800 Subject: [PATCH 16/32] Constant rename --- src/service/constants.rs | 4 ++-- src/service/rocket/api.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/service/constants.rs b/src/service/constants.rs index e222d58..a36931c 100644 --- a/src/service/constants.rs +++ b/src/service/constants.rs @@ -1,5 +1,5 @@ -pub const CURRENT_MAJOR_VERSION: i32 = 4; -pub const CURRENT_MINOR_VERSION: i32 = 0; +pub const API_MAJOR_VERSION: i32 = 4; +pub const API_MINOR_VERSION: i32 = 0; pub const COOKIE_SESSION: &str = "session"; pub const COOKIE_USERNAME: &str = "username"; pub const COOKIE_ADMIN: &str = "admin"; diff --git a/src/service/rocket/api.rs b/src/service/rocket/api.rs index a61e088..6e2281c 100644 --- a/src/service/rocket/api.rs +++ b/src/service/rocket/api.rs @@ -192,8 +192,8 @@ impl From for PathBuf { #[get("/version")] fn version() -> Json { let current_version = dto::Version { - major: CURRENT_MAJOR_VERSION, - minor: CURRENT_MINOR_VERSION, + major: API_MAJOR_VERSION, + minor: API_MINOR_VERSION, }; Json(current_version) } From 9ed0526075f34ec33a6ff0f82ae9107620f0d160 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Thu, 16 Jan 2020 23:40:10 -0800 Subject: [PATCH 17/32] Remobed blanket import --- src/service/tests.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/service/tests.rs b/src/service/tests.rs index 9083443..05889b2 100644 --- a/src/service/tests.rs +++ b/src/service/tests.rs @@ -5,7 +5,7 @@ use crate::service::dto; use crate::vfs; #[cfg(feature = "service-rocket")] -pub use crate::service::rocket::test::*; +pub use crate::service::rocket::test; const TEST_USERNAME: &str = "test_user"; const TEST_PASSWORD: &str = "test_password"; @@ -15,25 +15,25 @@ const TEST_MOUNT_SOURCE: &str = "test/collection"; #[named] #[tokio::test] async fn test_index() { - let mut service = make_service(function_name!()).await; - get(&mut service, "/").await; + let mut service = test::make_service(function_name!()).await; + test::get(&mut service, "/").await; } #[named] #[tokio::test] async fn test_swagger_index() { - let mut service = make_service(function_name!()).await; - get(&mut service, "/swagger").await; + let mut service = test::make_service(function_name!()).await; + test::get(&mut service, "/swagger").await; } #[named] #[tokio::test] async fn test_swagger_index_with_trailing_slash() { - let mut service = make_service(function_name!()).await; - get(&mut service, "/swagger/").await; + let mut service = test::make_service(function_name!()).await; + test::get(&mut service, "/swagger/").await; } -async fn complete_initial_setup(service: &mut ServiceType) { +async fn complete_initial_setup(service: &mut test::ServiceType) { let configuration = config::Config { album_art_pattern: None, prefix_url: None, @@ -49,24 +49,25 @@ async fn complete_initial_setup(service: &mut ServiceType) { source: TEST_MOUNT_SOURCE.into(), }]), }; - put_json(service, "/api/settings", &configuration).await; + test::put_json(service, "/api/settings", &configuration).await; } #[named] #[tokio::test] async fn test_version() { - let mut service = make_service(function_name!()).await; - let version: dto::Version = get_json(&mut service, "/api/version").await; + let mut service = test::make_service(function_name!()).await; + let version: dto::Version = test::get_json(&mut service, "/api/version").await; assert_eq!(version, dto::Version { major: 4, minor: 0 }); } #[named] #[tokio::test] async fn test_initial_setup() { - let mut service = make_service(function_name!()).await; + let mut service = test::make_service(function_name!()).await; { - let initial_setup: dto::InitialSetup = get_json(&mut service, "/api/initial_setup").await; + let initial_setup: dto::InitialSetup = + test::get_json(&mut service, "/api/initial_setup").await; assert_eq!( initial_setup, dto::InitialSetup { @@ -78,7 +79,8 @@ async fn test_initial_setup() { complete_initial_setup(&mut service).await; { - let initial_setup: dto::InitialSetup = get_json(&mut service, "/api/initial_setup").await; + let initial_setup: dto::InitialSetup = + test::get_json(&mut service, "/api/initial_setup").await; assert_eq!( initial_setup, dto::InitialSetup { From ed66200689d80041bb7057e717c36a97d79a05b9 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 01:17:23 -0800 Subject: [PATCH 18/32] Decoupled most tests from rocket --- Cargo.lock | 1 + Cargo.toml | 1 + src/service/dto.rs | 16 ++ src/service/mod.rs | 2 +- src/service/rocket/api.rs | 32 +-- src/service/rocket/api_tests.rs | 479 -------------------------------- src/service/rocket/mod.rs | 2 - src/service/rocket/test.rs | 163 ++++++----- src/service/test.rs | 416 +++++++++++++++++++++++++++ src/service/tests.rs | 91 ------ 10 files changed, 533 insertions(+), 670 deletions(-) delete mode 100644 src/service/rocket/api_tests.rs create mode 100644 src/service/test.rs delete mode 100644 src/service/tests.rs diff --git a/Cargo.lock b/Cargo.lock index ac06477..ecd67e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1547,6 +1547,7 @@ dependencies = [ "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index df7d6a3..55bca09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ simplelog = "0.7" thiserror = "1.0" time = "0.1" toml = "0.5" +url = "2.1" [dependencies.rocket_contrib] version = "0.4.2" diff --git a/src/service/dto.rs b/src/service/dto.rs index fb31e5c..124e6c7 100644 --- a/src/service/dto.rs +++ b/src/service/dto.rs @@ -10,3 +10,19 @@ pub struct Version { pub struct InitialSetup { pub has_any_users: bool, } + +#[derive(Serialize, Deserialize)] +pub struct AuthCredentials { + pub username: String, + pub password: String, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct ListPlaylistsEntry { + pub name: String, +} + +#[derive(Serialize, Deserialize)] +pub struct SavePlaylistInput { + pub tracks: Vec, +} diff --git a/src/service/mod.rs b/src/service/mod.rs index 176de4f..e975016 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -3,7 +3,7 @@ mod dto; mod error; #[cfg(test)] -mod tests; +mod test; #[cfg(feature = "service-rocket")] mod rocket; diff --git a/src/service/rocket/api.rs b/src/service/rocket/api.rs index 6e2281c..19d227d 100644 --- a/src/service/rocket/api.rs +++ b/src/service/rocket/api.rs @@ -4,7 +4,6 @@ use rocket::request::{self, FromParam, FromRequest, Request}; use rocket::response::content::Html; use rocket::{delete, get, post, put, routes, Outcome, State}; use rocket_contrib::json::Json; -use serde::{Deserialize, Serialize}; use std::fs::File; use std::ops::Deref; use std::path::PathBuf; @@ -239,21 +238,10 @@ fn trigger_index( Ok(()) } -#[derive(Serialize, Deserialize)] -pub struct AuthCredentials { - pub username: String, - pub password: String, -} - -#[derive(Serialize)] -struct AuthOutput { - admin: bool, -} - #[post("/auth", data = "")] fn auth( db: State<'_, DB>, - credentials: Json, + credentials: Json, mut cookies: Cookies<'_>, ) -> std::result::Result<(), APIError> { if !user::auth(&db, &credentials.username, &credentials.password)? { @@ -335,33 +323,23 @@ fn serve(db: State<'_, DB>, _auth: Auth, path: VFSPathBuf) -> Result, auth: Auth) -> Result>> { +fn list_playlists(db: State<'_, DB>, auth: Auth) -> Result>> { let playlist_names = playlist::list_playlists(&auth.username, db.deref().deref())?; - let playlists: Vec = playlist_names + let playlists: Vec = playlist_names .into_iter() - .map(|p| ListPlaylistsEntry { name: p }) + .map(|p| dto::ListPlaylistsEntry { name: p }) .collect(); Ok(Json(playlists)) } -#[derive(Serialize, Deserialize)] -pub struct SavePlaylistInput { - pub tracks: Vec, -} - #[put("/playlist/", data = "")] fn save_playlist( db: State<'_, DB>, auth: Auth, name: String, - playlist: Json, + playlist: Json, ) -> Result<()> { playlist::save_playlist(&name, &auth.username, &playlist.tracks, db.deref().deref())?; Ok(()) diff --git a/src/service/rocket/api_tests.rs b/src/service/rocket/api_tests.rs deleted file mode 100644 index 5fdf362..0000000 --- a/src/service/rocket/api_tests.rs +++ /dev/null @@ -1,479 +0,0 @@ -use rocket::http::hyper::header::*; -use rocket::http::uri::Uri; -use rocket::http::Status; -use rocket::local::Client; -use std::{thread, time}; - -use super::api; -use crate::config; -use crate::ddns; -use crate::index; -use crate::vfs; - -use super::test::get_test_environment; - -const TEST_USERNAME: &str = "test_user"; -const TEST_PASSWORD: &str = "test_password"; -const TEST_MOUNT_NAME: &str = "collection"; -const TEST_MOUNT_SOURCE: &str = "test/collection"; - -fn complete_initial_setup(client: &Client) { - let configuration = config::Config { - album_art_pattern: None, - prefix_url: None, - reindex_every_n_seconds: None, - ydns: None, - users: Some(vec![config::ConfigUser { - name: TEST_USERNAME.into(), - password: TEST_PASSWORD.into(), - admin: true, - }]), - mount_dirs: Some(vec![vfs::MountPoint { - name: TEST_MOUNT_NAME.into(), - source: TEST_MOUNT_SOURCE.into(), - }]), - }; - let body = serde_json::to_string(&configuration).unwrap(); - let response = client.put("/api/settings").body(&body).dispatch(); - assert_eq!(response.status(), Status::Ok); -} - -fn do_auth(client: &Client) { - let credentials = api::AuthCredentials { - username: TEST_USERNAME.into(), - password: TEST_PASSWORD.into(), - }; - let body = serde_json::to_string(&credentials).unwrap(); - let response = client.post("/api/auth").body(body).dispatch(); - assert_eq!(response.status(), Status::Ok); -} - -#[test] -fn settings() { - let env = get_test_environment("api_settings.sqlite"); - let client = &env.client; - complete_initial_setup(client); - - { - let response = client.get("/api/settings").dispatch(); - assert_eq!(response.status(), Status::Unauthorized); - } - - do_auth(client); - - { - let mut response = client.get("/api/settings").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: config::Config = serde_json::from_str(&response_body).unwrap(); - assert_eq!( - response_json, - config::Config { - album_art_pattern: Some("Folder.(jpg|png)".to_string()), - reindex_every_n_seconds: Some(1800), - mount_dirs: Some(vec![vfs::MountPoint { - name: TEST_MOUNT_NAME.into(), - source: TEST_MOUNT_SOURCE.into() - }]), - prefix_url: None, - users: Some(vec![config::ConfigUser { - name: TEST_USERNAME.into(), - password: "".into(), - admin: true - }]), - ydns: Some(ddns::DDNSConfig { - host: "".into(), - username: "".into(), - password: "".into() - }), - } - ); - } - - let mut configuration = config::Config { - album_art_pattern: Some("my_pattern".to_owned()), - reindex_every_n_seconds: Some(3600), - mount_dirs: Some(vec![ - vfs::MountPoint { - name: TEST_MOUNT_NAME.into(), - source: TEST_MOUNT_SOURCE.into(), - }, - vfs::MountPoint { - name: "more_music".into(), - source: "test/collection".into(), - }, - ]), - prefix_url: Some("my_prefix".to_owned()), - users: Some(vec![ - config::ConfigUser { - name: "test_user".into(), - password: "some_password".into(), - admin: true, - }, - config::ConfigUser { - name: "other_user".into(), - password: "some_other_password".into(), - admin: false, - }, - ]), - ydns: Some(ddns::DDNSConfig { - host: "my_host".into(), - username: "my_username".into(), - password: "my_password".into(), - }), - }; - - let body = serde_json::to_string(&configuration).unwrap(); - - configuration.users = Some(vec![ - config::ConfigUser { - name: "test_user".into(), - password: "".into(), - admin: true, - }, - config::ConfigUser { - name: "other_user".into(), - password: "".into(), - admin: false, - }, - ]); - - client.put("/api/settings").body(body).dispatch(); - - { - let mut response = client.get("/api/settings").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: config::Config = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json, configuration); - } -} - -#[test] -fn preferences() { - // TODO -} - -#[test] -fn trigger_index() { - let env = get_test_environment("api_trigger_index.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - - { - let mut response = client.get("/api/random").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 0); - } - - { - let response = client.post("/api/trigger_index").dispatch(); - assert_eq!(response.status(), Status::Ok); - } - - let timeout = time::Duration::from_secs(5); - thread::sleep(timeout); - - { - let mut response = client.get("/api/random").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 2); - } -} - -#[test] -fn auth() { - let env = get_test_environment("api_auth.sqlite"); - let client = &env.client; - complete_initial_setup(client); - - { - let credentials = api::AuthCredentials { - username: "garbage".into(), - password: "garbage".into(), - }; - let response = client - .post("/api/auth") - .body(serde_json::to_string(&credentials).unwrap()) - .dispatch(); - assert_eq!(response.status(), Status::Unauthorized); - } - { - let credentials = api::AuthCredentials { - username: TEST_USERNAME.into(), - password: "garbage".into(), - }; - let response = client - .post("/api/auth") - .body(serde_json::to_string(&credentials).unwrap()) - .dispatch(); - assert_eq!(response.status(), Status::Unauthorized); - } - { - let credentials = api::AuthCredentials { - username: TEST_USERNAME.into(), - password: TEST_PASSWORD.into(), - }; - let response = client - .post("/api/auth") - .body(serde_json::to_string(&credentials).unwrap()) - .dispatch(); - assert_eq!(response.status(), Status::Ok); - assert!(response - .cookies() - .iter() - .any(|cookie| cookie.name() == "username")); - assert!(response - .cookies() - .iter() - .any(|cookie| cookie.name() == "admin")); - assert!(response - .cookies() - .iter() - .any(|cookie| cookie.name() == "session")); - } -} - -#[test] -fn browse() { - let env = get_test_environment("api_browse.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - { - let mut response = client.get("/api/browse").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 1); - } - - let mut next; - { - let mut response = client.get("/api/browse/collection").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 2); - - match response_json[0] { - index::CollectionFile::Directory(ref d) => { - next = d.path.clone(); - } - _ => panic!(), - } - } - - // /api/browse/collection/Khemmis - { - let url = format!("/api/browse/{}", Uri::percent_encode(&next)); - let mut response = client.get(url).dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 1); - match response_json[0] { - index::CollectionFile::Directory(ref d) => { - next = d.path.clone(); - } - _ => panic!(), - } - } - - // /api/browse/collection/Khemmis/Hunted - { - let url = format!("/api/browse/{}", Uri::percent_encode(&next)); - let mut response = client.get(url).dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 5); - } -} - -#[test] -fn flatten() { - let env = get_test_environment("api_flatten.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - { - let mut response = client.get("/api/flatten").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 12); - } - - { - let mut response = client.get("/api/flatten/collection").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 12); - } -} - -#[test] -fn random() { - let env = get_test_environment("api_random.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - let mut response = client.get("/api/random").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 2); -} - -#[test] -fn recent() { - let env = get_test_environment("api_recent.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - let mut response = client.get("/api/recent").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 2); -} - -#[test] -fn search() { - let env = get_test_environment("api_search.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - let mut response = client.get("/api/search/door").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 1); - match response_json[0] { - index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())), - _ => panic!(), - } -} - -#[test] -fn serve() { - let env = get_test_environment("api_serve.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - { - let mut response = client - .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") - .dispatch(); - assert_eq!(response.status(), Status::Ok); - let body = response.body().unwrap(); - let body = body.into_bytes().unwrap(); - assert_eq!(body.len(), 24_142); - } - - { - let mut response = client - .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") - .header(Range::bytes(100, 299)) - .dispatch(); - assert_eq!(response.status(), Status::PartialContent); - let body = response.body().unwrap(); - let body = body.into_bytes().unwrap(); - assert_eq!(body.len(), 200); - assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200"); - } -} - -#[test] -fn playlists() { - let env = get_test_environment("api_playlists.sqlite"); - let client = &env.client; - complete_initial_setup(client); - do_auth(client); - env.update_index(); - - { - let mut response = client.get("/api/playlists").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 0); - } - - { - let songs: Vec; - { - let mut response = client.get("/api/flatten").dispatch(); - let response_body = response.body_string().unwrap(); - songs = serde_json::from_str(&response_body).unwrap(); - } - let my_playlist = api::SavePlaylistInput { - tracks: songs[2..6].into_iter().map(|s| s.path.clone()).collect(), - }; - let response = client - .put("/api/playlist/my_playlist") - .body(serde_json::to_string(&my_playlist).unwrap()) - .dispatch(); - assert_eq!(response.status(), Status::Ok); - } - - { - let mut response = client.get("/api/playlists").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!( - response_json, - vec![api::ListPlaylistsEntry { - name: "my_playlist".into() - }] - ); - } - - { - let mut response = client.get("/api/playlist/my_playlist").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 4); - } - - { - let response = client.delete("/api/playlist/my_playlist").dispatch(); - assert_eq!(response.status(), Status::Ok); - } - - { - let mut response = client.get("/api/playlists").dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - let response_json: Vec = - serde_json::from_str(&response_body).unwrap(); - assert_eq!(response_json.len(), 0); - } -} diff --git a/src/service/rocket/mod.rs b/src/service/rocket/mod.rs index 00ea1d8..10fbc8d 100644 --- a/src/service/rocket/mod.rs +++ b/src/service/rocket/mod.rs @@ -3,7 +3,5 @@ mod serve; pub mod server; -#[cfg(test)] -mod api_tests; #[cfg(test)] pub mod test; diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index f1de84a..1e673df 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -11,84 +11,107 @@ use std::sync::Arc; use super::server; use crate::db::DB; use crate::index; +use crate::service::test::{HttpStatus, TestService}; -pub struct TestEnvironment { - pub client: Client, +pub struct RocketTestService { + client: Client, command_sender: Arc, - db: DB, } -impl TestEnvironment { - pub fn update_index(&self) { - index::update(&self.db).unwrap(); +pub type ServiceType = RocketTestService; + +impl HttpStatus for Status { + fn is_ok(&self) -> bool { + *self == Status::Ok + } + + fn is_unauthorized(&self) -> bool { + *self == Status::Unauthorized } } -impl Drop for TestEnvironment { +impl TestService for RocketTestService { + type Status = Status; + + fn new(db_name: &str) -> Self { + let mut db_path = PathBuf::new(); + db_path.push("test"); + db_path.push(format!("{}.sqlite", db_name)); + if db_path.exists() { + fs::remove_file(&db_path).unwrap(); + } + let db = DB::new(&db_path).unwrap(); + + let web_dir_path = PathBuf::from("web"); + let mut swagger_dir_path = PathBuf::from("docs"); + swagger_dir_path.push("swagger"); + let command_sender = index::init(db.clone()); + + let auth_secret: [u8; 32] = [0; 32]; + + let server = server::get_server( + 5050, + &auth_secret, + "/api", + "/", + &web_dir_path, + "/swagger", + &swagger_dir_path, + db.clone(), + command_sender.clone(), + ) + .unwrap(); + let client = Client::new(server).unwrap(); + RocketTestService { + client, + command_sender, + } + } + + fn get(&mut self, url: &str) -> Status { + let client = &self.client; + let response = client.get(url).dispatch(); + response.status() + } + + fn post(&mut self, url: &str) -> Status { + let client = &self.client; + let response = client.post(url).dispatch(); + response.status() + } + + fn delete(&mut self, url: &str) -> Status { + let client = &self.client; + let response = client.delete(url).dispatch(); + response.status() + } + + fn get_json(&mut self, url: &str) -> T { + let client = &self.client; + let mut response = client.get(url).dispatch(); + assert_eq!(response.status(), Status::Ok); + let response_body = response.body_string().unwrap(); + dbg!(&response_body); + serde_json::from_str(&response_body).unwrap() + } + + fn put_json(&mut self, url: &str, payload: &T) { + let client = &self.client; + let body = serde_json::to_string(payload).unwrap(); + let response = client.put(url).body(&body).dispatch(); + assert_eq!(response.status(), Status::Ok); + } + + fn post_json(&mut self, url: &str, payload: &T) -> Status { + let client = &self.client; + let body = serde_json::to_string(payload).unwrap(); + let response = client.post(url).body(&body).dispatch(); + response.status() + } +} + +impl Drop for RocketTestService { fn drop(&mut self) { self.command_sender.deref().exit().unwrap(); } } - -pub fn get_test_environment(db_name: &str) -> TestEnvironment { - let mut db_path = PathBuf::new(); - db_path.push("test"); - db_path.push(db_name); - if db_path.exists() { - fs::remove_file(&db_path).unwrap(); - } - let db = DB::new(&db_path).unwrap(); - - let web_dir_path = PathBuf::from("web"); - let mut swagger_dir_path = PathBuf::from("docs"); - swagger_dir_path.push("swagger"); - let command_sender = index::init(db.clone()); - - let auth_secret: [u8; 32] = [0; 32]; - - let server = server::get_server( - 5050, - &auth_secret, - "/api", - "/", - &web_dir_path, - "/swagger", - &swagger_dir_path, - db.clone(), - command_sender.clone(), - ) - .unwrap(); - let client = Client::new(server).unwrap(); - TestEnvironment { - client, - command_sender, - db, - } -} - -pub type ServiceType = TestEnvironment; - -pub async fn make_service(test_name: &str) -> TestEnvironment { - get_test_environment(&format!("{}.sqlite", test_name)) -} - -pub async fn get(service: &mut TestEnvironment, url: &str) { - let client = &service.client; - let response = client.get(url).dispatch(); - assert_eq!(response.status(), Status::Ok); -} - -pub async fn get_json(service: &mut TestEnvironment, url: &str) -> T { - let client = &service.client; - let mut response = client.get(url).dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - serde_json::from_str(&response_body).unwrap() -} - -pub async fn put_json(service: &mut TestEnvironment, url: &str, payload: &T) { - let client = &service.client; - let body = serde_json::to_string(payload).unwrap(); - let response = client.put(url).body(&body).dispatch(); - assert_eq!(response.status(), Status::Ok); -} diff --git a/src/service/test.rs b/src/service/test.rs new file mode 100644 index 0000000..a592036 --- /dev/null +++ b/src/service/test.rs @@ -0,0 +1,416 @@ +use function_name::named; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::path::PathBuf; +use std::time::Duration; +use url::form_urlencoded::byte_serialize; + +use crate::service::dto; +use crate::{config, ddns, index, vfs}; + +#[cfg(feature = "service-rocket")] +pub use crate::service::rocket::test::ServiceType; + +const TEST_USERNAME: &str = "test_user"; +const TEST_PASSWORD: &str = "test_password"; +const TEST_MOUNT_NAME: &str = "collection"; +const TEST_MOUNT_SOURCE: &str = "test/collection"; + +pub trait HttpStatus { + fn is_ok(&self) -> bool; + fn is_unauthorized(&self) -> bool; +} + +pub trait TestService { + type Status: HttpStatus; + + fn new(db_name: &str) -> Self; + fn get(&mut self, url: &str) -> Self::Status; + fn post(&mut self, url: &str) -> Self::Status; + fn delete(&mut self, url: &str) -> Self::Status; + fn get_json(&mut self, url: &str) -> T; + fn put_json(&mut self, url: &str, payload: &T); + fn post_json(&mut self, url: &str, payload: &T) -> Self::Status; + + fn complete_initial_setup(&mut self) { + let configuration = config::Config { + album_art_pattern: None, + prefix_url: None, + reindex_every_n_seconds: None, + ydns: None, + users: Some(vec![config::ConfigUser { + name: TEST_USERNAME.into(), + password: TEST_PASSWORD.into(), + admin: true, + }]), + mount_dirs: Some(vec![vfs::MountPoint { + name: TEST_MOUNT_NAME.into(), + source: TEST_MOUNT_SOURCE.into(), + }]), + }; + self.put_json("/api/settings", &configuration); + } + + fn login(&mut self) { + let credentials = dto::AuthCredentials { + username: TEST_USERNAME.into(), + password: TEST_PASSWORD.into(), + }; + self.post_json("/api/auth", &credentials); + } + + fn index(&mut self) { + assert!(self.post("/api/trigger_index").is_ok()); + for _ in 1..20 { + let entries: Vec = self.get_json("/api/browse"); + if entries.len() > 0 { + return; + } + std::thread::sleep(Duration::from_secs(1)); + } + panic!("index timeout"); + } +} + +#[named] +#[test] +fn test_service_index() { + let mut service = ServiceType::new(function_name!()); + service.get("/"); +} + +#[named] +#[test] +fn test_service_swagger_index() { + let mut service = ServiceType::new(function_name!()); + assert!(service.get("/swagger").is_ok()); +} + +#[named] +#[test] +fn test_service_swagger_index_with_trailing_slash() { + let mut service = ServiceType::new(function_name!()); + assert!(service.get("/swagger/").is_ok()); +} + +#[named] +#[test] +fn test_service_version() { + let mut service = ServiceType::new(function_name!()); + let version: dto::Version = service.get_json("/api/version"); + assert_eq!(version, dto::Version { major: 4, minor: 0 }); +} + +#[named] +#[test] +fn test_service_initial_setup() { + let mut service = ServiceType::new(function_name!()); + { + let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); + assert_eq!( + initial_setup, + dto::InitialSetup { + has_any_users: false + } + ); + } + service.complete_initial_setup(); + { + let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); + assert_eq!( + initial_setup, + dto::InitialSetup { + has_any_users: true + } + ); + } +} + +#[named] +#[test] +fn test_service_settings() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + + assert!(service.get("/api/settings").is_unauthorized()); + service.login(); + + { + let configuration: config::Config = service.get_json("/api/settings"); + assert_eq!( + configuration, + config::Config { + album_art_pattern: Some("Folder.(jpg|png)".to_string()), + reindex_every_n_seconds: Some(1800), + mount_dirs: Some(vec![vfs::MountPoint { + name: TEST_MOUNT_NAME.into(), + source: TEST_MOUNT_SOURCE.into() + }]), + prefix_url: None, + users: Some(vec![config::ConfigUser { + name: TEST_USERNAME.into(), + password: "".into(), + admin: true + }]), + ydns: Some(ddns::DDNSConfig { + host: "".into(), + username: "".into(), + password: "".into() + }), + } + ); + } + + let mut configuration = config::Config { + album_art_pattern: Some("my_pattern".to_owned()), + reindex_every_n_seconds: Some(3600), + mount_dirs: Some(vec![ + vfs::MountPoint { + name: TEST_MOUNT_NAME.into(), + source: TEST_MOUNT_SOURCE.into(), + }, + vfs::MountPoint { + name: "more_music".into(), + source: "test/collection".into(), + }, + ]), + prefix_url: Some("my_prefix".to_owned()), + users: Some(vec![ + config::ConfigUser { + name: "test_user".into(), + password: "some_password".into(), + admin: true, + }, + config::ConfigUser { + name: "other_user".into(), + password: "some_other_password".into(), + admin: false, + }, + ]), + ydns: Some(ddns::DDNSConfig { + host: "my_host".into(), + username: "my_username".into(), + password: "my_password".into(), + }), + }; + + service.put_json("/api/settings", &configuration); + + configuration.users = Some(vec![ + config::ConfigUser { + name: "test_user".into(), + password: "".into(), + admin: true, + }, + config::ConfigUser { + name: "other_user".into(), + password: "".into(), + admin: false, + }, + ]); + + let received: config::Config = service.get_json("/api/settings"); + assert_eq!(received, configuration); +} + +#[named] +#[test] +fn test_service_preferences() { + // TODO +} + +#[named] +#[test] +fn test_service_trigger_index() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + + let entries: Vec = service.get_json("/api/random"); + assert_eq!(entries.len(), 0); + + service.index(); + + let entries: Vec = service.get_json("/api/random"); + assert_eq!(entries.len(), 2); +} + +#[named] +#[test] +fn test_service_auth() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + + { + let credentials = dto::AuthCredentials { + username: "garbage".into(), + password: "garbage".into(), + }; + assert!(service + .post_json("/api/auth", &credentials) + .is_unauthorized()); + } + { + let credentials = dto::AuthCredentials { + username: TEST_USERNAME.into(), + password: "garbage".into(), + }; + assert!(service + .post_json("/api/auth", &credentials) + .is_unauthorized()); + } + { + let credentials = dto::AuthCredentials { + username: TEST_USERNAME.into(), + password: TEST_PASSWORD.into(), + }; + assert!(service.post_json("/api/auth", &credentials).is_ok()); + // TODO validate cookies + } +} + +#[named] +#[test] +fn test_service_browse() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let entries: Vec = service.get_json("/api/browse"); + assert_eq!(entries.len(), 1); + + let mut path = PathBuf::new(); + path.push("collection"); + path.push("Khemmis"); + path.push("Hunted"); + let encoded_path: String = byte_serialize(path.to_string_lossy().as_ref().as_bytes()).collect(); + let uri = format!("/api/browse/{}", encoded_path); + + let entries: Vec = service.get_json(&uri); + assert_eq!(entries.len(), 5); +} + +#[named] +#[test] +fn test_service_flatten() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let entries: Vec = service.get_json("/api/flatten"); + assert_eq!(entries.len(), 12); + + let entries: Vec = service.get_json("/api/flatten/collection"); + assert_eq!(entries.len(), 12); +} + +#[named] +#[test] +fn test_service_random() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let entries: Vec = service.get_json("/api/random"); + assert_eq!(entries.len(), 2); +} + +#[named] +#[test] +fn test_service_recent() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let entries: Vec = service.get_json("/api/recent"); + assert_eq!(entries.len(), 2); +} + +#[named] +#[test] +fn test_service_search() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let results: Vec = service.get_json("/api/search/door"); + assert_eq!(results.len(), 1); + match results[0] { + index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())), + _ => panic!(), + } +} + +/* TODO +#[named] +#[test] +fn test_service_serve() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + { + let mut response = client + .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") + .dispatch(); + assert_eq!(response.status(), Status::Ok); + let body = response.body().unwrap(); + let body = body.into_bytes().unwrap(); + assert_eq!(body.len(), 24_142); + } + + { + let mut response = client + .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") + .header(Range::bytes(100, 299)) + .dispatch(); + assert_eq!(response.status(), Status::PartialContent); + let body = response.body().unwrap(); + let body = body.into_bytes().unwrap(); + assert_eq!(body.len(), 200); + assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200"); + } +} +*/ + +#[named] +#[test] +fn test_service_playlists() { + let mut service = ServiceType::new(function_name!()); + service.complete_initial_setup(); + service.login(); + service.index(); + + let playlists: Vec = service.get_json("/api/playlists"); + assert_eq!(playlists.len(), 0); + + let mut my_songs: Vec = service.get_json("/api/flatten"); + my_songs.pop(); + my_songs.pop(); + let my_playlist = dto::SavePlaylistInput { + tracks: my_songs.iter().map(|s| s.path.clone()).collect(), + }; + service.put_json("/api/playlist/my_playlist", &my_playlist); + + let playlists: Vec = service.get_json("/api/playlists"); + assert_eq!( + playlists, + vec![dto::ListPlaylistsEntry { + name: "my_playlist".into() + }] + ); + + let songs: Vec = service.get_json("/api/playlist/my_playlist"); + assert_eq!(songs, my_songs); + + service.delete("/api/playlist/my_playlist"); + + let playlists: Vec = service.get_json("/api/playlists"); + assert_eq!(playlists.len(), 0); +} diff --git a/src/service/tests.rs b/src/service/tests.rs deleted file mode 100644 index 05889b2..0000000 --- a/src/service/tests.rs +++ /dev/null @@ -1,91 +0,0 @@ -use function_name::named; - -use crate::config; -use crate::service::dto; -use crate::vfs; - -#[cfg(feature = "service-rocket")] -pub use crate::service::rocket::test; - -const TEST_USERNAME: &str = "test_user"; -const TEST_PASSWORD: &str = "test_password"; -const TEST_MOUNT_NAME: &str = "collection"; -const TEST_MOUNT_SOURCE: &str = "test/collection"; - -#[named] -#[tokio::test] -async fn test_index() { - let mut service = test::make_service(function_name!()).await; - test::get(&mut service, "/").await; -} - -#[named] -#[tokio::test] -async fn test_swagger_index() { - let mut service = test::make_service(function_name!()).await; - test::get(&mut service, "/swagger").await; -} - -#[named] -#[tokio::test] -async fn test_swagger_index_with_trailing_slash() { - let mut service = test::make_service(function_name!()).await; - test::get(&mut service, "/swagger/").await; -} - -async fn complete_initial_setup(service: &mut test::ServiceType) { - let configuration = config::Config { - album_art_pattern: None, - prefix_url: None, - reindex_every_n_seconds: None, - ydns: None, - users: Some(vec![config::ConfigUser { - name: TEST_USERNAME.into(), - password: TEST_PASSWORD.into(), - admin: true, - }]), - mount_dirs: Some(vec![vfs::MountPoint { - name: TEST_MOUNT_NAME.into(), - source: TEST_MOUNT_SOURCE.into(), - }]), - }; - test::put_json(service, "/api/settings", &configuration).await; -} - -#[named] -#[tokio::test] -async fn test_version() { - let mut service = test::make_service(function_name!()).await; - let version: dto::Version = test::get_json(&mut service, "/api/version").await; - assert_eq!(version, dto::Version { major: 4, minor: 0 }); -} - -#[named] -#[tokio::test] -async fn test_initial_setup() { - let mut service = test::make_service(function_name!()).await; - - { - let initial_setup: dto::InitialSetup = - test::get_json(&mut service, "/api/initial_setup").await; - assert_eq!( - initial_setup, - dto::InitialSetup { - has_any_users: false - } - ); - } - - complete_initial_setup(&mut service).await; - - { - let initial_setup: dto::InitialSetup = - test::get_json(&mut service, "/api/initial_setup").await; - assert_eq!( - initial_setup, - dto::InitialSetup { - has_any_users: true - } - ); - } -} From 3c45150651af67e766ce5f414f4e198198185e52 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 01:44:12 -0800 Subject: [PATCH 19/32] Use standard http responses as test service outputs --- Cargo.lock | 12 +++++++++ Cargo.toml | 1 + src/service/rocket/test.rs | 53 +++++++++++++++++--------------------- src/service/test.rs | 34 +++++++++--------------- 4 files changed, 49 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecd67e4..0317cb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -811,6 +811,16 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http-body" version = "0.1.0" @@ -1522,6 +1532,7 @@ dependencies = [ "flamer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "function_name 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "id3 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", "lewton 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2839,6 +2850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" diff --git a/Cargo.toml b/Cargo.toml index 55bca09..026cf64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ flame = { version = "0.2.2", optional = true } flamer = { version = "0.4", optional = true } function_name = "0.2.0" getopts = "0.2.15" +http = "0.2" id3 = "0.3" image = "0.22" libsqlite3-sys = { version = "0.16", features = ["bundled-windows"] } diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index 1e673df..9dcdc81 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -1,3 +1,4 @@ +use http::Response; use rocket; use rocket::http::Status; use rocket::local::Client; @@ -11,7 +12,17 @@ use std::sync::Arc; use super::server; use crate::db::DB; use crate::index; -use crate::service::test::{HttpStatus, TestService}; +use crate::service::test::TestService; + +pub struct RocketResponse<'r>(&'r rocket::Response<'r>); +impl<'r> Into> for RocketResponse<'r> { + fn into(self) -> Response<()> { + Response::builder() + .status(self.0.status().code) + .body(()) + .unwrap() + } +} pub struct RocketTestService { client: Client, @@ -20,19 +31,7 @@ pub struct RocketTestService { pub type ServiceType = RocketTestService; -impl HttpStatus for Status { - fn is_ok(&self) -> bool { - *self == Status::Ok - } - - fn is_unauthorized(&self) -> bool { - *self == Status::Unauthorized - } -} - impl TestService for RocketTestService { - type Status = Status; - fn new(db_name: &str) -> Self { let mut db_path = PathBuf::new(); db_path.push("test"); @@ -68,22 +67,19 @@ impl TestService for RocketTestService { } } - fn get(&mut self, url: &str) -> Status { - let client = &self.client; - let response = client.get(url).dispatch(); - response.status() + fn get(&mut self, url: &str) -> Response<()> { + let response = self.client.get(url).dispatch(); + RocketResponse(response.deref()).into() } - fn post(&mut self, url: &str) -> Status { - let client = &self.client; - let response = client.post(url).dispatch(); - response.status() + fn post(&mut self, url: &str) -> Response<()> { + let response = self.client.post(url).dispatch(); + RocketResponse(response.deref()).into() } - fn delete(&mut self, url: &str) -> Status { - let client = &self.client; - let response = client.delete(url).dispatch(); - response.status() + fn delete(&mut self, url: &str) -> Response<()> { + let response = self.client.delete(url).dispatch(); + RocketResponse(response.deref()).into() } fn get_json(&mut self, url: &str) -> T { @@ -102,11 +98,10 @@ impl TestService for RocketTestService { assert_eq!(response.status(), Status::Ok); } - fn post_json(&mut self, url: &str, payload: &T) -> Status { - let client = &self.client; + fn post_json(&mut self, url: &str, payload: &T) -> Response<()> { let body = serde_json::to_string(payload).unwrap(); - let response = client.post(url).body(&body).dispatch(); - response.status() + let response = self.client.post(url).body(&body).dispatch(); + RocketResponse(response.deref()).into() } } diff --git a/src/service/test.rs b/src/service/test.rs index a592036..6385733 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -1,4 +1,5 @@ use function_name::named; +use http::{Response, StatusCode}; use serde::de::DeserializeOwned; use serde::Serialize; use std::path::PathBuf; @@ -16,21 +17,14 @@ const TEST_PASSWORD: &str = "test_password"; const TEST_MOUNT_NAME: &str = "collection"; const TEST_MOUNT_SOURCE: &str = "test/collection"; -pub trait HttpStatus { - fn is_ok(&self) -> bool; - fn is_unauthorized(&self) -> bool; -} - pub trait TestService { - type Status: HttpStatus; - fn new(db_name: &str) -> Self; - fn get(&mut self, url: &str) -> Self::Status; - fn post(&mut self, url: &str) -> Self::Status; - fn delete(&mut self, url: &str) -> Self::Status; + fn get(&mut self, url: &str) -> Response<()>; + fn post(&mut self, url: &str) -> Response<()>; + fn delete(&mut self, url: &str) -> Response<()>; fn get_json(&mut self, url: &str) -> T; fn put_json(&mut self, url: &str, payload: &T); - fn post_json(&mut self, url: &str, payload: &T) -> Self::Status; + fn post_json(&mut self, url: &str, payload: &T) -> Response<()>; fn complete_initial_setup(&mut self) { let configuration = config::Config { @@ -60,7 +54,7 @@ pub trait TestService { } fn index(&mut self) { - assert!(self.post("/api/trigger_index").is_ok()); + assert!(self.post("/api/trigger_index").status() == StatusCode::OK); for _ in 1..20 { let entries: Vec = self.get_json("/api/browse"); if entries.len() > 0 { @@ -83,14 +77,14 @@ fn test_service_index() { #[test] fn test_service_swagger_index() { let mut service = ServiceType::new(function_name!()); - assert!(service.get("/swagger").is_ok()); + assert!(service.get("/swagger").status() == StatusCode::OK); } #[named] #[test] fn test_service_swagger_index_with_trailing_slash() { let mut service = ServiceType::new(function_name!()); - assert!(service.get("/swagger/").is_ok()); + assert!(service.get("/swagger/").status() == StatusCode::OK); } #[named] @@ -132,7 +126,7 @@ fn test_service_settings() { let mut service = ServiceType::new(function_name!()); service.complete_initial_setup(); - assert!(service.get("/api/settings").is_unauthorized()); + assert!(service.get("/api/settings").status() == StatusCode::UNAUTHORIZED); service.login(); { @@ -246,25 +240,21 @@ fn test_service_auth() { username: "garbage".into(), password: "garbage".into(), }; - assert!(service - .post_json("/api/auth", &credentials) - .is_unauthorized()); + assert!(service.post_json("/api/auth", &credentials).status() == StatusCode::UNAUTHORIZED); } { let credentials = dto::AuthCredentials { username: TEST_USERNAME.into(), password: "garbage".into(), }; - assert!(service - .post_json("/api/auth", &credentials) - .is_unauthorized()); + assert!(service.post_json("/api/auth", &credentials).status() == StatusCode::UNAUTHORIZED); } { let credentials = dto::AuthCredentials { username: TEST_USERNAME.into(), password: TEST_PASSWORD.into(), }; - assert!(service.post_json("/api/auth", &credentials).is_ok()); + assert!(service.post_json("/api/auth", &credentials).status() == StatusCode::OK); // TODO validate cookies } } From 7f7da0050ba5442c8ce35145616efb3e42adf58a Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 02:37:33 -0800 Subject: [PATCH 20/32] First half of serve request --- Cargo.lock | 30 +------------------- Cargo.toml | 7 ++--- src/service/rocket/test.rs | 52 +++++++++++++++++++++++------------ src/service/test.rs | 56 +++++++++++++++++++++----------------- 4 files changed, 70 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0317cb3..be9bb3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1497,11 +1497,6 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "pin-project-lite" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "pkg-config" version = "0.3.17" @@ -1541,6 +1536,7 @@ dependencies = [ "metaflac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "mp3-duration 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1555,7 +1551,6 @@ dependencies = [ "simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2367,17 +2362,6 @@ dependencies = [ "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-buf" version = "0.1.1" @@ -2416,15 +2400,6 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-reactor" version = "0.1.11" @@ -2922,7 +2897,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum png 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "247cb804bd7fc86d0c2b153d1374265e67945875720136ca8fe451f11c6aed52" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" @@ -3011,12 +2985,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -"checksum tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa2fdcfa937b20cb3c822a635ceecd5fc1a27a6a474527e5516aa24b8c8820a" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "50a61f268a3db2acee8dcab514efc813dc6dbe8a00e86076f935f94304b59a7a" "checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" diff --git a/Cargo.toml b/Cargo.toml index 026cf64..84b8793 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,10 +51,6 @@ default_features = false features = ["json", "serve"] optional = true -[dependencies.tokio] -version = "0.2" -features = ["macros", "rt-threaded"] - [target.'cfg(windows)'.dependencies] uuid = "0.8" @@ -65,3 +61,6 @@ features = ["winuser", "libloaderapi", "shellapi", "errhandlingapi"] [target.'cfg(unix)'.dependencies] sd-notify = "0.1.0" unix-daemonize = "0.1.2" + +[dev-dependencies] +percent-encoding = "2.1" \ No newline at end of file diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index 9dcdc81..cbf6e1c 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -1,11 +1,11 @@ -use http::Response; +use http::response::{Builder, Response}; use rocket; use rocket::http::Status; use rocket::local::Client; use serde::de::DeserializeOwned; use serde::Serialize; use std::fs; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use std::path::PathBuf; use std::sync::Arc; @@ -14,13 +14,27 @@ use crate::db::DB; use crate::index; use crate::service::test::TestService; -pub struct RocketResponse<'r>(&'r rocket::Response<'r>); -impl<'r> Into> for RocketResponse<'r> { +pub struct RocketResponse<'r, 's>(&'r mut rocket::Response<'s>); + +impl<'r, 's> Into for RocketResponse<'r, 's> { + fn into(self) -> Builder { + Response::builder().status(self.0.status().code) + } +} + +impl<'r, 's> Into> for RocketResponse<'r, 's> { fn into(self) -> Response<()> { - Response::builder() - .status(self.0.status().code) - .body(()) - .unwrap() + let builder: Builder = self.into(); + builder.body(()).unwrap() + } +} + +impl<'r, 's> Into>> for RocketResponse<'r, 's> { + fn into(self) -> Response> { + let body = self.0.body().unwrap(); + let body = body.into_bytes().unwrap(); + let builder: Builder = self.into(); + builder.body(body).unwrap() } } @@ -68,18 +82,23 @@ impl TestService for RocketTestService { } fn get(&mut self, url: &str) -> Response<()> { - let response = self.client.get(url).dispatch(); - RocketResponse(response.deref()).into() + let mut response = self.client.get(url).dispatch(); + RocketResponse(response.deref_mut()).into() + } + + fn get_bytes(&mut self, url: &str) -> Response> { + let mut response = self.client.get(url).dispatch(); + RocketResponse(response.deref_mut()).into() } fn post(&mut self, url: &str) -> Response<()> { - let response = self.client.post(url).dispatch(); - RocketResponse(response.deref()).into() + let mut response = self.client.post(url).dispatch(); + RocketResponse(response.deref_mut()).into() } fn delete(&mut self, url: &str) -> Response<()> { - let response = self.client.delete(url).dispatch(); - RocketResponse(response.deref()).into() + let mut response = self.client.delete(url).dispatch(); + RocketResponse(response.deref_mut()).into() } fn get_json(&mut self, url: &str) -> T { @@ -87,7 +106,6 @@ impl TestService for RocketTestService { let mut response = client.get(url).dispatch(); assert_eq!(response.status(), Status::Ok); let response_body = response.body_string().unwrap(); - dbg!(&response_body); serde_json::from_str(&response_body).unwrap() } @@ -100,8 +118,8 @@ impl TestService for RocketTestService { fn post_json(&mut self, url: &str, payload: &T) -> Response<()> { let body = serde_json::to_string(payload).unwrap(); - let response = self.client.post(url).body(&body).dispatch(); - RocketResponse(response.deref()).into() + let mut response = self.client.post(url).body(&body).dispatch(); + RocketResponse(response.deref_mut()).into() } } diff --git a/src/service/test.rs b/src/service/test.rs index 6385733..ac6adab 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -1,10 +1,10 @@ use function_name::named; use http::{Response, StatusCode}; +use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; use serde::de::DeserializeOwned; use serde::Serialize; use std::path::PathBuf; use std::time::Duration; -use url::form_urlencoded::byte_serialize; use crate::service::dto; use crate::{config, ddns, index, vfs}; @@ -20,6 +20,7 @@ const TEST_MOUNT_SOURCE: &str = "test/collection"; pub trait TestService { fn new(db_name: &str) -> Self; fn get(&mut self, url: &str) -> Response<()>; + fn get_bytes(&mut self, url: &str) -> Response>; fn post(&mut self, url: &str) -> Response<()>; fn delete(&mut self, url: &str) -> Response<()>; fn get_json(&mut self, url: &str) -> T; @@ -274,8 +275,10 @@ fn test_service_browse() { path.push("collection"); path.push("Khemmis"); path.push("Hunted"); - let encoded_path: String = byte_serialize(path.to_string_lossy().as_ref().as_bytes()).collect(); - let uri = format!("/api/browse/{}", encoded_path); + let uri = format!( + "/api/browse/{}", + percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC) + ); let entries: Vec = service.get_json(&uri); assert_eq!(entries.len(), 5); @@ -336,7 +339,6 @@ fn test_service_search() { } } -/* TODO #[named] #[test] fn test_service_serve() { @@ -345,29 +347,33 @@ fn test_service_serve() { service.login(); service.index(); - { - let mut response = client - .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") - .dispatch(); - assert_eq!(response.status(), Status::Ok); - let body = response.body().unwrap(); - let body = body.into_bytes().unwrap(); - assert_eq!(body.len(), 24_142); - } + let mut path = PathBuf::new(); + path.push("collection"); + path.push("Khemmis"); + path.push("Hunted"); + path.push("02 - Candlelight.mp3"); + let uri = format!( + "/api/serve/{}", + percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC) + ); - { - let mut response = client - .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") - .header(Range::bytes(100, 299)) - .dispatch(); - assert_eq!(response.status(), Status::PartialContent); - let body = response.body().unwrap(); - let body = body.into_bytes().unwrap(); - assert_eq!(body.len(), 200); - assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200"); - } + let response = service.get_bytes(&uri); + assert_eq!(response.status(), StatusCode::OK); + assert_eq!(response.body().len(), 24_142); + + // TODO + // { + // let mut response = client + // .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") + // .header(Range::bytes(100, 299)) + // .dispatch(); + // assert_eq!(response.status(), Status::PartialContent); + // let body = response.body().unwrap(); + // let body = body.into_bytes().unwrap(); + // assert_eq!(body.len(), 200); + // assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200"); + // } } -*/ #[named] #[test] From 9f4f6b4337a197de4c70422d7d44d1e8ebd8cd39 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 02:49:00 -0800 Subject: [PATCH 21/32] Added TODO --- src/service/rocket/server.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index db44396..8af06c5 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -68,6 +68,7 @@ pub fn run( db, command_sender, )?; + // TODO do this in main std::thread::spawn(move || { server.launch(); }); From 5ccc0065156cbb71df3a2b955e01534b10e20451 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 21:14:25 -0800 Subject: [PATCH 22/32] Cleaner TestService API --- src/service/rocket/test.rs | 80 ++++++++++++++++++++++++-------------- src/service/test.rs | 78 +++++++++++++++++++++++-------------- 2 files changed, 100 insertions(+), 58 deletions(-) diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index cbf6e1c..b9d2cf4 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -1,6 +1,5 @@ use http::response::{Builder, Response}; use rocket; -use rocket::http::Status; use rocket::local::Client; use serde::de::DeserializeOwned; use serde::Serialize; @@ -14,26 +13,31 @@ use crate::db::DB; use crate::index; use crate::service::test::TestService; -pub struct RocketResponse<'r, 's>(&'r mut rocket::Response<'s>); - -impl<'r, 's> Into for RocketResponse<'r, 's> { - fn into(self) -> Builder { - Response::builder().status(self.0.status().code) - } +pub struct RocketResponse<'r, 's> { + response: &'s mut rocket::Response<'r>, } -impl<'r, 's> Into> for RocketResponse<'r, 's> { - fn into(self) -> Response<()> { - let builder: Builder = self.into(); +impl<'r, 's> RocketResponse<'r, 's> { + fn builder(&self) -> Builder { + Response::builder().status(self.response.status().code) + } + + fn to_void(&self) -> Response<()> { + let builder = self.builder(); builder.body(()).unwrap() } -} -impl<'r, 's> Into>> for RocketResponse<'r, 's> { - fn into(self) -> Response> { - let body = self.0.body().unwrap(); + fn to_bytes(&mut self) -> Response> { + let body = self.response.body().unwrap(); let body = body.into_bytes().unwrap(); - let builder: Builder = self.into(); + let builder = self.builder(); + builder.body(body).unwrap() + } + + fn to_object(&mut self) -> Response { + let body = self.response.body_string().unwrap(); + let body = serde_json::from_str(&body).unwrap(); + let builder = self.builder(); builder.body(body).unwrap() } } @@ -83,43 +87,61 @@ impl TestService for RocketTestService { fn get(&mut self, url: &str) -> Response<()> { let mut response = self.client.get(url).dispatch(); - RocketResponse(response.deref_mut()).into() + RocketResponse { + response: response.deref_mut(), + } + .to_void() } fn get_bytes(&mut self, url: &str) -> Response> { let mut response = self.client.get(url).dispatch(); - RocketResponse(response.deref_mut()).into() + RocketResponse { + response: response.deref_mut(), + } + .to_bytes() } fn post(&mut self, url: &str) -> Response<()> { let mut response = self.client.post(url).dispatch(); - RocketResponse(response.deref_mut()).into() + RocketResponse { + response: response.deref_mut(), + } + .to_void() } fn delete(&mut self, url: &str) -> Response<()> { let mut response = self.client.delete(url).dispatch(); - RocketResponse(response.deref_mut()).into() + RocketResponse { + response: response.deref_mut(), + } + .to_void() } - fn get_json(&mut self, url: &str) -> T { - let client = &self.client; - let mut response = client.get(url).dispatch(); - assert_eq!(response.status(), Status::Ok); - let response_body = response.body_string().unwrap(); - serde_json::from_str(&response_body).unwrap() + fn get_json(&mut self, url: &str) -> Response { + let mut response = self.client.get(url).dispatch(); + RocketResponse { + response: response.deref_mut(), + } + .to_object() } - fn put_json(&mut self, url: &str, payload: &T) { + fn put_json(&mut self, url: &str, payload: &T) -> Response<()> { let client = &self.client; let body = serde_json::to_string(payload).unwrap(); - let response = client.put(url).body(&body).dispatch(); - assert_eq!(response.status(), Status::Ok); + let mut response = client.put(url).body(&body).dispatch(); + RocketResponse { + response: response.deref_mut(), + } + .to_void() } fn post_json(&mut self, url: &str, payload: &T) -> Response<()> { let body = serde_json::to_string(payload).unwrap(); let mut response = self.client.post(url).body(&body).dispatch(); - RocketResponse(response.deref_mut()).into() + RocketResponse { + response: response.deref_mut(), + } + .to_void() } } diff --git a/src/service/test.rs b/src/service/test.rs index ac6adab..6980d70 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -23,8 +23,8 @@ pub trait TestService { fn get_bytes(&mut self, url: &str) -> Response>; fn post(&mut self, url: &str) -> Response<()>; fn delete(&mut self, url: &str) -> Response<()>; - fn get_json(&mut self, url: &str) -> T; - fn put_json(&mut self, url: &str, payload: &T); + fn get_json(&mut self, url: &str) -> Response; + fn put_json(&mut self, url: &str, payload: &T) -> Response<()>; fn post_json(&mut self, url: &str, payload: &T) -> Response<()>; fn complete_initial_setup(&mut self) { @@ -57,7 +57,8 @@ pub trait TestService { fn index(&mut self) { assert!(self.post("/api/trigger_index").status() == StatusCode::OK); for _ in 1..20 { - let entries: Vec = self.get_json("/api/browse"); + let response = self.get_json::>("/api/browse"); + let entries = response.body(); if entries.len() > 0 { return; } @@ -92,8 +93,9 @@ fn test_service_swagger_index_with_trailing_slash() { #[test] fn test_service_version() { let mut service = ServiceType::new(function_name!()); - let version: dto::Version = service.get_json("/api/version"); - assert_eq!(version, dto::Version { major: 4, minor: 0 }); + let response = service.get_json::("/api/version"); + let version = response.body(); + assert_eq!(version, &dto::Version { major: 4, minor: 0 }); } #[named] @@ -101,20 +103,22 @@ fn test_service_version() { fn test_service_initial_setup() { let mut service = ServiceType::new(function_name!()); { - let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); + let response = service.get_json::("/api/initial_setup"); + let initial_setup = response.body(); assert_eq!( initial_setup, - dto::InitialSetup { + &dto::InitialSetup { has_any_users: false } ); } service.complete_initial_setup(); { - let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); + let response = service.get_json::("/api/initial_setup"); + let initial_setup = response.body(); assert_eq!( initial_setup, - dto::InitialSetup { + &dto::InitialSetup { has_any_users: true } ); @@ -131,10 +135,11 @@ fn test_service_settings() { service.login(); { - let configuration: config::Config = service.get_json("/api/settings"); + let response = service.get_json::("/api/settings"); + let configuration = response.body(); assert_eq!( configuration, - config::Config { + &config::Config { album_art_pattern: Some("Folder.(jpg|png)".to_string()), reindex_every_n_seconds: Some(1800), mount_dirs: Some(vec![vfs::MountPoint { @@ -204,8 +209,9 @@ fn test_service_settings() { }, ]); - let received: config::Config = service.get_json("/api/settings"); - assert_eq!(received, configuration); + let response = service.get_json::("/api/settings"); + let received = response.body(); + assert_eq!(received, &configuration); } #[named] @@ -221,12 +227,14 @@ fn test_service_trigger_index() { service.complete_initial_setup(); service.login(); - let entries: Vec = service.get_json("/api/random"); + let response = service.get_json::>("/api/random"); + let entries = response.body(); assert_eq!(entries.len(), 0); service.index(); - let entries: Vec = service.get_json("/api/random"); + let response = service.get_json::>("/api/random"); + let entries = response.body(); assert_eq!(entries.len(), 2); } @@ -268,7 +276,8 @@ fn test_service_browse() { service.login(); service.index(); - let entries: Vec = service.get_json("/api/browse"); + let response = service.get_json::>("/api/browse"); + let entries = response.body(); assert_eq!(entries.len(), 1); let mut path = PathBuf::new(); @@ -280,7 +289,8 @@ fn test_service_browse() { percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC) ); - let entries: Vec = service.get_json(&uri); + let response = service.get_json::>(&uri); + let entries = response.body(); assert_eq!(entries.len(), 5); } @@ -292,10 +302,12 @@ fn test_service_flatten() { service.login(); service.index(); - let entries: Vec = service.get_json("/api/flatten"); + let response = service.get_json::>("/api/flatten"); + let entries = response.body(); assert_eq!(entries.len(), 12); - let entries: Vec = service.get_json("/api/flatten/collection"); + let response = service.get_json::>("/api/flatten/collection"); + let entries = response.body(); assert_eq!(entries.len(), 12); } @@ -307,7 +319,8 @@ fn test_service_random() { service.login(); service.index(); - let entries: Vec = service.get_json("/api/random"); + let response = service.get_json::>("/api/random"); + let entries = response.body(); assert_eq!(entries.len(), 2); } @@ -319,7 +332,8 @@ fn test_service_recent() { service.login(); service.index(); - let entries: Vec = service.get_json("/api/recent"); + let response = service.get_json::>("/api/recent"); + let entries = response.body(); assert_eq!(entries.len(), 2); } @@ -331,7 +345,8 @@ fn test_service_search() { service.login(); service.index(); - let results: Vec = service.get_json("/api/search/door"); + let response = service.get_json::>("/api/search/door"); + let results = response.body(); assert_eq!(results.len(), 1); match results[0] { index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())), @@ -383,10 +398,12 @@ fn test_service_playlists() { service.login(); service.index(); - let playlists: Vec = service.get_json("/api/playlists"); + let response = service.get_json::>("/api/playlists"); + let playlists = response.body(); assert_eq!(playlists.len(), 0); - let mut my_songs: Vec = service.get_json("/api/flatten"); + let response = service.get_json::>("/api/flatten"); + let mut my_songs = response.into_body(); my_songs.pop(); my_songs.pop(); let my_playlist = dto::SavePlaylistInput { @@ -394,19 +411,22 @@ fn test_service_playlists() { }; service.put_json("/api/playlist/my_playlist", &my_playlist); - let playlists: Vec = service.get_json("/api/playlists"); + let response = service.get_json::>("/api/playlists"); + let playlists = response.body(); assert_eq!( playlists, - vec![dto::ListPlaylistsEntry { + &vec![dto::ListPlaylistsEntry { name: "my_playlist".into() }] ); - let songs: Vec = service.get_json("/api/playlist/my_playlist"); - assert_eq!(songs, my_songs); + let response = service.get_json::>("/api/playlist/my_playlist"); + let songs = response.body(); + assert_eq!(songs, &my_songs); service.delete("/api/playlist/my_playlist"); - let playlists: Vec = service.get_json("/api/playlists"); + let response = service.get_json::>("/api/playlists"); + let playlists = response.body(); assert_eq!(playlists.len(), 0); } From fa178b92be2637f51177747e50b391c02e614786 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 21:51:28 -0800 Subject: [PATCH 23/32] Validate partial content support --- src/service/rocket/test.rs | 18 +++++++++++++++--- src/service/test.rs | 27 ++++++++++++--------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/service/rocket/test.rs b/src/service/rocket/test.rs index b9d2cf4..18ff43a 100644 --- a/src/service/rocket/test.rs +++ b/src/service/rocket/test.rs @@ -1,4 +1,5 @@ use http::response::{Builder, Response}; +use http::{HeaderMap, HeaderValue}; use rocket; use rocket::local::Client; use serde::de::DeserializeOwned; @@ -19,7 +20,11 @@ pub struct RocketResponse<'r, 's> { impl<'r, 's> RocketResponse<'r, 's> { fn builder(&self) -> Builder { - Response::builder().status(self.response.status().code) + let mut builder = Response::builder().status(self.response.status().code); + for header in self.response.headers().iter() { + builder = builder.header(header.name(), header.value()); + } + builder } fn to_void(&self) -> Response<()> { @@ -93,8 +98,15 @@ impl TestService for RocketTestService { .to_void() } - fn get_bytes(&mut self, url: &str) -> Response> { - let mut response = self.client.get(url).dispatch(); + fn get_bytes(&mut self, url: &str, headers: &HeaderMap) -> Response> { + let mut request = self.client.get(url); + for (name, value) in headers.iter() { + request.add_header(rocket::http::Header::new( + name.as_str().to_owned(), + value.to_str().unwrap().to_owned(), + )) + } + let mut response = request.dispatch(); RocketResponse { response: response.deref_mut(), } diff --git a/src/service/test.rs b/src/service/test.rs index 6980d70..7c02333 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -1,5 +1,6 @@ use function_name::named; -use http::{Response, StatusCode}; +use http::header::*; +use http::{HeaderMap, HeaderValue, Response, StatusCode}; use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; use serde::de::DeserializeOwned; use serde::Serialize; @@ -20,7 +21,7 @@ const TEST_MOUNT_SOURCE: &str = "test/collection"; pub trait TestService { fn new(db_name: &str) -> Self; fn get(&mut self, url: &str) -> Response<()>; - fn get_bytes(&mut self, url: &str) -> Response>; + fn get_bytes(&mut self, url: &str, headers: &HeaderMap) -> Response>; fn post(&mut self, url: &str) -> Response<()>; fn delete(&mut self, url: &str) -> Response<()>; fn get_json(&mut self, url: &str) -> Response; @@ -372,22 +373,18 @@ fn test_service_serve() { percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC) ); - let response = service.get_bytes(&uri); + let response = service.get_bytes(&uri, &HeaderMap::new()); assert_eq!(response.status(), StatusCode::OK); assert_eq!(response.body().len(), 24_142); - // TODO - // { - // let mut response = client - // .get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3") - // .header(Range::bytes(100, 299)) - // .dispatch(); - // assert_eq!(response.status(), Status::PartialContent); - // let body = response.body().unwrap(); - // let body = body.into_bytes().unwrap(); - // assert_eq!(body.len(), 200); - // assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200"); - // } + { + let mut headers = HeaderMap::new(); + headers.append(RANGE, HeaderValue::from_str("bytes=100-299").unwrap()); + let response = service.get_bytes(&uri, &headers); + assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT); + assert_eq!(response.body().len(), 200); + assert_eq!(response.headers().get(CONTENT_LENGTH).unwrap(), "200"); + } } #[named] From 9df21737fa7158bca8c02a3bd02005660a9f700d Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 22:02:17 -0800 Subject: [PATCH 24/32] Validate auth cookies --- Cargo.lock | 1 + Cargo.toml | 1 + src/service/test.rs | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be9bb3a..9d4d4a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1521,6 +1521,7 @@ dependencies = [ "ape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "flame 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 84b8793..d4afb38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ anyhow = "1.0" ape = "0.2.0" app_dirs = "1.1.1" base64 = "0.11.0" +cookie = "0.12.0" diesel = { version = "1.4", features = ["sqlite", "r2d2"] } diesel_migrations = { version = "1.4", features = ["sqlite"] } flame = { version = "0.2.2", optional = true } diff --git a/src/service/test.rs b/src/service/test.rs index 7c02333..29a6ed9 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -1,3 +1,4 @@ +use cookie::Cookie; use function_name::named; use http::header::*; use http::{HeaderMap, HeaderValue, Response, StatusCode}; @@ -7,6 +8,7 @@ use serde::Serialize; use std::path::PathBuf; use std::time::Duration; +use crate::service::constants::*; use crate::service::dto; use crate::{config, ddns, index, vfs}; @@ -264,8 +266,17 @@ fn test_service_auth() { username: TEST_USERNAME.into(), password: TEST_PASSWORD.into(), }; - assert!(service.post_json("/api/auth", &credentials).status() == StatusCode::OK); - // TODO validate cookies + let response = service.post_json("/api/auth", &credentials); + assert!(response.status() == StatusCode::OK); + let cookies: Vec = response + .headers() + .get_all(SET_COOKIE) + .iter() + .map(|c| Cookie::parse(c.to_str().unwrap()).unwrap()) + .collect(); + assert!(cookies.iter().any(|c| c.name() == COOKIE_SESSION)); + assert!(cookies.iter().any(|c| c.name() == COOKIE_USERNAME)); + assert!(cookies.iter().any(|c| c.name() == COOKIE_ADMIN)); } } From a4991a620e3f02dcb22b77d992222caaa95b7d86 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Fri, 17 Jan 2020 22:08:36 -0800 Subject: [PATCH 25/32] Removed outdated TODO --- src/service/rocket/server.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/service/rocket/server.rs b/src/service/rocket/server.rs index 8af06c5..e02f23f 100644 --- a/src/service/rocket/server.rs +++ b/src/service/rocket/server.rs @@ -68,9 +68,6 @@ pub fn run( db, command_sender, )?; - // TODO do this in main - std::thread::spawn(move || { - server.launch(); - }); + server.launch(); Ok(()) } From 95f6c62531f0e13c4efd717eac39f62df87b7c4c Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 13:23:22 -0800 Subject: [PATCH 26/32] Removed redundant transactions (https://github.com/diesel-rs/diesel/commit/59f59e3ccd96531f568e75b2ffad10b4b21e05e9) --- src/index.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/index.rs b/src/index.rs index 70b80a6..feac2af 100644 --- a/src/index.rs +++ b/src/index.rs @@ -183,12 +183,9 @@ impl IndexBuilder { #[cfg_attr(feature = "profile-index", flame)] fn flush_songs(&mut self) -> Result<()> { let connection = self.db.connect()?; - connection.transaction::<_, anyhow::Error, _>(|| { - diesel::insert_into(songs::table) - .values(&self.new_songs) - .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 - Ok(()) - })?; + diesel::insert_into(songs::table) + .values(&self.new_songs) + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 self.new_songs.clear(); Ok(()) } @@ -196,12 +193,9 @@ impl IndexBuilder { #[cfg_attr(feature = "profile-index", flame)] fn flush_directories(&mut self) -> Result<()> { let connection = self.db.connect()?; - connection.transaction::<_, anyhow::Error, _>(|| { - diesel::insert_into(directories::table) - .values(&self.new_directories) - .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 - Ok(()) - })?; + diesel::insert_into(directories::table) + .values(&self.new_directories) + .execute(&*connection)?; // TODO https://github.com/diesel-rs/diesel/issues/1822 self.new_directories.clear(); Ok(()) } From e64435efa5d72f4507faaa774dc83cbd82789105 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:19:44 -0800 Subject: [PATCH 27/32] Database sanity settings --- src/db/mod.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 6f923af..e59695d 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,6 +1,7 @@ use anyhow::*; use diesel::r2d2::{self, ConnectionManager, PooledConnection}; use diesel::sqlite::SqliteConnection; +use diesel::RunQueryDsl; use diesel_migrations; use log::info; use std::path::Path; @@ -18,14 +19,29 @@ pub struct DB { pool: r2d2::Pool>, } +#[derive(Debug)] +struct ConnectionCustomizer {} +impl diesel::r2d2::CustomizeConnection for ConnectionCustomizer { + fn on_acquire(&self, connection: &mut SqliteConnection) -> Result<(), diesel::r2d2::Error> { + let query = diesel::sql_query(r#" + PRAGMA busy_timeout = 60000; + PRAGMA journal_mode = WAL; + PRAGMA synchronous = NORMAL; + PRAGMA foreign_keys = ON; + "#); + query.execute(connection) + .map_err(|e| diesel::r2d2::Error::QueryError(e))?; + Ok(()) + } +} + impl DB { pub fn new(path: &Path) -> Result { info!("Database file path: {}", path.to_string_lossy()); let manager = ConnectionManager::::new(path.to_string_lossy()); - let pool = r2d2::Pool::builder() - .build(manager) - .expect("Failed to create pool."); // TODO handle error - + let pool = diesel::r2d2::Pool::builder() + .connection_customizer(Box::new(ConnectionCustomizer {})) + .build(manager)?; let db = DB { pool: pool }; db.migrate_up()?; Ok(db) From 50421e91d6dd46c230f60690ed37182ce1ce6369 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:25:10 -0800 Subject: [PATCH 28/32] Log errors in index self_trigger --- src/index.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/index.rs b/src/index.rs index feac2af..ac66355 100644 --- a/src/index.rs +++ b/src/index.rs @@ -482,7 +482,10 @@ pub fn self_trigger(db: &DB, command_buffer: &Arc) { .map_err(|e| Error::new(e)) }) .map(|s: MiscSettings| s.index_sleep_duration_seconds) - .unwrap_or(1800) // TODO log error + .unwrap_or_else(|e| { + error!("Could not retrieve index sleep duration: {}", e); + 1800 + }) }; thread::sleep(time::Duration::from_secs(sleep_duration as u64)); } From f9ebb432b226097edbe210529e99270dbcdf6b0a Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:31:10 -0800 Subject: [PATCH 29/32] Removed redundant derefs --- src/ddns.rs | 3 +-- src/index.rs | 28 ++++++++++++++-------------- src/playlist.rs | 9 ++++----- src/vfs.rs | 3 +-- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/ddns.rs b/src/ddns.rs index 8eda3bd..2dcf6ea 100644 --- a/src/ddns.rs +++ b/src/ddns.rs @@ -1,5 +1,4 @@ use anyhow::*; -use core::ops::Deref; use diesel::prelude::*; use log::{error, info}; use reqwest; @@ -28,7 +27,7 @@ impl DDNSConfigSource for DB { let connection = self.connect()?; Ok(ddns_config .select((host, username, password)) - .get_result(connection.deref())?) + .get_result(&connection)?) } } diff --git a/src/index.rs b/src/index.rs index ac66355..ee31a62 100644 --- a/src/index.rs +++ b/src/index.rs @@ -371,7 +371,7 @@ fn clean(db: &DB) -> Result<()> { let connection = db.connect()?; for chunk in missing_songs[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) { diesel::delete(songs::table.filter(songs::path.eq_any(chunk))) - .execute(connection.deref())?; + .execute(&connection)?; } } } @@ -382,7 +382,7 @@ fn clean(db: &DB) -> Result<()> { let connection = db.connect()?; all_directories = directories::table .select(directories::path) - .load(connection.deref())?; + .load(&connection)?; } let missing_directories = all_directories @@ -397,7 +397,7 @@ fn clean(db: &DB) -> Result<()> { let connection = db.connect()?; for chunk in missing_directories[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) { diesel::delete(directories::table.filter(directories::path.eq_any(chunk))) - .execute(connection.deref())?; + .execute(&connection)?; } } } @@ -533,7 +533,7 @@ where // Browse top-level let real_directories: Vec = directories::table .filter(directories::parent.is_null()) - .load(connection.deref())?; + .load(&connection)?; let virtual_directories = real_directories .into_iter() .filter_map(|s| virtualize_directory(&vfs, s)); @@ -546,7 +546,7 @@ where let real_directories: Vec = directories::table .filter(directories::parent.eq(&real_path_string)) .order(sql::("path COLLATE NOCASE ASC")) - .load(connection.deref())?; + .load(&connection)?; let virtual_directories = real_directories .into_iter() .filter_map(|s| virtualize_directory(&vfs, s)); @@ -555,7 +555,7 @@ where let real_songs: Vec = songs::table .filter(songs::parent.eq(&real_path_string)) .order(sql::("path COLLATE NOCASE ASC")) - .load(connection.deref())?; + .load(&connection)?; let virtual_songs = real_songs .into_iter() .filter_map(|s| virtualize_song(&vfs, s)); @@ -579,9 +579,9 @@ where songs .filter(path.like(&like_path)) .order(path) - .load(connection.deref())? + .load(&connection)? } else { - songs.order(path).load(connection.deref())? + songs.order(path).load(&connection)? }; let virtual_songs = real_songs @@ -598,7 +598,7 @@ pub fn get_random_albums(db: &DB, count: i64) -> Result> { .filter(album.is_not_null()) .limit(count) .order(random) - .load(connection.deref())?; + .load(&connection)?; let virtual_directories = real_directories .into_iter() .filter_map(|s| virtualize_directory(&vfs, s)); @@ -613,7 +613,7 @@ pub fn get_recent_albums(db: &DB, count: i64) -> Result> { .filter(album.is_not_null()) .order(date_added.desc()) .limit(count) - .load(connection.deref())?; + .load(&connection)?; let virtual_directories = real_directories .into_iter() .filter_map(|s| virtualize_directory(&vfs, s)); @@ -632,7 +632,7 @@ pub fn search(db: &DB, query: &str) -> Result> { let real_directories: Vec = directories .filter(path.like(&like_test)) .filter(parent.not_like(&like_test)) - .load(connection.deref())?; + .load(&connection)?; let virtual_directories = real_directories .into_iter() @@ -653,7 +653,7 @@ pub fn search(db: &DB, query: &str) -> Result> { .or(album_artist.like(&like_test)), ) .filter(parent.not_like(&like_test)) - .load(connection.deref())?; + .load(&connection)?; let virtual_songs = real_songs .into_iter() @@ -674,7 +674,7 @@ pub fn get_song(db: &DB, virtual_path: &Path) -> Result { use self::songs::dsl::*; let real_song: Song = songs .filter(path.eq(real_path_string)) - .get_result(connection.deref())?; + .get_result(&connection)?; match virtualize_song(&vfs, real_song) { Some(s) => Ok(s), @@ -715,7 +715,7 @@ fn test_metadata() { let connection = db.connect().unwrap(); let songs: Vec = songs::table .filter(songs::title.eq("シャーベット (Sherbet)")) - .load(connection.deref()) + .load(&connection) .unwrap(); assert_eq!(songs.len(), 1); diff --git a/src/playlist.rs b/src/playlist.rs index 39dfc77..4d8bf88 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -1,6 +1,5 @@ use anyhow::*; use core::clone::Clone; -use core::ops::Deref; use diesel; use diesel::prelude::*; use diesel::sql_types; @@ -57,14 +56,14 @@ pub fn list_playlists(owner: &str, db: &DB) -> Result> { user = users .filter(name.eq(owner)) .select((id,)) - .first(connection.deref())?; + .first(&connection)?; } { use self::playlists::dsl::*; let found_playlists: Vec = Playlist::belonging_to(&user) .select(name) - .load(connection.deref())?; + .load(&connection)?; Ok(found_playlists) } } @@ -129,7 +128,7 @@ pub fn save_playlist(playlist_name: &str, owner: &str, content: &[String], db: & connection.transaction::<_, diesel::result::Error, _>(|| { // Delete old content (if any) let old_songs = PlaylistSong::belonging_to(&playlist); - diesel::delete(old_songs).execute(connection.deref())?; + diesel::delete(old_songs).execute(&connection)?; // Insert content diesel::insert_into(playlist_songs::table) @@ -207,7 +206,7 @@ pub fn delete_playlist(playlist_name: &str, owner: &str, db: &DB) -> Result<()> { use self::playlists::dsl::*; let q = Playlist::belonging_to(&user).filter(name.eq(playlist_name)); - diesel::delete(q).execute(connection.deref())?; + diesel::delete(q).execute(&connection)?; } Ok(()) diff --git a/src/vfs.rs b/src/vfs.rs index d5b9280..b623c8b 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -1,5 +1,4 @@ use anyhow::*; -use core::ops::Deref; use diesel::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -20,7 +19,7 @@ impl VFSSource for DB { let connection = self.connect()?; let points: Vec = mount_points .select((source, name)) - .get_results(connection.deref())?; + .get_results(&connection)?; for point in points { vfs.mount(&Path::new(&point.source), &point.name)?; } From 0e6be32a8ca2d0da76ecaee7d6cdb4b4e08920be Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:37:35 -0800 Subject: [PATCH 30/32] Removed unused feature --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 30c763c..3208f81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ #![recursion_limit = "256"] -#![feature(proc_macro_hygiene, decl_macro, type_alias_impl_trait)] +#![feature(proc_macro_hygiene, decl_macro)] #[macro_use] extern crate diesel; From ee71df9d0b3d5e24232eabf69e2f65e8ba6707e4 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:48:47 -0800 Subject: [PATCH 31/32] Lock CI rustc to working nightly (https://github.com/rust-lang/rust/issues/68264) --- .github/workflows/build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 572c9bd..01f4f32 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,10 +24,10 @@ jobs: submodules: true - uses: actions-rs/toolchain@v1 with: - toolchain: nightly - override: true + toolchain: nightly-2020-01-14 + profile: minimal + default: true - uses: actions-rs/cargo@v1 with: command: test - toolchain: nightly args: --release ${{ matrix.features }} From 2efc0df04ecad8eae1c6e89dfafc3962c8a0c7dd Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Sat, 18 Jan 2020 14:59:19 -0800 Subject: [PATCH 32/32] Don't build without a backend --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 01f4f32..b821126 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - features: [--all-features, --no-default-features] + features: [--all-features, --features default] os: [ubuntu-latest, windows-latest, macOS-latest] steps: