From 0ef11b637640efbfea3d537450abdf12ad79baf6 Mon Sep 17 00:00:00 2001 From: Ben Bangert Date: Wed, 23 May 2018 10:41:37 -0700 Subject: [PATCH] feat: switch Rust startup to Rust only Co-authored by: Phil Jenvey Closes #1243 --- .gitignore | 1 + autopush_rs/Cargo.lock => Cargo.lock | 604 ++++++++++++++++---------- Cargo.toml | 2 + Dockerfile | 2 +- Dockerfile.python27 | 2 +- autopush/main.py | 80 ---- autopush/main_argparse.py | 10 - autopush/tests/test_rs_integration.py | 304 +++++++------ autopush/webpush_server.py | 39 -- autopush_rs/Cargo.toml | 20 +- autopush_rs/__init__.py | 107 ----- autopush_rs/build.rs | 26 -- autopush_rs/src/db/commands.rs | 16 +- autopush_rs/src/db/mod.rs | 20 + autopush_rs/src/errors.rs | 2 + autopush_rs/src/lib.rs | 8 +- autopush_rs/src/main.rs | 53 +++ autopush_rs/src/rt.rs | 300 ------------- autopush_rs/src/server/mod.rs | 341 ++++++--------- autopush_rs/src/settings.rs | 131 ++++++ setup.py | 17 +- tox.ini | 2 +- 22 files changed, 939 insertions(+), 1148 deletions(-) rename autopush_rs/Cargo.lock => Cargo.lock (81%) create mode 100644 Cargo.toml delete mode 100644 autopush/webpush_server.py delete mode 100644 autopush_rs/__init__.py delete mode 100644 autopush_rs/build.rs create mode 100644 autopush_rs/src/main.rs delete mode 100644 autopush_rs/src/rt.rs create mode 100644 autopush_rs/src/settings.rs diff --git a/.gitignore b/.gitignore index a7e4edce..86d76206 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ pypy/ .eggs/ autopush_rs/target autopush_rs/_native* +target *.rs.bk diff --git a/autopush_rs/Cargo.lock b/Cargo.lock similarity index 81% rename from autopush_rs/Cargo.lock rename to Cargo.lock index b348acfd..0a3e96b3 100644 --- a/autopush_rs/Cargo.lock +++ b/Cargo.lock @@ -5,18 +5,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aho-corasick" -version = "0.6.4" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "ansi_term" -version = "0.11.0" +name = "aho-corasick" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -37,7 +37,7 @@ name = "atty" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -49,9 +49,11 @@ dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cadence 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cbindgen 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chan-signal 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "config 0.8.0 (git+https://github.com/mehcode/config-rs?rev=e8fa9fee96185ddd18ebcef8a925c75459111edb)", + "docopt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "fernet 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -59,12 +61,12 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -72,8 +74,8 @@ dependencies = [ "rusoto_credential 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rusoto_dynamodb 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "sentry 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_dynamodb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -83,36 +85,36 @@ dependencies = [ "slog-stdlog 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "state_machine_future 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-openssl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tungstenite 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tungstenite 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "woothee 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -120,10 +122,23 @@ name = "base64" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bit-set" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-vec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "0.9.1" @@ -155,7 +170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -163,7 +178,7 @@ name = "bytes" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -175,21 +190,6 @@ dependencies = [ "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cbindgen" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cc" version = "1.0.15" @@ -200,28 +200,47 @@ name = "cfg-if" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chan" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "chan-signal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chan 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "chrono" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "clap" -version = "2.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "config" +version = "0.8.0" +source = "git+https://github.com/mehcode/config-rs?rev=e8fa9fee96185ddd18ebcef8a925c75459111edb#e8fa9fee96185ddd18ebcef8a925c75459111edb" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde-hjson 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -235,7 +254,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -243,7 +262,7 @@ name = "core-foundation-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -261,11 +280,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-deque" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -281,14 +300,6 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-utils" version = "0.3.2" @@ -356,6 +367,18 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "docopt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -371,7 +394,7 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -385,7 +408,7 @@ name = "error-chain" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -393,7 +416,7 @@ name = "error-chain" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -407,8 +430,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -511,7 +534,7 @@ name = "hostname" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -530,7 +553,7 @@ dependencies = [ [[package]] name = "hyper" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -541,15 +564,17 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -558,7 +583,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -578,7 +603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -594,26 +619,20 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "isatty" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itoa" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" version = "0.4.1" @@ -650,7 +669,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.40" +version = "0.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -659,10 +678,24 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "linked-hash-map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "log" version = "0.3.9" @@ -684,12 +717,28 @@ name = "matches" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -699,7 +748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mime" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -710,7 +759,7 @@ name = "mime_guess" version = "2.0.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -726,7 +775,7 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -751,7 +800,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -765,7 +814,7 @@ version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -774,17 +823,33 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nom" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" -version = "0.1.36" +version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.2" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -792,7 +857,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -803,29 +868,30 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.30" +version = "0.9.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -891,7 +957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" -version = "0.2.3" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -907,13 +973,21 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -923,13 +997,13 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.37" +version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -937,7 +1011,19 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -952,6 +1038,23 @@ dependencies = [ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "regex-syntax" version = "0.5.6" @@ -960,6 +1063,14 @@ dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex-syntax" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "relay" version = "0.1.1" @@ -989,15 +1100,15 @@ dependencies = [ "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1014,15 +1125,15 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rusoto_credential 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1035,7 +1146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1048,10 +1159,10 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "rusoto_core 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1100,7 +1211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1110,7 +1221,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1131,45 +1242,50 @@ name = "sentry" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde" -version = "1.0.45" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "serde_derive" -version = "1.0.21" +name = "serde" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde-hjson" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "serde_derive_internals" -version = "0.17.0" +name = "serde_derive" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1178,7 +1294,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rusoto_dynamodb 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1188,17 +1304,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_test" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_urlencoded" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1254,7 +1378,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1286,7 +1410,7 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1297,24 +1421,6 @@ name = "smallvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "standalone-quote" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "standalone-syn" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "standalone-quote 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "state_machine_future" version = "0.1.6" @@ -1340,6 +1446,16 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synom" version = "0.11.3" @@ -1372,7 +1488,7 @@ name = "term" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1389,17 +1505,26 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "textwrap" -version = "0.9.0" +name = "thread-id" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1413,11 +1538,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1490,7 +1615,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1551,7 +1676,7 @@ name = "tokio-threadpool" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1607,16 +1732,21 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "try-lock" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "tungstenite" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "input_buffer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1663,7 +1793,7 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1671,11 +1801,6 @@ name = "unicode-segmentation" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-width" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.0.4" @@ -1709,6 +1834,11 @@ name = "utf-8" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1724,12 +1854,12 @@ dependencies = [ [[package]] name = "uuid" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1737,11 +1867,6 @@ name = "vcpkg" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vec_map" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "version_check" version = "0.1.3" @@ -1752,6 +1877,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "want" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -1823,37 +1958,47 @@ dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "yaml-rust" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" +"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" -"checksum backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea58cd16fd6c9d120b5bcb01d63883ae4cc7ba2aed35c1841b862a3c7ef6639" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbdd17cd962b570302f5297aea8648d5923e22e555c2ed2d8b2e34eca646bf6d" +"checksum backtrace-sys 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3951a5d75651d5817056daf3132ed9cd7918bc7f2afc313b379009e832209a4d" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" +"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" +"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" +"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" "checksum cadence 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "99612ce0a00efdaf3d81a5e8e17f0eed55a10e862033183c847a0365983af88c" -"checksum cbindgen 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5199d190f7369ad9e1520fb4837a6fcb5f34d4c86c9720de642a1ad9949928f5" "checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba" "checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" +"checksum chan 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "9af7c487bb99c929ba2715b1a3a7bf45f5062bf5b6eae5d32b292a96c5865172" +"checksum chan-signal 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f1e11f6e1c14c9e805a87c622cb8fcb636283b3119a2150af390cc6702d7fe" "checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6" -"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" +"checksum config 0.8.0 (git+https://github.com/mehcode/config-rs?rev=e8fa9fee96185ddd18ebcef8a925c75459111edb)" = "" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" -"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" +"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" "checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958" "checksum darling 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1630fdbe3554154a50624487c79b0140a424e87dc08061db1a2211359792acab" @@ -1861,9 +2006,10 @@ dependencies = [ "checksum darling_macro 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "01581bdeabb86f69970dbd9e6ee3c61963f9a7321169589e3dffa16033c0928c" "checksum derive_state_machine_future 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54e84dd4e2e6b94edda02aaae8fd8d02f68404817c89183e16d217bb380d08e8" "checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603" +"checksum docopt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e67fb750c36fc6fffbd3575cf8f2b46790fc0b05096ae3c03a36cf71b55e1e2b" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" -"checksum env_logger 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "00c45cec4cde3daac5f036c74098b4956151525cdf360cff5ee0092c98823e54" +"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" @@ -1884,40 +2030,45 @@ dependencies = [ "checksum hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "58fab6e177434b0bb4cd344a4dabaa5bd6d7a8d792b1885aebcae7af1091d1cb" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)" = "549dbb86397490ce69d908425b9beebc85bbaad25157d67479d4995bb56fdf9a" +"checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" "checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum input_buffer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64fc52dd2f15e7ce28663e4eada58f457aa8c220044d531c3b8d56a8781af9b1" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" +"checksum isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6c324313540cd4d7ba008d43dc6606a32a5579f13cc17b2804c13096f0a5c522" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" +"checksum libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)" = "ac8ebf8343a981e2fa97042b14768f02ed3e1d602eac06cae6166df3c8ced206" "checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" +"checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" +"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" +"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" +"checksum mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b28683d0b09bbc20be1c9b3f6f24854efb1356ffcffee08ea3f6e65596e85fa" "checksum mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130ea3c9c1b65dba905ab5a4d9ac59234a9585c24d135f264e187fe7336febbd" "checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" +"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" +"checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +"checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)" = "63c6ff2c7d9903daf9f3429eb2f6beedb15b1f7362e3529e5bf00b6caf182400" +"checksum openssl 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "736898acffb0e00a14d86c5b836aee2ca1c502efcf1c1b0d17a936dfc49ec47f" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)" = "73ae718c3562989cd3a0a5c26610feca02f8116822f6f195e6cf4887481e57f5" +"checksum openssl-sys 0.9.31 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6a27d108b29befe1822d40e2e22f85518dac59acbf7f30fdc532f48fd0a77" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" @@ -1926,15 +2077,20 @@ dependencies = [ "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" -"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" +"checksum proc-macro2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a45f2f0ae0b5757f6fe9e68745ba25f5246aea3598984ed81d013865873c1f84" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum quote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e53eeda07ddbd8b057dde66d9beded11d0dfda13f0db0769e6b71d6bcf2074e" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "0a12d51a5b5fd700e6c757f15877685bfa04fd7eb60c108f01d045cafa0073c2" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3" +"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rent_to_own 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05a51ad2b1c5c710fa89e6b1631068dab84ed687bc6a5fe061ad65da3d0c25b2" @@ -1953,12 +2109,14 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum sentry 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c931969579f133c35280ccc1969a4786984449bd8adad937ef9f76cef3bdfbc" -"checksum serde 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "6a49d806123bcdaacdefe7aab3721c64ec11d05921bf64d888a857d3a92024a0" -"checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" -"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" +"checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" +"checksum serde 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "2a4d976362a13caad61c38cf841401d2d4d480496a9391c3842c288b01f9de95" +"checksum serde-hjson 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a2376ebb8976138927f48b49588ef73cde2f6591b8b3df22f4063e0f27b9bec" +"checksum serde_derive 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "94bb618afe46430c6b089e9b111dc5b2fcd3e26a268da0993f6d16bea51c6021" "checksum serde_dynamodb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe982f1146e7134af153b2d1fdcab083f09c184600b232cd7a120ec191a4e1b" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" -"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" +"checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" +"checksum serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e703cef904312097cfceab9ce131ff6bbe09e8c964a0703345a5f49238757bc1" "checksum sha1 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "933ed2cffa70bb0e1a2c1bf1174d0f39dd3b81bbf5597d882d886710c8729924" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" @@ -1971,11 +2129,10 @@ dependencies = [ "checksum slog-stdlog 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ac42f8254ae996cc7d640f9410d3b048dcdf8887a10df4d5d4c44966de24c4a8" "checksum slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5951a808c40f419922ee014c15b6ae1cd34d963538b57d8a4778b9ca3fff1e0b" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum standalone-quote 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcedac1d6d98e7e9d1d6e628f5635af9566688ae5f6cea70a3976f495ae8d839" -"checksum standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "115808f5187c07c23cb93eee49d542fae54c6e8285d3a24c6ff683fcde9243db" "checksum state_machine_future 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eaafbb574dda413e09727f3a534af6837756c9edb69691c120a3240fa30179da" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum syn 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99d991a9e7c33123925e511baab68f7ec25c3795962fe326a2395e5a42a614f0" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" @@ -1983,9 +2140,10 @@ dependencies = [ "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" +"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" +"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" @@ -2002,27 +2160,28 @@ dependencies = [ "checksum tokio-tungstenite 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3cedf5e2d459171cb08aa6126572a06d827de4208d35281a4cc98081182d5d1a" "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" +"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" "checksum tungstenite 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b3904357c86319d331cf9430bc7379a669f1bde1e20be51115c0fc96c0b9c9de" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90d662d111b0dbb08a180f2761026cba648c258023c355954a7c00e00e354636" +"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" -"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "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" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" +"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" -"checksum uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8630752f979f1b6b87c49830a5e3784082545de63920d59fbaac252474319447" +"checksum uuid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8abd2aaa3d03fbc210a1543664f0aa406f4d3b56660e401a7c69df8b893fab" "checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -2033,3 +2192,4 @@ dependencies = [ "checksum woothee 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e7c2cece51be2a2f25518a9efdd303d5ca8dfa619272f091e7dedbba95d1873" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" +"checksum yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57ab38ee1a4a266ed033496cf9af1828d8d6e6c1cfa5f643a2809effcae4d628" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..422eafe7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["autopush_rs"] diff --git a/Dockerfile b/Dockerfile index 9185e513..84aab020 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN \ make clean && \ pip install -r requirements.txt && \ pypy setup.py develop && \ - cd autopush_rs && \ + cargo install --path autopush_rs && \ cargo clean && \ rustup self uninstall -y diff --git a/Dockerfile.python27 b/Dockerfile.python27 index 5a1d0852..5101ee6d 100644 --- a/Dockerfile.python27 +++ b/Dockerfile.python27 @@ -14,7 +14,7 @@ RUN \ make clean && \ pip install -r requirements.txt && \ python setup.py develop && \ - cd autopush_rs && \ + cargo install --path autopush_rs && \ cargo clean && \ rustup self uninstall -y diff --git a/autopush/main.py b/autopush/main.py index bf228faf..767078b1 100644 --- a/autopush/main.py +++ b/autopush/main.py @@ -1,6 +1,5 @@ """autopush/autoendpoint daemon scripts""" import os -import time from argparse import Namespace # noqa from twisted.application.internet import ( @@ -40,7 +39,6 @@ monkey_patch_ssl_wrap_socket, undo_monkey_patch_ssl_wrap_socket, ) -from autopush.webpush_server import WebPushServer from autopush.websocket import ( ConnectionWSSite, PushServerFactory, @@ -307,81 +305,3 @@ def from_argparse(cls, ns, resource=None): aws_ddb_endpoint=ns.aws_ddb_endpoint, resource=resource ) - - -class RustConnectionApplication(AutopushMultiService): - """The autopush application""" - - config_files = AutopushMultiService.shared_config_files + ( - '/etc/autopush_connection.ini', - 'configs/autopush_connection.ini', - '~/.autopush_connection.ini', - '.autopush_connection.ini' - ) - - parse_args = staticmethod(parse_connection) # type: ignore - logger_name = "AutopushRust" - push_server = None - - def setup(self, rotate_tables=True, num_threads=10): - super(RustConnectionApplication, self).setup(rotate_tables) - - self.db.setup(self.conf.preflight_uaid) - - # No add_memusage: requires twisted - self.push_server = WebPushServer( - self.conf, - self.db, - num_threads=num_threads, - ) - - def run(self): # pragma: nocover - try: - self.startService() - while True: - try: - # handle a graceful shutdown on SIGINT w/ a busy - # loop. we can't Thread.join because SIGINT won't - # interrupt it - time.sleep(6000) - except KeyboardInterrupt: - return 1 - finally: - self.stopService() - - def startService(self): - self.push_server.start() - - def stopService(self): - self.push_server.stop() - - @classmethod - def from_argparse(cls, ns, resource=None): # pragma: nocover - # type: (Namespace, DynamoDBResource) -> AutopushMultiService - return super(RustConnectionApplication, cls)._from_argparse( - ns, - port=ns.port, - endpoint_scheme=ns.endpoint_scheme, - endpoint_hostname=ns.endpoint_hostname, - endpoint_port=ns.endpoint_port, - router_scheme="https" if ns.router_ssl_key else "http", - router_hostname=ns.router_hostname, - router_port=ns.router_port, - env=ns.env, - hello_timeout=ns.hello_timeout, - router_ssl=dict( - key=ns.router_ssl_key, - cert=ns.router_ssl_cert, - dh_param=ns.ssl_dh_param - ), - # XXX: default is for autopush_rs - auto_ping_interval=ns.auto_ping_interval or 300, - auto_ping_timeout=ns.auto_ping_timeout, - max_connections=ns.max_connections, - close_handshake_timeout=ns.close_handshake_timeout, - aws_ddb_endpoint=ns.aws_ddb_endpoint, - megaphone_api_url=ns.megaphone_api_url, - megaphone_api_token=ns.megaphone_api_token, - megaphone_poll_interval=ns.megaphone_poll_interval, - resource=resource - ) diff --git a/autopush/main_argparse.py b/autopush/main_argparse.py index e8b24c7a..4843cc0c 100644 --- a/autopush/main_argparse.py +++ b/autopush/main_argparse.py @@ -232,16 +232,6 @@ def parse_connection(config_files, args): help="The client handshake timeout. Set to 0 to" "disable.", default=0, type=int, env_var="HELLO_TIMEOUT") - parser.add_argument('--megaphone_api_url', - help="The megaphone API URL to query for updates", - default=None, type=str, env_var="MEGAPHONE_API_URL") - parser.add_argument('--megaphone_api_token', - help="The megaphone API token", - default=None, type=str, env_var="MEGAPHONE_API_TOKEN") - parser.add_argument('--megaphone_poll_interval', - help="The megaphone API polling interval", - default=30, type=int, - env_var="MEGAPHONE_POLL_INTERVAL") add_shared_args(parser) return parser.parse_args(args) diff --git a/autopush/tests/test_rs_integration.py b/autopush/tests/test_rs_integration.py index 58dc3851..b7fa1749 100644 --- a/autopush/tests/test_rs_integration.py +++ b/autopush/tests/test_rs_integration.py @@ -11,17 +11,19 @@ import logging import os import re +import signal import socket +import subprocess import time -import datetime import uuid from contextlib import contextmanager from http.server import BaseHTTPRequestHandler, HTTPServer -from mock import Mock, patch from threading import Thread, Event +from queue import Queue, Empty from unittest.case import SkipTest import ecdsa +import psutil import requests import twisted.internet.base from cryptography.fernet import Fernet @@ -41,7 +43,6 @@ from autopush.main import ( ConnectionApplication, EndpointApplication, - RustConnectionApplication, ) from autopush.utils import base64url_encode from autopush.tests.support import TestingLogObserver @@ -52,17 +53,27 @@ log = logging.getLogger(__name__) +here_dir = os.path.abspath(os.path.dirname(__file__)) +root_dir = os.path.dirname(os.path.dirname(here_dir)) + twisted.internet.base.DelayedCall.debug = True ROUTER_TABLE = os.environ.get("ROUTER_TABLE", "router_int_test") MESSAGE_TABLE = os.environ.get("MESSAGE_TABLE", "message_int_test") CRYPTO_KEY = Fernet.generate_key() -CONNECTION_PORT = 9050 -ENDPOINT_PORT = 9060 -ROUTER_PORT = 9070 +CONNECTION_PORT = 9150 +ENDPOINT_PORT = 9160 +ROUTER_PORT = 9170 +MP_CONNECTION_PORT = 9052 +MP_ROUTER_PORT = 9072 +RP_CONNECTION_PORT = 9054 +RP_ROUTER_PORT = 9074 CN_SERVER = None +CN_MP_SERVER = None +MOCK_SERVER_THREAD = None +CN_QUEUES = [] def get_free_port(): @@ -73,45 +84,115 @@ def get_free_port(): return port +MOCK_MP_SERVER_PORT = get_free_port() + + +def enqueue_output(out, queue): + for line in iter(out.readline, b''): + queue.put(line) + out.close() + + def setup_module(): - global CN_SERVER + global CN_SERVER, CN_QUEUES, CN_MP_SERVER, MOCK_SERVER_THREAD logging.getLogger('boto').setLevel(logging.CRITICAL) if "SKIP_INTEGRATION" in os.environ: # pragma: nocover raise SkipTest("Skipping integration tests") - conn_defaults = dict( + conn_conf = dict( hostname='localhost', port=CONNECTION_PORT, + endpoint_hostname="localhost", endpoint_port=ENDPOINT_PORT, router_port=ROUTER_PORT, endpoint_scheme='http', - statsd_host=None, - router_table=dict(tablename=ROUTER_TABLE), - message_table=dict(tablename=MESSAGE_TABLE), - use_cryptography=True, - ) - - conn_conf = AutopushConfig( + statsd_host="", + router_tablename=ROUTER_TABLE, + message_tablename=MESSAGE_TABLE, crypto_key=CRYPTO_KEY, auto_ping_interval=60.0, auto_ping_timeout=10.0, close_handshake_timeout=5, max_connections=5000, - human_logs=False, - **conn_defaults + human_logs="false", ) + rust_bin = root_dir + "/target/release/autopush_rs" + possible_paths = ["/target/debug/autopush_rs", + "/autopush_rs/target/release/autopush_rs", + "/autopush_rs/target/debug/autopush_rs"] + while possible_paths and not os.path.exists(rust_bin): # pragma: nocover + rust_bin = root_dir + possible_paths.pop(0) + + # Setup the environment + for key, val in conn_conf.items(): + key = "autopush_" + key + os.environ[key.upper()] = str(val) + + cmd = [rust_bin] + CN_SERVER = subprocess.Popen(cmd, shell=True, env=os.environ, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + # Spin up the readers to dump the output from stdout/stderr + out_q = Queue() + t = Thread(target=enqueue_output, args=(CN_SERVER.stdout, out_q)) + t.daemon = True # thread dies with the program + t.start() + err_q = Queue() + t = Thread(target=enqueue_output, args=(CN_SERVER.stderr, err_q)) + t.daemon = True # thread dies with the program + t.start() + CN_QUEUES.extend([out_q, err_q]) + + # Megaphone API mock + MockMegaphoneRequestHandler.services = {} + MockMegaphoneRequestHandler.polled.clear() + mock_server = HTTPServer(('localhost', MOCK_MP_SERVER_PORT), + MockMegaphoneRequestHandler) + MOCK_SERVER_THREAD = Thread(target=mock_server.serve_forever) + MOCK_SERVER_THREAD.setDaemon(True) + MOCK_SERVER_THREAD.start() + + # Setup the megaphone connection node + megaphone_api_url = 'http://localhost:{port}/v1/broadcasts'.format( + port=MOCK_MP_SERVER_PORT) + conn_conf.update(dict( + port=MP_CONNECTION_PORT, + endpoint_port=ENDPOINT_PORT, + router_port=MP_ROUTER_PORT, + auto_ping_interval=0.5, + auto_ping_timeout=10.0, + close_handshake_timeout=5, + max_connections=5000, + megaphone_api_url=megaphone_api_url, + megaphone_api_token=MockMegaphoneRequestHandler.token, + megaphone_poll_interval=1, + )) - CN_SERVER = conn = RustConnectionApplication( - conn_conf, - resource=autopush.tests.boto_resource, - ) - conn.setup(rotate_tables=False, num_threads=2) - conn.startService() + # Setup the environment + for key, val in conn_conf.items(): + key = "autopush_" + key + os.environ[key.upper()] = str(val) + + cmd = [rust_bin] + CN_MP_SERVER = subprocess.Popen(cmd, shell=True, env=os.environ) + time.sleep(1) def teardown_module(): - global CN_SERVER - CN_SERVER.stopService() + global CN_SERVER, CN_MP_SERVER + # This kinda sucks, but its the only way to nuke the child procs + proc = psutil.Process(pid=CN_SERVER.pid) + child_procs = proc.children(recursive=True) + for p in [proc] + child_procs: + os.kill(p.pid, signal.SIGTERM) + CN_SERVER.wait() + + proc = psutil.Process(pid=CN_MP_SERVER.pid) + child_procs = proc.children(recursive=True) + for p in [proc] + child_procs: + os.kill(p.pid, signal.SIGTERM) + CN_MP_SERVER.wait() class MockMegaphoneRequestHandler(BaseHTTPRequestHandler): @@ -168,6 +249,17 @@ def setUp(self): ) self.start_ep(self._ep_conf) + def tearDown(self): + for queue in CN_QUEUES: + is_empty = False + while not is_empty: + try: + line = queue.get_nowait() + except Empty: + is_empty = True + else: + print(line) + def endpoint_kwargs(self): return self._endpoint_defaults @@ -749,16 +841,12 @@ def test_with_bad_key(self): class TestRustWebPushBroadcast(unittest.TestCase): - connection_port = 9052 - endpoint_port = 9060 - router_port = 9072 - _endpoint_defaults = dict( hostname='localhost', - port=endpoint_port, - endpoint_port=endpoint_port, + port=ENDPOINT_PORT, + endpoint_port=ENDPOINT_PORT, endpoint_scheme='http', - router_port=router_port, + router_port=MP_ROUTER_PORT, statsd_host=None, router_table=dict(tablename=ROUTER_TABLE), message_table=dict(tablename=MESSAGE_TABLE), @@ -767,9 +855,9 @@ class TestRustWebPushBroadcast(unittest.TestCase): _conn_defaults = dict( hostname='localhost', - port=connection_port, - endpoint_port=endpoint_port, - router_port=router_port, + port=RP_CONNECTION_PORT, + endpoint_port=ENDPOINT_PORT, + router_port=RP_ROUTER_PORT, endpoint_scheme='http', statsd_host=None, router_table=dict(tablename=ROUTER_TABLE), @@ -788,54 +876,42 @@ def start_ep(self, ep_conf): ep.startService() self.addCleanup(ep.stopService) - def start_conn(self, conn_conf): - self.conn = conn = RustConnectionApplication( - conn_conf, - resource=autopush.tests.boto_resource, - ) - conn.setup(rotate_tables=False, num_threads=2) - conn.startService() - self.addCleanup(conn.stopService) - def setUp(self): - # Megaphone API mock - mock_server_port = get_free_port() - MockMegaphoneRequestHandler.services = {} - MockMegaphoneRequestHandler.polled.clear() - mock_server = HTTPServer(('localhost', mock_server_port), - MockMegaphoneRequestHandler) - mock_server_thread = Thread(target=mock_server.serve_forever) - mock_server_thread.setDaemon(True) - mock_server_thread.start() - self.addCleanup(mock_server.shutdown) - self.mock_server_thread = mock_server_thread + self.mock_server_thread = MOCK_SERVER_THREAD self.mock_megaphone = MockMegaphoneRequestHandler self.logs = TestingLogObserver() begin_or_register(self.logs) self.addCleanup(globalLogPublisher.removeObserver, self.logs) - megaphone_api_url = 'http://localhost:{port}/v1/broadcasts'.format( - port=mock_server.server_port) - self._ep_conf = AutopushConfig( crypto_key=CRYPTO_KEY, **self.endpoint_kwargs() ) + + self.start_ep(self._ep_conf) + + # Create a Python connection application for accessing the db self._conn_conf = AutopushConfig( crypto_key=CRYPTO_KEY, - auto_ping_interval=0.5, - auto_ping_timeout=10.0, - close_handshake_timeout=5, - max_connections=5000, - megaphone_api_url=megaphone_api_url, - megaphone_api_token=MockMegaphoneRequestHandler.token, - megaphone_poll_interval=1, **self.conn_kwargs() ) - - self.start_ep(self._ep_conf) - self.start_conn(self._conn_conf) + self.conn = conn = ConnectionApplication( + self._conn_conf, + resource=autopush.tests.boto_resource, + ) + conn.setup(rotate_tables=True) + + def tearDown(self): + for queue in CN_QUEUES: + is_empty = False + while not is_empty: + try: + line = queue.get_nowait() + except Empty: + is_empty = True + else: + print(line) def endpoint_kwargs(self): return self._endpoint_defaults @@ -845,7 +921,7 @@ def conn_kwargs(self): @inlineCallbacks def quick_register(self, sslcontext=None, connection_port=None): - conn_port = connection_port or self.connection_port + conn_port = connection_port or MP_CONNECTION_PORT client = Client("ws://localhost:{}/".format(conn_port), sslcontext=sslcontext) yield client.connect() @@ -866,13 +942,13 @@ def legacy_endpoint(self): @property def _ws_url(self): - return "ws://localhost:{}/".format(self.connection_port) + return "ws://localhost:{}/".format(MP_CONNECTION_PORT) @inlineCallbacks def test_broadcast_update_on_connect(self): self.mock_megaphone.services = {"kinto:123": "ver1"} self.mock_megaphone.polled.clear() - self.mock_megaphone.polled.wait() + self.mock_megaphone.polled.wait(timeout=5) old_ver = {"kinto:123": "ver0"} client = Client(self._ws_url) @@ -884,7 +960,7 @@ def test_broadcast_update_on_connect(self): self.mock_megaphone.services = {"kinto:123": "ver2"} self.mock_megaphone.polled.clear() - self.mock_megaphone.polled.wait() + self.mock_megaphone.polled.wait(timeout=5) result = yield client.get_broadcast(2) assert result["broadcasts"]["kinto:123"] == "ver2" @@ -895,7 +971,7 @@ def test_broadcast_update_on_connect(self): def test_broadcast_subscribe(self): self.mock_megaphone.services = {"kinto:123": "ver1"} self.mock_megaphone.polled.clear() - self.mock_megaphone.polled.wait() + self.mock_megaphone.polled.wait(timeout=5) old_ver = {"kinto:123": "ver0"} client = Client(self._ws_url) @@ -911,7 +987,7 @@ def test_broadcast_subscribe(self): self.mock_megaphone.services = {"kinto:123": "ver2"} self.mock_megaphone.polled.clear() - self.mock_megaphone.polled.wait() + self.mock_megaphone.polled.wait(timeout=5) result = yield client.get_broadcast(2) assert result["broadcasts"]["kinto:123"] == "ver2" @@ -922,7 +998,7 @@ def test_broadcast_subscribe(self): def test_broadcast_no_changes(self): self.mock_megaphone.services = {"kinto:123": "ver1"} self.mock_megaphone.polled.clear() - self.mock_megaphone.polled.wait() + self.mock_megaphone.polled.wait(timeout=5) old_ver = {"kinto:123": "ver1"} client = Client(self._ws_url) @@ -934,43 +1010,6 @@ def test_broadcast_no_changes(self): yield self.shut_down(client) - @inlineCallbacks - def test_no_rotation(self): - # override autopush settings - ep_safe = self._ep_conf.allow_table_rotation - conn_safe = self._conn_conf.allow_table_rotation - self._ep_conf.allow_table_rotation = False - self._conn_conf.allow_table_rotation = False - yield self.ep.stopService() - yield self.conn.stopService() - try: - self.start_ep(self._ep_conf) - self.start_conn(self._conn_conf) - data = str(uuid.uuid4()) - client = yield self.quick_register() - result = yield client.send_notification(data=data) - assert result["headers"]["encryption"] == client._crypto_key - assert result["data"] == base64url_encode(data) - assert result["messageType"] == "notification" - - assert len(self.ep.db.message_tables) == 1 - table_name = self.ep.db.message_tables[0] - target_day = datetime.date(2016, 2, 29) - with patch.object(datetime, 'date', - Mock(wraps=datetime.date)) as patched: - patched.today.return_value = target_day - yield self.ep.db.update_rotating_tables() - assert len(self.ep.db.message_tables) == 1 - assert table_name == self.ep.db.message_tables[0] - finally: - yield self.ep.stopService() - yield self.conn.stopService() - self._ep_conf.allow_table_rotation = ep_safe - self._conn_conf.allow_table_rotation = conn_safe - self.start_ep(self._ep_conf) - self.start_conn(self._conn_conf) - yield self.shut_down(client) - @inlineCallbacks def test_webpush_monthly_rotation(self): from autopush.db import make_rotating_tablename @@ -1184,7 +1223,7 @@ def test_webpush_monthly_rotation_prior_record_exists(self): @inlineCallbacks def test_webpush_monthly_rotation_no_channels(self): from autopush.db import make_rotating_tablename - client = Client("ws://localhost:{}/".format(self.connection_port)) + client = Client("ws://localhost:{}/".format(MP_CONNECTION_PORT)) yield client.connect() yield client.hello() yield client.disconnect() @@ -1236,16 +1275,12 @@ def test_webpush_monthly_rotation_no_channels(self): class TestRustAndPythonWebPush(unittest.TestCase): - connection_port = 9052 - endpoint_port = 9060 - router_port = 9072 - _endpoint_defaults = dict( hostname='localhost', - port=endpoint_port, - endpoint_port=endpoint_port, + port=ENDPOINT_PORT, + endpoint_port=ENDPOINT_PORT, endpoint_scheme='http', - router_port=router_port, + router_port=RP_ROUTER_PORT, statsd_host=None, router_table=dict(tablename=ROUTER_TABLE), message_table=dict(tablename=MESSAGE_TABLE), @@ -1254,9 +1289,9 @@ class TestRustAndPythonWebPush(unittest.TestCase): _conn_defaults = dict( hostname='localhost', - port=connection_port, - endpoint_port=endpoint_port, - router_port=router_port, + port=RP_CONNECTION_PORT, + endpoint_port=ENDPOINT_PORT, + router_port=RP_ROUTER_PORT, endpoint_scheme='http', statsd_host=None, router_table=dict(tablename=ROUTER_TABLE), @@ -1303,6 +1338,17 @@ def setUp(self): self.start_ep(self._ep_conf) self.start_conn(self._conn_conf) + def tearDown(self): + for queue in CN_QUEUES: + is_empty = False + while not is_empty: + try: + line = queue.get_nowait() + except Empty: + is_empty = True + else: + print(line) + def endpoint_kwargs(self): return self._endpoint_defaults @@ -1311,7 +1357,7 @@ def conn_kwargs(self): @inlineCallbacks def quick_register(self, sslcontext=None, connection_port=None): - conn_port = connection_port or self.connection_port + conn_port = connection_port or RP_CONNECTION_PORT client = Client("ws://localhost:{}/".format(conn_port), sslcontext=sslcontext) yield client.connect() @@ -1324,17 +1370,13 @@ def shut_down(self, client=None): if client: yield client.disconnect() - @property - def _ws_url(self): - return "ws://localhost:{}/".format(self.connection_port) - @inlineCallbacks def test_cross_topic_no_delivery_on_reconnect(self): data = str(uuid.uuid4()) client = yield self.quick_register(connection_port=CONNECTION_PORT) yield client.disconnect() yield client.send_notification(data=data, topic="Inbox") - yield client.connect(connection_port=self.connection_port) + yield client.connect(connection_port=RP_CONNECTION_PORT) yield client.hello() result = yield client.get_notification(timeout=10) assert result["headers"]["encryption"] == client._crypto_key @@ -1347,7 +1389,7 @@ def test_cross_topic_no_delivery_on_reconnect(self): result = yield client.get_notification(0.5) assert result is None yield client.disconnect() - yield client.connect(connection_port=self.connection_port) + yield client.connect(connection_port=RP_CONNECTION_PORT) yield client.hello() result = yield client.get_notification(0.5) assert result is None @@ -1367,7 +1409,7 @@ def test_cross_topic_no_delivery_on_reconnect_reverse(self): assert result["messageType"] == "notification" yield client.ack(result["channelID"], result["version"]) yield client.disconnect() - yield client.connect(connection_port=self.connection_port) + yield client.connect(connection_port=RP_CONNECTION_PORT) yield client.hello() result = yield client.get_notification(0.5) assert result is None diff --git a/autopush/webpush_server.py b/autopush/webpush_server.py deleted file mode 100644 index edde690e..00000000 --- a/autopush/webpush_server.py +++ /dev/null @@ -1,39 +0,0 @@ -"""WebPush Server - -""" -from twisted.logger import Logger - -from autopush.db import ( # noqa - DatabaseManager, -) - -from autopush.config import AutopushConfig # noqa -from autopush_rs import AutopushServer # noqa - -log = Logger() - -# sentinel objects -_STOP = object() - - -############################################################################### -# Main push server class -############################################################################### -class WebPushServer(object): - def __init__(self, conf, db, num_threads=10): - # type: (AutopushConfig, DatabaseManager, int) -> None - self.conf = conf - self.db = db - self.db.setup_tables() - self.num_threads = num_threads - self.rust = AutopushServer(conf, db.message_tables) - self.running = False - - def start(self): - # type: () -> None - self.running = True - self.rust.startService() - - def stop(self): - self.running = False - self.rust.stopService() diff --git a/autopush_rs/Cargo.toml b/autopush_rs/Cargo.toml index c3477a4e..5e8b3177 100644 --- a/autopush_rs/Cargo.toml +++ b/autopush_rs/Cargo.toml @@ -1,20 +1,31 @@ [package] name = "autopush" version = "0.1.0" -authors = ["Alex Crichton "] +authors = [ + "Ben Bangert ", + "JR Conlin ", + "Alex Crichton ", + "Phil Jenvey ", +] [lib] name = "autopush" -crate-type = ["cdylib"] -[build-dependencies] -cbindgen = "0.6.0" +[[bin]] +name = "autopush_rs" +path = "src/main.rs" + +[dependencies.config] +git = "https://github.com/mehcode/config-rs" +rev = "e8fa9fee96185ddd18ebcef8a925c75459111edb" [dependencies] base64 = "0.9.1" bytes = "0.4.6" cadence = "0.13.2" +chan-signal = "0.3.1" chrono = "0.4.2" +docopt = "1.0.0" env_logger = { version = "0.5.6", default-features = false } error-chain = "0.11.0" fernet = "0.1" @@ -40,7 +51,6 @@ rusoto_credential = "0.11.0" rusoto_dynamodb = "0.32.0" sentry = "0.2.0" serde = "1.0.45" -# Pinned to 1.0.21 due to cbindgen serde_derive = "1.0.21" serde_dynamodb = "0.1.2" serde_json = "1.0.13" diff --git a/autopush_rs/__init__.py b/autopush_rs/__init__.py deleted file mode 100644 index 70644357..00000000 --- a/autopush_rs/__init__.py +++ /dev/null @@ -1,107 +0,0 @@ -from autopush_rs._native import ffi, lib - - -def ffi_from_buffer(s): - if s is None: - return ffi.NULL - else: - return ffi.from_buffer(s) - - -def free(obj, free_fn): - if obj.ffi is None: - return - ffi.gc(obj.ffi, None) - free_fn(obj.ffi) - obj.ffi = None - - -class AutopushServer(object): - def __init__(self, conf, message_tables): - # type: (AutopushConfig, List[str]) -> AutopushServer - cfg = ffi.new('AutopushServerOptions*') - cfg.auto_ping_interval = conf.auto_ping_interval - cfg.auto_ping_timeout = conf.auto_ping_timeout - cfg.close_handshake_timeout = conf.close_handshake_timeout - cfg.max_connections = conf.max_connections - cfg.open_handshake_timeout = 5 - cfg.port = conf.port - cfg.router_port = conf.router_port - cfg.router_url = ffi_from_buffer(conf.router_url) - cfg.endpoint_url = ffi_from_buffer(conf.endpoint_url) - self.crypto_key = ','.join(name.encode('utf-8') for name in - conf._crypto_key) - cfg.crypto_key = ffi_from_buffer(self.crypto_key) - cfg.ssl_cert = ffi_from_buffer(conf.ssl.cert) - cfg.ssl_dh_param = ffi_from_buffer(conf.ssl.dh_param) - cfg.ssl_key = ffi_from_buffer(conf.ssl.key) - cfg.json_logging = not conf.human_logs - cfg.statsd_host = ffi_from_buffer(conf.statsd_host) - cfg.statsd_port = conf.statsd_port - cfg.router_table_name = ffi_from_buffer(conf.router_table.tablename) - # XXX: keepalive - self.message_table_names = ','.join(name.encode('utf-8') for name in - message_tables) - cfg.message_table_names = ffi_from_buffer(self.message_table_names) - cfg.megaphone_api_url = ffi_from_buffer(conf.megaphone_api_url) - cfg.megaphone_api_token = ffi_from_buffer(conf.megaphone_api_token) - cfg.megaphone_poll_interval = conf.megaphone_poll_interval - - ptr = _call(lib.autopush_server_new, cfg) - self.ffi = ffi.gc(ptr, lib.autopush_server_free) - - def startService(self): - _call(lib.autopush_server_start, - self.ffi) - - def stopService(self): - if self.ffi is None: - return - _call(lib.autopush_server_stop, self.ffi) - self._free_ffi() - - def _free_ffi(self): - free(self, lib.autopush_server_free) - - -last_err = None - - -def _call(f, *args): - # We cache errors across invocations of `_call` to avoid allocating a new - # error each time we call an FFI function. Each function call, however, - # needs a unique error, so take the global `last_err`, lazily initializing - # it if necessary. - global last_err - my_err = last_err - last_err = None - if my_err is None: - my_err = ffi.new('AutopushError*') - - # The error pointer is always the last argument, so pass that in and call - # the actual FFI function. If the return value is nonzero then it was a - # successful call and we can put our error back into the global slot - # and return. - args = args + (my_err,) - ret = f(*args) - if ffi.cast('size_t', ret) != 0: - last_err = my_err - return ret - - # If an error happened then it means that the Rust side of things panicked - # which we need to handle here. Acquire the string from the error, if - # available, and re-raise as a python `RuntimeError`. - # - # Note that we're also careful here to clean up the error's internals to - # avoid memory leaks and then once we're completely done we can restore our - # local error to its global position. - errln = lib.autopush_error_msg_len(my_err); - if errln > 0: - ptr = lib.autopush_error_msg_ptr(my_err) - msg = 'rust panic: ' + ffi.buffer(ptr, errln)[:] - exn = RuntimeError(msg) - else: - exn = RuntimeError('unknown error in rust') - lib.autopush_error_cleanup(my_err) - last_err = my_err - raise exn diff --git a/autopush_rs/build.rs b/autopush_rs/build.rs deleted file mode 100644 index b3d5b6cf..00000000 --- a/autopush_rs/build.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Generate autopush.h via cbindgen -extern crate cbindgen; - -use std::{env, fs, path::PathBuf}; - -fn main() { - let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR undefined"); - let pkg_name = env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME undefined"); - let target = PathBuf::from(format!("{}/target/{}.h", crate_dir, pkg_name)); - - let result = cbindgen::Builder::new() - .with_crate(crate_dir) - .with_language(cbindgen::Language::C) - .generate(); - match result { - Ok(bindings) => { - bindings.write_to_file(target); - } - Err(e) => { - eprintln!("cbindgen unable to generate bindings: {}", e); - if target.exists() { - fs::remove_file(target).unwrap(); - } - } - } -} diff --git a/autopush_rs/src/db/commands.rs b/autopush_rs/src/db/commands.rs index 6ae69d78..b5badf7a 100644 --- a/autopush_rs/src/db/commands.rs +++ b/autopush_rs/src/db/commands.rs @@ -9,8 +9,8 @@ use futures::{future, Future}; use futures_backoff::retry_if; use rusoto_dynamodb::{ AttributeValue, DeleteItemError, DeleteItemInput, DeleteItemOutput, DynamoDb, GetItemError, - GetItemInput, GetItemOutput, PutItemError, PutItemInput, PutItemOutput, QueryError, QueryInput, - UpdateItemError, UpdateItemInput, UpdateItemOutput, + GetItemInput, GetItemOutput, ListTablesInput, ListTablesOutput, PutItemError, PutItemInput, + PutItemOutput, QueryError, QueryInput, UpdateItemError, UpdateItemInput, UpdateItemOutput, }; use serde_dynamodb; @@ -35,6 +35,18 @@ fn has_connected_this_month(user: &DynamoDbUser) -> bool { }) } +pub fn list_tables( + ddb: Rc>, + start_key: Option, +) -> impl Future { + let input = ListTablesInput { + exclusive_start_table_name: start_key, + limit: Some(100), + }; + ddb.list_tables(&input) + .chain_err(|| "Unable to list tables") +} + pub fn fetch_messages( ddb: Rc>, table_name: &str, diff --git a/autopush_rs/src/db/mod.rs b/autopush_rs/src/db/mod.rs index 2a61ea5d..e003bc23 100644 --- a/autopush_rs/src/db/mod.rs +++ b/autopush_rs/src/db/mod.rs @@ -81,6 +81,26 @@ impl DynamoStorage { Self { ddb: Rc::new(ddb) } } + pub fn list_message_tables(&self, prefix: &str) -> Result> { + let mut names: Vec = Vec::new(); + let mut start_key = None; + loop { + let result = commands::list_tables(self.ddb.clone(), start_key).wait()?; + start_key = result.last_evaluated_table_name; + if let Some(table_names) = result.table_names { + names.extend(table_names); + } + if start_key.is_none() { + break; + } + } + let names = names + .into_iter() + .filter(|name| name.starts_with(prefix)) + .collect(); + Ok(names) + } + pub fn increment_storage( &self, table_name: &str, diff --git a/autopush_rs/src/errors.rs b/autopush_rs/src/errors.rs index 81dd765e..fed9943b 100644 --- a/autopush_rs/src/errors.rs +++ b/autopush_rs/src/errors.rs @@ -29,6 +29,7 @@ use std::io; use std::num; use cadence; +use config; use futures::Future; use httparse; use sentry; @@ -46,6 +47,7 @@ error_chain! { SentryError(sentry::Error); UuidParseError(uuid::ParseError); ParseIntError(num::ParseIntError); + ConfigError(config::ConfigError); } errors { diff --git a/autopush_rs/src/lib.rs b/autopush_rs/src/lib.rs index f156d9e0..b99d70df 100644 --- a/autopush_rs/src/lib.rs +++ b/autopush_rs/src/lib.rs @@ -62,7 +62,10 @@ extern crate base64; extern crate bytes; extern crate cadence; +extern crate chan_signal; extern crate chrono; +extern crate config; +extern crate docopt; extern crate fernet; #[macro_use] extern crate futures; @@ -116,11 +119,10 @@ extern crate error_chain; #[macro_use] mod db; mod client; -mod errors; +pub mod errors; mod http; mod protocol; -#[macro_use] -pub mod rt; pub mod server; +pub mod settings; #[macro_use] mod util; diff --git a/autopush_rs/src/main.rs b/autopush_rs/src/main.rs new file mode 100644 index 00000000..d0db4508 --- /dev/null +++ b/autopush_rs/src/main.rs @@ -0,0 +1,53 @@ +#[macro_use] +extern crate serde_derive; +extern crate autopush; +extern crate chan_signal; +extern crate docopt; + +use std::env; + +use chan_signal::Signal; +use docopt::Docopt; + +use autopush::errors::{Result, ResultExt}; +use autopush::server::{AutopushServer, ServerOptions}; +use autopush::settings::Settings; + +const USAGE: &'static str = " +Usage: autopush_rs [options] + +Options: + -h, --help Show this message. + --config-connection=CONFIGFILE Connection confiruation file path. + --config-shared=CONFIGFILE Common configuration file path. +"; + +#[derive(Debug, Deserialize)] +struct Args { + flag_config_connection: Option, + flag_config_shared: Option, +} + +fn main() -> Result<()> { + let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]); + let args: Args = Docopt::new(USAGE) + .and_then(|d| d.deserialize()) + .unwrap_or_else(|e| e.exit()); + let mut filenames = Vec::new(); + if let Some(shared_filename) = args.flag_config_shared { + filenames.push(shared_filename); + } + if let Some(config_filename) = args.flag_config_connection { + filenames.push(config_filename); + } + let settings = Settings::with_env_and_config_files(&filenames)?; + // Setup the AWS env var if it was set + if let Some(ref ddb_local) = settings.aws_ddb_endpoint { + env::set_var("AWS_LOCAL_DYNAMODB", ddb_local); + } + let server_opts = ServerOptions::from_settings(settings)?; + let server = AutopushServer::new(server_opts); + server.start(); + signal.recv().unwrap(); + server.stop().chain_err(|| "Failed to shutdown properly") +} diff --git a/autopush_rs/src/rt.rs b/autopush_rs/src/rt.rs deleted file mode 100644 index 62494792..00000000 --- a/autopush_rs/src/rt.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Runtime support for calling in and out of Python -//! -//! This module provides a number of utilities for interfacing with Python in a -//! safe fashion. It's primarily used to handle *panics* in Rust which otherwise -//! could cause segfaults or strange crashes if otherwise unhandled. -//! -//! The current protocol for Python calling into Rust looks like so: -//! -//! * Primarily, all panics are caught in Rust. Panics are intended to be -//! translated to exceptions in Python to indicate a fatal error happened in -//! Rust. -//! -//! * Almost all FFI functions take a `&mut AutopushError` as their last -//! argument. This argument is used to capture the reason of a panic so it can -//! later be introspected in Python to generate a runtime assertion. The -//! handling of `AutopushError` is intended to be relatively transparent by -//! just needing to pass it to some functions in this module. -//! -//! * A `UnwindGuard` is provided for stateful objects persisted across FFI -//! function calls. If a Rust function panics it's typically not intended to -//! be rerun at a later date with the same arguments, so what `UnwindGuard` -//! will do is only provide access to the internals *until* a panic happens. -//! After a panic then access to the internals will be gated and forbidden -//! until destruction. This should help prevent bugs from becoming worse bugs -//! quickly (in theory). -//! -//! All Rust objects shared with Python have an `UnwindGuard` internally which -//! protects all of the state that Rust is fiddling with. -//! -//! Typically you can just look at some other examples of `#[no_mangle]` -//! functions throughout this crate and copy those idioms, otherwise there's -//! documentation on each specific function here. - -use std::any::Any; -use std::cell::Cell; -use std::mem; -use std::panic; -use std::ptr; - -/// Generic error which is used on all function calls from Python into Rust. -/// -/// This is allocated in Python and reused across function calls when possible. -/// It effectively stores a `Box` which is what's created whenever a Rust -/// thread panics. This `Box` may store an object, a string, etc. -#[repr(C)] -pub struct AutopushError { - p1: usize, - p2: usize, -} - -impl AutopushError { - /// Attempts to extract the error message out of this inernal `Box`. - /// This may fail if the `Any` doesn't look like it can be stringified - /// though. - fn string(&self) -> Option<&str> { - assert!(self.p1 != 0); - assert!(self.p2 != 0); - let any: &Any = unsafe { mem::transmute((self.p1, self.p2)) }; - // Similar to what libstd does, only check for `&'static str` and - // `String`. - any.downcast_ref::<&'static str>() - .map(|s| &s[..]) - .or_else(|| any.downcast_ref::().map(|s| &s[..])) - } - - fn assert_empty(&self) { - assert_eq!(self.p1, 0); - assert_eq!(self.p2, 0); - } - - fn fill(&mut self, any: Box) { - self.assert_empty(); - unsafe { - let ptrs: (usize, usize) = mem::transmute(any); - self.p1 = ptrs.0; - self.p2 = ptrs.1; - } - } - - /// Deallocates the internal `Box`, freeing the resources behind it. - unsafe fn cleanup(&mut self) { - mem::transmute::<_, Box>((self.p1, self.p2)); - self.p1 = 0; - self.p2 = 0; - } -} - -/// Acquires the length of the error message in this error, or returns 0 if -/// there is no error message. -#[no_mangle] -pub extern "C" fn autopush_error_msg_len(err: *const AutopushError) -> usize { - abort_on_panic(|| unsafe { (*err).string().map_or(0, |s| s.len()) }) -} - -/// Returns the data pointer of the error message, if any. If not present -/// returns null. -#[no_mangle] -pub extern "C" fn autopush_error_msg_ptr(err: *const AutopushError) -> *const u8 { - abort_on_panic(|| unsafe { (*err).string().map_or(ptr::null(), |s| s.as_ptr()) }) -} - -/// Deallocates the internal `Box`, freeing any resources it contains. -/// -/// The error itself can continue to be reused for future function calls. -#[no_mangle] -pub unsafe extern "C" fn autopush_error_cleanup(err: *mut AutopushError) { - abort_on_panic(|| { - (&mut *err).cleanup(); - }); -} - -/// Helper structure to provide "unwind safety" to ensure we don't reuse values -/// accidentally after a panic. -pub struct UnwindGuard { - poisoned: Cell, - inner: T, -} - -impl UnwindGuard { - pub fn new(t: T) -> UnwindGuard { - Self { - poisoned: Cell::new(false), - inner: t, - } - } - - /// This function is intended to be immediately called in an FFI callback, - /// and will execute the closure `f` catching panics. - /// - /// The `err` provided will be filled in if the function panics. - /// - /// The closure `f` will execute with the state this `UnwindGuard` is - /// internally protecting, allowing it shared access to the various pieces. - /// The closure's return value is then also automatically converted to an - /// FFI-safe value through the `AbiInto` trait. Various impls for this trait - /// can be found below (possible types to return). - /// - /// Note that if this `UnwindGuard` previously caught a panic then the - /// closure `f` will not be executed. This function will immediately return - /// with the "null" return value to propagate the panic again. - pub fn catch(&self, err: &mut AutopushError, f: F) -> R::AbiRet - where - F: FnOnce(&T) -> R, - R: AbiInto, - { - err.assert_empty(); - if self.poisoned.get() { - err.fill(Box::new(String::from("accessing poisoned object"))); - return R::null(); - } - - // The usage of `AssertUnwindSafe` should be ok here because as - // soon as we see this closure panic we'll disallow all further - // access to the internals of `self`. - let mut panicked = true; - let ret = catch( - err, - panic::AssertUnwindSafe(|| { - let ret = f(&self.inner); - panicked = false; - ret - }), - ); - if panicked { - self.poisoned.set(true); - } - ret - } -} - -/// Catches a panic within the closure `f`, filling in `err` if a panic happens. -/// -/// This is typically only used for constructors where there's no state -/// persisted across calls. -pub fn catch(err: &mut AutopushError, f: F) -> T::AbiRet -where - F: panic::UnwindSafe + FnOnce() -> T, - T: AbiInto, -{ - err.assert_empty(); - - match panic::catch_unwind(f) { - Ok(t) => t.abi_into(), - Err(e) => unsafe { - let ptrs: (usize, usize) = mem::transmute(e); - err.p1 = ptrs.0; - err.p2 = ptrs.1; - T::null() - }, - } -} - -/// Helper to *abort* on panics rather than catch them and communicate to -/// python. -/// -/// This should be rarely used but is used when executing destructors in Rust, -/// which should be infallible (and this is just a double-check that they are). -pub fn abort_on_panic(f: F) -> R -where - F: FnOnce() -> R, -{ - struct Bomb { - active: bool, - } - - impl Drop for Bomb { - fn drop(&mut self) { - if self.active { - panic!("unexpected panic, aborting process"); - } - } - } - - let mut bomb = Bomb { active: true }; - let r = f(); - bomb.active = false; - r -} - -pub trait AbiInto { - type AbiRet; - - fn abi_into(self) -> Self::AbiRet; - fn null() -> Self::AbiRet; -} - -impl AbiInto for () { - type AbiRet = i32; - - fn abi_into(self) -> i32 { - 1 - } - - fn null() -> i32 { - 0 - } -} - -impl AbiInto for Box { - type AbiRet = *mut T; - - fn abi_into(self) -> *mut T { - Self::into_raw(self) - } - - fn null() -> *mut T { - ptr::null_mut() - } -} - -impl AbiInto for Option> { - type AbiRet = *mut T; - - fn abi_into(self) -> *mut T { - match self { - Some(b) => Box::into_raw(b), - None => 1 as *mut T, - } - } - - fn null() -> *mut T { - ptr::null_mut() - } -} - -impl AbiInto for *const T { - type AbiRet = *const T; - - fn abi_into(self) -> *const T { - self - } - - fn null() -> *const T { - ptr::null() - } -} - -impl AbiInto for *mut T { - type AbiRet = *mut T; - - fn abi_into(self) -> *mut T { - self - } - - fn null() -> *mut T { - ptr::null_mut() - } -} - -impl AbiInto for usize { - type AbiRet = usize; - - fn abi_into(self) -> usize { - self + 1 - } - - fn null() -> usize { - 0 - } -} diff --git a/autopush_rs/src/server/mod.rs b/autopush_rs/src/server/mod.rs index 9a39ed81..6a0f0ac5 100644 --- a/autopush_rs/src/server/mod.rs +++ b/autopush_rs/src/server/mod.rs @@ -2,7 +2,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::default::Default; use std::env; -use std::ffi::CStr; use std::io; use std::net::SocketAddr; use std::panic; @@ -22,7 +21,6 @@ use futures::{Async, AsyncSink, Future, Poll, Sink, StartSend, Stream}; use hex; use hyper::server::Http; use hyper::{self, header, StatusCode}; -use libc::c_char; use openssl::hash; use openssl::ssl::SslAcceptor; use reqwest; @@ -33,22 +31,23 @@ use tokio_core::net::TcpListener; use tokio_core::reactor::{Core, Handle, Timeout}; use tokio_io; use tokio_tungstenite::{accept_hdr_async, WebSocketStream}; -use tungstenite::Message; use tungstenite::handshake::server::Request; +use tungstenite::Message; use uuid::Uuid; use client::{Client, RegisteredClient}; +use db::DynamoStorage; use errors::*; use errors::{Error, Result}; use http; use protocol::{ClientMessage, Notification, ServerMessage, ServerNotification}; -use rt::{self, AutopushError, UnwindGuard}; use server::dispatch::{Dispatch, RequestType}; use server::metrics::metrics_from_opts; use server::webpush_io::WebpushIo; -use db::DynamoStorage; -use util::megaphone::{ClientServices, MegaphoneAPIResponse, Service, ServiceChangeTracker, - ServiceClientInit}; +use settings::Settings; +use util::megaphone::{ + ClientServices, MegaphoneAPIResponse, Service, ServiceChangeTracker, ServiceClientInit, +}; use util::{self, timeout, RcObject}; mod dispatch; @@ -58,54 +57,62 @@ mod webpush_io; const UAHEADER: &str = "User-Agent"; -pub struct AutopushServer { - inner: UnwindGuard, +fn ito_dur(seconds: u32) -> Option { + if seconds == 0 { + None + } else { + Some(Duration::new(seconds.into(), 0)) + } +} + +fn fto_dur(seconds: f64) -> Option { + if seconds == 0.0 { + None + } else { + Some(Duration::new( + seconds as u64, + (seconds.fract() * 1_000_000_000.0) as u32, + )) + } } // a signaler to shut down a tokio Core and its associated thread struct ShutdownHandle(oneshot::Sender<()>, thread::JoinHandle<()>); -struct AutopushServerInner { +pub struct AutopushServer { opts: Arc, - // Used when shutting down a server shutdown_handles: Cell>>, } -#[repr(C)] -pub struct AutopushServerOptions { - pub debug: i32, - pub router_port: u16, - pub port: u16, - pub ssl_key: *const c_char, - pub ssl_cert: *const c_char, - pub ssl_dh_param: *const c_char, - pub open_handshake_timeout: u32, - pub auto_ping_interval: f64, - pub auto_ping_timeout: f64, - pub max_connections: u32, - pub close_handshake_timeout: u32, - pub json_logging: i32, - pub message_table_names: *const c_char, - pub router_table_name: *const c_char, - pub router_url: *const c_char, - pub endpoint_url: *const c_char, - pub crypto_key: *const c_char, - pub statsd_host: *const c_char, - pub statsd_port: u16, - pub megaphone_api_url: *const c_char, - pub megaphone_api_token: *const c_char, - pub megaphone_poll_interval: u32, -} +impl AutopushServer { + pub fn new(opts: ServerOptions) -> Self { + Self { + opts: Arc::new(opts), + shutdown_handles: Cell::new(None), + } + } -pub struct Server { - uaids: RefCell>, - broadcaster: RefCell, - pub ddb: DynamoStorage, - open_connections: Cell, - tls_acceptor: Option, - pub opts: Arc, - pub handle: Handle, - pub metrics: StatsdClient, + pub fn start(&self) { + util::init_logging(!self.opts.human_logs); + let handles = Server::start(&self.opts).expect("failed to start server"); + self.shutdown_handles.set(Some(handles)); + } + + /// Blocks execution of the calling thread until the helper thread with the + /// tokio reactor has exited. + pub fn stop(&self) -> Result<()> { + let mut result = Ok(()); + if let Some(shutdown_handles) = self.shutdown_handles.take() { + for ShutdownHandle(tx, thread) in shutdown_handles { + let _ = tx.send(()); + if let Err(err) = thread.join() { + result = Err(From::from(ErrorKind::Thread(err))); + } + } + } + util::reset_logging(); + result + } } pub struct ServerOptions { @@ -131,163 +138,79 @@ pub struct ServerOptions { pub megaphone_api_url: Option, pub megaphone_api_token: Option, pub megaphone_poll_interval: Duration, + pub human_logs: bool, } -#[no_mangle] -pub extern "C" fn autopush_server_new( - opts: *const AutopushServerOptions, - err: &mut AutopushError, -) -> *mut AutopushServer { - unsafe fn to_s<'a>(ptr: *const c_char) -> Option<&'a str> { - if ptr.is_null() { - return None; - } - let s = CStr::from_ptr(ptr).to_str().expect("invalid utf-8"); - if s.is_empty() { - None - } else { - Some(s) - } - } - - unsafe fn ito_dur(seconds: u32) -> Option { - if seconds == 0 { - None - } else { - Some(Duration::new(seconds.into(), 0)) - } - } - - unsafe fn fto_dur(seconds: f64) -> Option { - if seconds == 0.0 { - None - } else { - Some(Duration::new( - seconds as u64, - (seconds.fract() * 1_000_000_000.0) as u32, - )) - } - } - - rt::catch(err, || unsafe { - let opts = &*opts; - - util::init_logging(opts.json_logging != 0); - let fernets: Vec = to_s(opts.crypto_key) - .map(|s| s.to_string()) - .expect("crypto_key must be specified") +impl ServerOptions { + pub fn from_settings(settings: Settings) -> Result { + let fernets: Vec = settings + .crypto_key .split(',') .map(|s| s.trim().to_string()) .map(|key| Fernet::new(&key).expect("Invalid key supplied")) .collect(); let fernet = MultiFernet::new(fernets); - let mut opts = ServerOptions { - debug: opts.debug != 0, - port: opts.port, + let ddb = DynamoStorage::new(); + let message_table_names = ddb + .list_message_tables(&settings.message_tablename) + .expect("Failed to locate message tables"); + let router_url = settings.router_url(); + let endpoint_url = settings.endpoint_url(); + let mut opts = Self { + debug: settings.debug, + port: settings.port, fernet, - router_port: opts.router_port, - statsd_host: to_s(opts.statsd_host).map(|s| s.to_string()), - statsd_port: opts.statsd_port, - message_table_names: to_s(opts.message_table_names) - .map(|s| s.to_string()) - .expect("message table names must be specified") - .split(',') - .map(|s| s.trim().to_string()) - .collect(), + router_port: settings.router_port, + statsd_host: if settings.statsd_host.is_empty() { + None + } else { + Some(settings.statsd_host) + }, + statsd_port: settings.statsd_port, + message_table_names, current_message_month: "".to_string(), - router_table_name: to_s(opts.router_table_name) - .map(|s| s.to_string()) - .expect("router table name must be specified"), - router_url: to_s(opts.router_url) - .map(|s| s.to_string()) - .expect("router url must be specified"), - endpoint_url: to_s(opts.endpoint_url) - .map(|s| s.to_string()) - .expect("endpoint url must be specified"), - ssl_key: to_s(opts.ssl_key).map(PathBuf::from), - ssl_cert: to_s(opts.ssl_cert).map(PathBuf::from), - ssl_dh_param: to_s(opts.ssl_dh_param).map(PathBuf::from), - auto_ping_interval: fto_dur(opts.auto_ping_interval) - .expect("ping interval cannot be 0"), - auto_ping_timeout: fto_dur(opts.auto_ping_timeout).expect("ping timeout cannot be 0"), - close_handshake_timeout: ito_dur(opts.close_handshake_timeout), - max_connections: if opts.max_connections == 0 { + router_table_name: settings.router_tablename, + router_url, + endpoint_url, + ssl_key: settings.router_ssl_key.map(PathBuf::from), + ssl_cert: settings.router_ssl_cert.map(PathBuf::from), + ssl_dh_param: settings.router_ssl_dh_param.map(PathBuf::from), + auto_ping_interval: fto_dur(settings.auto_ping_interval) + .expect("auto ping interval cannot be 0"), + auto_ping_timeout: fto_dur(settings.auto_ping_timeout) + .expect("auto ping timeout cannot be 0"), + close_handshake_timeout: ito_dur(settings.close_handshake_timeout), + max_connections: if settings.max_connections == 0 { None } else { - Some(opts.max_connections) + Some(settings.max_connections) }, - open_handshake_timeout: ito_dur(opts.open_handshake_timeout), - megaphone_api_url: to_s(opts.megaphone_api_url).map(|s| s.to_string()), - megaphone_api_token: to_s(opts.megaphone_api_token).map(|s| s.to_string()), - megaphone_poll_interval: ito_dur(opts.megaphone_poll_interval) - .expect("poll interval cannot be 0"), + open_handshake_timeout: ito_dur(5), + megaphone_api_url: settings.megaphone_api_url, + megaphone_api_token: settings.megaphone_api_token, + megaphone_poll_interval: ito_dur(settings.megaphone_poll_interval) + .expect("megaphone poll interval cannot be 0"), + human_logs: settings.human_logs, }; opts.message_table_names.sort_unstable(); - opts.current_message_month = opts.message_table_names + opts.current_message_month = opts + .message_table_names .last() .expect("No last message month found") .to_string(); - - Box::new(AutopushServer { - inner: UnwindGuard::new(AutopushServerInner { - opts: Arc::new(opts), - shutdown_handles: Cell::new(None), - }), - }) - }) -} - -#[no_mangle] -pub extern "C" fn autopush_server_start( - srv: *mut AutopushServer, - err: &mut AutopushError, -) -> i32 { - unsafe { - (*srv).inner.catch(err, |srv| { - let handles = Server::start(&srv.opts).expect("failed to start server"); - srv.shutdown_handles.set(Some(handles)); - }) - } -} - -#[no_mangle] -pub extern "C" fn autopush_server_stop(srv: *mut AutopushServer, err: &mut AutopushError) -> i32 { - unsafe { - (*srv).inner.catch(err, |srv| { - srv.stop().expect("tokio thread panicked"); - }) - } -} - -#[no_mangle] -pub extern "C" fn autopush_server_free(srv: *mut AutopushServer) { - rt::abort_on_panic(|| unsafe { - Box::from_raw(srv); - }); - util::reset_logging(); -} - -impl AutopushServerInner { - /// Blocks execution of the calling thread until the helper thread with the - /// tokio reactor has exited. - fn stop(&self) -> Result<()> { - let mut result = Ok(()); - if let Some(shutdown_handles) = self.shutdown_handles.take() { - for ShutdownHandle(tx, thread) in shutdown_handles { - let _ = tx.send(()); - if let Err(err) = thread.join() { - result = Err(From::from(ErrorKind::Thread(err))); - } - } - } - result + Ok(opts) } } -impl Drop for AutopushServerInner { - fn drop(&mut self) { - drop(self.stop()); - } +pub struct Server { + uaids: RefCell>, + broadcaster: RefCell, + pub ddb: DynamoStorage, + open_connections: Cell, + tls_acceptor: Option, + pub opts: Arc, + pub handle: Handle, + pub metrics: StatsdClient, } impl Server { @@ -374,7 +297,8 @@ impl Server { fn new(opts: &Arc) -> Result<(Rc, Core)> { let core = Core::new()?; let broadcaster = if let Some(ref megaphone_url) = opts.megaphone_api_url { - let megaphone_token = opts.megaphone_api_token + let megaphone_token = opts + .megaphone_api_token .as_ref() .expect("Megaphone API requires a Megaphone API Token to be set"); ServiceChangeTracker::with_api_services(megaphone_url, megaphone_token) @@ -397,8 +321,10 @@ impl Server { let handle = core.handle(); let srv2 = srv.clone(); - let ws_srv = ws_listener.incoming().map_err(Error::from).for_each( - move |(socket, addr)| { + let ws_srv = ws_listener + .incoming() + .map_err(Error::from) + .for_each(move |(socket, addr)| { // Make sure we're not handling too many clients before we start the // websocket handshake. let max = srv.opts.max_connections.unwrap_or(u32::max_value()); @@ -459,10 +385,12 @@ impl Server { // communication with the client, managing pings // here and deferring to `Client` to start driving // the internal state machine. - Box::new(ws.and_then(move |ws| { - PingManager::new(&srv2, ws, uarx, host) - .chain_err(|| "failed to make ping handler") - }).flatten()) + Box::new( + ws.and_then(move |ws| { + PingManager::new(&srv2, ws, uarx, host) + .chain_err(|| "failed to make ping handler") + }).flatten(), + ) } } }); @@ -482,11 +410,11 @@ impl Server { })); Ok(()) - }, - ); + }); if let Some(ref megaphone_url) = opts.megaphone_api_url { - let megaphone_token = opts.megaphone_api_token + let megaphone_token = opts + .megaphone_api_token .as_ref() .expect("Megaphone API requires a Megaphone API Token to be set"); let fut = MegaphoneUpdater::new( @@ -523,14 +451,16 @@ impl Server { let key_digest = hash::hash(hash::MessageDigest::sha256(), &raw_key) .chain_err(|| "Error creating message digest for key")?; base.extend(key_digest.iter()); - let encrypted = self.opts + let encrypted = self + .opts .fernet .encrypt(&base) .trim_matches('=') .to_string(); Ok(format!("{}v2/{}", root, encrypted)) } else { - let encrypted = self.opts + let encrypted = self + .opts .fernet .encrypt(&base) .trim_matches('=') @@ -587,9 +517,7 @@ impl Server { pub fn disconnet_client(&self, uaid: &Uuid, uid: &Uuid) { debug!("Disconnecting client!"); let mut uaids = self.uaids.borrow_mut(); - let client_exists = uaids - .get(uaid) - .map_or(false, |client| client.uid == *uid); + let client_exists = uaids.get(uaid).map_or(false, |client| client.uid == *uid); if client_exists { uaids.remove(uaid).expect("Couldn't remove client?"); } @@ -668,7 +596,8 @@ impl Future for MegaphoneUpdater { MegaphoneState::Waiting => { try_ready!(self.timeout.poll()); debug!("Sending megaphone API request"); - let fut = self.client + let fut = self + .client .get(&self.api_url) .header(header::Authorization(self.api_token.clone())) .send() @@ -702,14 +631,6 @@ impl Future for MegaphoneUpdater { } } -struct PingManager { - socket: RcObject>>, - timeout: Timeout, - waiting: WaitingFor, - srv: Rc, - client: CloseState>>>>, -} - enum WaitingFor { SendPing, Pong, @@ -721,6 +642,14 @@ enum CloseState { Closing, } +struct PingManager { + socket: RcObject>>, + timeout: Timeout, + waiting: WaitingFor, + srv: Rc, + client: CloseState>>>>, +} + impl PingManager { fn new( srv: &Rc, diff --git a/autopush_rs/src/settings.rs b/autopush_rs/src/settings.rs new file mode 100644 index 00000000..c4a6fd9b --- /dev/null +++ b/autopush_rs/src/settings.rs @@ -0,0 +1,131 @@ +use std::net::ToSocketAddrs; + +use config::{Config, ConfigError, Environment, File}; +use fernet::Fernet; +use hostname::get_hostname; + +lazy_static! { + static ref HOSTNAME: String = get_hostname().unwrap(); + static ref RESOLVED_HOSTNAME: String = get_resolved_hostname(); +} + +fn get_resolved_hostname() -> String { + let hostname = get_hostname().expect("Can't get hostname"); + hostname + .to_socket_addrs() + .expect("Failed to resolve hostnames") + .last() + .expect("No hostnames found") + .to_string() +} + +#[derive(Debug, Deserialize)] +pub struct Settings { + pub debug: bool, + pub port: u16, + pub hostname: Option, + pub resolve_hostname: bool, + pub router_port: u16, + pub router_hostname: Option, + pub router_tablename: String, + pub message_tablename: String, + pub router_ssl_key: Option, + pub router_ssl_cert: Option, + pub router_ssl_dh_param: Option, + pub auto_ping_interval: f64, + pub auto_ping_timeout: f64, + pub max_connections: u32, + pub close_handshake_timeout: u32, + pub endpoint_scheme: String, + pub endpoint_hostname: Option, + pub endpoint_port: u16, + pub crypto_key: String, + pub statsd_host: String, + pub statsd_port: u16, + pub aws_ddb_endpoint: Option, + pub megaphone_api_url: Option, + pub megaphone_api_token: Option, + pub megaphone_poll_interval: u32, + pub human_logs: bool, +} + +impl Settings { + /// Load the settings from the config files in order first then the environment. + pub fn with_env_and_config_files(filenames: &[String]) -> Result { + let mut s = Config::default(); + // Set our defaults, this can be fixed up drastically later after: + // https://github.com/mehcode/config-rs/issues/60 + s.set_default("debug", false)?; + s.set_default("port", 8080)?; + s.set_default("resolve_hostname", false)?; + s.set_default("router_port", 8081)?; + s.set_default("router_tablename", "router")?; + s.set_default("message_tablename", "message")?; + s.set_default("auto_ping_interval", 300)?; + s.set_default("auto_ping_timeout", 4)?; + s.set_default("max_connections", 0)?; + s.set_default("close_handshake_timeout", 0)?; + s.set_default("endpoint_scheme", "http")?; + s.set_default("endpoint_port", 8082)?; + s.set_default("crypto_key", vec![Fernet::generate_key()])?; + s.set_default("statsd_host", "localhost")?; + s.set_default("statsd_port", 8125)?; + s.set_default("megaphone_poll_interval", 30)?; + s.set_default("human_logs", false)?; + + // Merge the configs from the files + for filename in filenames { + s.merge(File::with_name(filename))?; + } + + // Merge the environment overrides + s.merge(Environment::with_prefix("autopush"))?; + s.try_into() + } + + pub fn router_url(&self) -> String { + let router_scheme = if self.router_ssl_key.is_none() { + "http" + } else { + "https" + }; + let hostname = self.host_name(); + format!( + "{}://{}:{}", + router_scheme, + self.router_hostname.as_ref().unwrap_or(&hostname), + self.router_port + ) + } + + pub fn endpoint_url(&self) -> String { + format!( + "{}://{}:{}", + self.endpoint_scheme, + self.endpoint_hostname + .as_ref() + .expect("Endpoint hostname must be supplied"), + self.endpoint_port + ) + } + + fn host_name(&self) -> String { + if let Some(ref hostname) = self.hostname { + if self.resolve_hostname { + return hostname + .to_socket_addrs() + .expect("Failed to resolve hostnames") + .last() + .expect("No hostnames found") + .to_string(); + } else { + return hostname.clone(); + } + } + if self.resolve_hostname { + RESOLVED_HOSTNAME.clone() + } else { + HOSTNAME.clone() + } + } +} diff --git a/setup.py b/setup.py index b8a7b60a..1d621deb 100644 --- a/setup.py +++ b/setup.py @@ -15,35 +15,25 @@ extra_options = { "packages": find_packages(), } + if WITH_RUST.lower() not in ('false', '0'): def build_native(spec): cmd = ['cargo', 'build'] - in_path = 'target/debug' if WITH_RUST.lower() == 'release': cmd.append('--release') - in_path = 'target/release' - build = spec.add_external_build( + spec.add_external_build( cmd=cmd, path='./autopush_rs' ) - spec.add_cffi_module( - module_path='autopush_rs._native', - dylib=lambda: build.find_dylib('autopush', in_path=in_path), - header_filename=lambda: build.find_header( - 'autopush.h', in_path='target'), - rtld_flags=['NOW', 'NODELETE'] - ) - extra_options.update( setup_requires=['milksnake'], install_requires=['milksnake'], milksnake_tasks=[ build_native ] - ) - +) setup(name="AutoPush", version=__version__, @@ -68,7 +58,6 @@ def build_native(spec): [console_scripts] autopush = autopush.main:ConnectionApplication.main autoendpoint = autopush.main:EndpointApplication.main - autopush_rs = autopush.main:RustConnectionApplication.main autokey = autokey:main endpoint_diagnostic = autopush.diagnostic_cli:run_endpoint_diagnostic_cli drop_users = autopush.scripts.drop_user:drop_users diff --git a/tox.ini b/tox.ini index 6c24f0f9..09d1b285 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ deps = -rtest-requirements.txt usedevelop = True passenv = SKIP_INTEGRATION WITH_RUST commands = - nosetests -v {posargs} autopush + nosetests {posargs} autopush install_command = pip install --pre {opts} {packages} [testenv:pypy]