diff --git a/Cargo.lock b/Cargo.lock index 757bc368d..f02a4157d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ name = "aho-corasick" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -289,7 +289,7 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -360,10 +360,10 @@ dependencies = [ [[package]] name = "cursive" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-channel 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "enum-map 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "enumset 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -371,8 +371,8 @@ dependencies = [ "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ncurses 5.94.0 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -587,7 +587,7 @@ dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cursive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cursive 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "grin_api 0.3.0", @@ -598,9 +598,9 @@ dependencies = [ "grin_servers 0.3.0", "grin_util 0.3.0", "grin_wallet 0.3.0", - "reqwest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -621,14 +621,17 @@ dependencies = [ "grin_util 0.3.0", "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.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-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -706,7 +709,7 @@ dependencies = [ "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -777,7 +780,7 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -841,7 +844,7 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -999,7 +1002,7 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1021,7 +1024,7 @@ dependencies = [ [[package]] name = "lazycell" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1148,10 +1151,12 @@ dependencies = [ [[package]] name = "memchr" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1225,7 +1230,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "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 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1487,6 +1492,14 @@ dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "owning_ref" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot" version = "0.6.4" @@ -1683,7 +1696,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1707,7 +1720,7 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1723,7 +1736,7 @@ dependencies = [ "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1809,7 +1822,7 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1862,7 +1875,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1883,7 +1896,7 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2237,6 +2250,16 @@ dependencies = [ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-tls" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-udp" version = "0.1.2" @@ -2534,14 +2557,14 @@ dependencies = [ "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum croaring 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "38961600edf0408acc371eb2359901f5ed2e634dde8537fc9a05e88fb26cde0e" "checksum croaring-sys 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "48a344ef01931b3106d6083c08fefc16e2b0b9d2de695a49a7437e56607cfda1" -"checksum crossbeam-channel 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a5716fadb87a5633db34c5e83ee6e036e6edc229f8a6bfb7c7c84ed340ba95df" +"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" "checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum csv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef22b37c7a51c564a365892c012dc0271221fdcc64c69b19ba4d6fa8bd96d9c" "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" -"checksum cursive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7024f124e4645e285879af7b54ea466dabfed91d16c3d8049df7a4e4c36d8bd" +"checksum cursive 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c75a59f5b54834c5853b1e8d0d4a256252d4ca1da02f0be3e245b48daa754233" "checksum daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4093d27eb267d617f03c2ee25d4c3ca525b89a76154001954a11984508ffbde5" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum dirs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f679c09c1cf5428702cc10f6846c56e4e23420d3a88bcc9335b17c630a7b710b" @@ -2584,7 +2607,7 @@ dependencies = [ "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum lazycell 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e26d4c411b39f0afcf2ba6fe502be90e6c9b299c952dbd86124782520a13cffd" +"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7d4b4c7aff5bac19b956f693d0ea0eade8066deb092186ae954fa6ba14daab98" "checksum libgit2-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "44b1900be992dd5698bd3bb422921e336306d413e2860e6ba3b50e62e6219c4c" @@ -2600,7 +2623,7 @@ dependencies = [ "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" -"checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d" +"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4b082692d3f6cf41b453af73839ce3dfc212c4411cbb2441dff80a716e38bd79" @@ -2636,6 +2659,7 @@ dependencies = [ "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" @@ -2663,7 +2687,7 @@ dependencies = [ "checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum reqwest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1cd396ef9387a076401c19701a86bc08d349ce45eab331247632b4bc9d0bd592" +"checksum reqwest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4265be4dad32ffa4be2cea9c8ecb5e096feca6b4ff024482bfc0f64b6019b2f" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" @@ -2681,9 +2705,9 @@ dependencies = [ "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" "checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" -"checksum serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "59790990c5115d16027f00913e2e66de23a51f70422e549d2ad68c8c5f268f1c" +"checksum serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d30ec34ac923489285d24688c7a9c0898d16edff27fc1f1bd854edeff6ca3b7f" "checksum serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aaed41d9fb1e2f587201b863356590c90c1157495d811430a0c0325fe8169650" -"checksum signal-hook 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc9a251608ddaef559cd5b08b539cbda8c36d0efe0506f9a864765d75dbd665" +"checksum signal-hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7ca1f1c0ed6c8beaab713ad902c041e4f09d06e1b4bb74c5fc553c078ed0110" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09e4f1d0276ac7d448d98db16f0dab0220c24d4842d88ce4dad4b306fa234f1d" @@ -2720,6 +2744,7 @@ dependencies = [ "checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565" "checksum tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a5758cecb6e0633cea5d563ac07c975e04961690b946b04fd84e7d6445a8f6af" "checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c" +"checksum tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e53fdbf3156f588be1676022fe794232b24922d426e8c14f4e46891c1e31c440" "checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" "checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" diff --git a/api/Cargo.toml b/api/Cargo.toml index 8aac2ab37..bd243e00b 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -17,7 +17,10 @@ serde_json = "1" slog = { version = "~2.3", features = ["max_level_trace", "release_max_level_trace"] } tokio = "0.1.7" tokio-core = "0.1.17" +tokio-tls = "0.2" +native-tls = "0.2" http = "0.1.5" +hyper-tls = "0.3" futures = "0.1.21" url = "1.7.0" diff --git a/api/src/client.rs b/api/src/client.rs index 4ae5d58f8..adbb3c6f6 100644 --- a/api/src/client.rs +++ b/api/src/client.rs @@ -19,6 +19,7 @@ use http::uri::{InvalidUri, Uri}; use hyper::header::{ACCEPT, USER_AGENT}; use hyper::rt::{Future, Stream}; use hyper::{Body, Client, Request}; +use hyper_tls; use serde::{Deserialize, Serialize}; use serde_json; @@ -165,7 +166,8 @@ where } fn send_request_async(req: Request) -> Box + Send> { - let client = Client::new(); + let https = hyper_tls::HttpsConnector::new(1).unwrap(); + let client = Client::builder().build::<_, Body>(https); Box::new( client .request(req) diff --git a/api/src/handlers.rs b/api/src/handlers.rs index e6c265d9b..8e3bf499d 100644 --- a/api/src/handlers.rs +++ b/api/src/handlers.rs @@ -13,17 +13,13 @@ // limitations under the License. use std::collections::HashMap; -use std::fmt::Debug; use std::net::SocketAddr; use std::sync::{Arc, RwLock, Weak}; -use std::thread; use failure::ResultExt; -use futures::future::{err, ok}; -use futures::{Future, Stream}; -use hyper::{Body, Request, Response, StatusCode}; -use serde::{Deserialize, Serialize}; -use serde_json; +use futures::future::ok; +use futures::Future; +use hyper::{Body, Request, StatusCode}; use chain; use core::core::hash::{Hash, Hashed}; @@ -40,6 +36,7 @@ use url::form_urlencoded; use util; use util::secp::pedersen::Commitment; use util::LOGGER; +use web::*; // All handlers use `Weak` references instead of `Arc` to avoid cycles that // can never be destroyed. These 2 functions are simple helpers to reduce the @@ -788,60 +785,6 @@ impl Handler for PoolPushHandler { } } -// Utility to serialize a struct into JSON and produce a sensible Response -// out of it. -fn json_response(s: &T) -> ResponseFuture -where - T: Serialize, -{ - match serde_json::to_string(s) { - Ok(json) => response(StatusCode::OK, json), - Err(_) => response(StatusCode::INTERNAL_SERVER_ERROR, ""), - } -} - -fn result_to_response(res: Result) -> ResponseFuture -where - T: Serialize, -{ - match res { - Ok(s) => json_response_pretty(&s), - Err(e) => match e.kind() { - ErrorKind::Argument(msg) => response(StatusCode::BAD_REQUEST, msg.clone()), - ErrorKind::RequestError(msg) => response(StatusCode::BAD_REQUEST, msg.clone()), - ErrorKind::NotFound => response(StatusCode::NOT_FOUND, ""), - ErrorKind::Internal(msg) => response(StatusCode::INTERNAL_SERVER_ERROR, msg.clone()), - ErrorKind::ResponseError(msg) => { - response(StatusCode::INTERNAL_SERVER_ERROR, msg.clone()) - } - }, - } -} - -// pretty-printed version of above -fn json_response_pretty(s: &T) -> ResponseFuture -where - T: Serialize, -{ - match serde_json::to_string_pretty(s) { - Ok(json) => response(StatusCode::OK, json), - Err(e) => response( - StatusCode::INTERNAL_SERVER_ERROR, - format!("can't create json response: {}", e), - ), - } -} - -fn response + Debug>(status: StatusCode, text: T) -> ResponseFuture { - Box::new(ok(just_response(status, text))) -} - -fn just_response + Debug>(status: StatusCode, text: T) -> Response { - let mut resp = Response::new(text.into()); - *resp.status_mut() = status; - resp -} - /// Start all server HTTP handlers. Register all of them with Router /// and runs the corresponding HTTP server. /// @@ -855,37 +798,14 @@ pub fn start_rest_apis( chain: Weak, tx_pool: Weak>, peers: Weak, -) { - let _ = thread::Builder::new() - .name("apis".to_string()) - .spawn(move || { - let mut apis = ApiServer::new(); +) -> bool { + let mut apis = ApiServer::new(); - let router = build_router(chain, tx_pool, peers).expect("unable to build API router"); + let router = build_router(chain, tx_pool, peers).expect("unable to build API router"); - info!(LOGGER, "Starting HTTP API server at {}.", addr); - let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address"); - apis.start(socket_addr, router).unwrap_or_else(|e| { - error!(LOGGER, "Failed to start API HTTP server: {}.", e); - }); - }); -} - -fn parse_body(req: Request) -> Box + Send> -where - for<'de> T: Deserialize<'de> + Send + 'static, -{ - Box::new( - req.into_body() - .concat2() - .map_err(|e| ErrorKind::RequestError(format!("Failed to read request: {}", e)).into()) - .and_then(|body| match serde_json::from_reader(&body.to_vec()[..]) { - Ok(obj) => ok(obj), - Err(e) => { - err(ErrorKind::RequestError(format!("Invalid request body: {}", e)).into()) - } - }), - ) + info!(LOGGER, "Starting HTTP API server at {}.", addr); + let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address"); + apis.start(socket_addr, router) } pub fn build_router( diff --git a/api/src/lib.rs b/api/src/lib.rs index 2a03dbd68..0c4a75375 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -24,6 +24,7 @@ extern crate failure; #[macro_use] extern crate failure_derive; extern crate hyper; +extern crate hyper_tls; #[macro_use] extern crate lazy_static; extern crate regex; @@ -35,16 +36,20 @@ extern crate serde_json; extern crate slog; extern crate futures; extern crate http; +extern crate native_tls; extern crate tokio; extern crate tokio_core; +extern crate tokio_tls; pub mod client; mod handlers; mod rest; mod router; mod types; +mod web; pub use handlers::start_rest_apis; pub use rest::*; pub use router::*; pub use types::*; +pub use web::*; diff --git a/api/src/rest.rs b/api/src/rest.rs index 14d4dcb93..7633bf37f 100644 --- a/api/src/rest.rs +++ b/api/src/rest.rs @@ -18,13 +18,19 @@ //! To use it, just have your service(s) implement the ApiEndpoint trait and //! register them on a ApiServer. +use failure::{Backtrace, Context, Fail}; +use futures::sync::oneshot; +use futures::Stream; use hyper::rt::Future; +use hyper::server::conn::Http; use hyper::{rt, Body, Request, Server}; +use native_tls::{Identity, TlsAcceptor}; use router::{Handler, HandlerObj, ResponseFuture, Router}; use std::fmt::{self, Display}; use std::net::SocketAddr; - -use failure::{Backtrace, Context, Fail}; +use std::{io, thread}; +use tokio::net::TcpListener; +use tokio_tls; use util::LOGGER; /// Errors that can be returned by an ApiEndpoint implementation. @@ -83,37 +89,113 @@ impl From> for Error { } } +/// TLS config +pub struct TLSConfig { + pub pkcs_bytes: Vec, + pub pass: String, +} + /// HTTP server allowing the registration of ApiEndpoint implementations. -pub struct ApiServer {} +pub struct ApiServer { + shutdown_sender: Option>, +} impl ApiServer { /// Creates a new ApiServer that will serve ApiEndpoint implementations /// under the root URL. pub fn new() -> ApiServer { - ApiServer {} + ApiServer { + shutdown_sender: None, + } } /// Starts the ApiServer at the provided address. - pub fn start(&mut self, addr: SocketAddr, router: Router) -> Result<(), String> { - let server = Server::bind(&addr) - .serve(router) - .map_err(|e| eprintln!("server error: {}", e)); + pub fn start(&mut self, addr: SocketAddr, router: Router) -> bool { + if self.shutdown_sender.is_some() { + error!(LOGGER, "Can't start HTTP API server, it's running already"); + return false; + } + let (tx, _rx) = oneshot::channel::<()>(); + let _ = thread::Builder::new() + .name("apis".to_string()) + .spawn(move || { + let server = Server::bind(&addr) + .serve(router) + // TODO graceful shutdown is unstable, investigate + //.with_graceful_shutdown(rx) + .map_err(|e| eprintln!("HTTP API server error: {}", e)); - //let mut rt = Runtime::new().unwrap(); - //if rt.block_on(server).is_err() { - // return Err("tokio block_on error".to_owned()); - //} - rt::run(server); - Ok(()) + rt::run(server); + }); + + info!(LOGGER, "HTTP API server has been started"); + self.shutdown_sender = Some(tx); + true } - /// Stops the API server - pub fn stop(&mut self) { - // TODO implement proper stop, the following method doesn't - // work for current_thread runtime. - // if let Some(rt) = self.rt.take() { - // rt.shutdown_now().wait().unwrap(); - // } + /// Starts the TLS ApiServer at the provided address. + /// TODO support stop operation + pub fn start_tls(&mut self, addr: SocketAddr, router: Router, conf: TLSConfig) -> bool { + if self.shutdown_sender.is_some() { + error!(LOGGER, "Can't start HTTP API server, it's running already"); + return false; + } + let _ = thread::Builder::new() + .name("apis".to_string()) + .spawn(move || { + let cert = Identity::from_pkcs12(conf.pkcs_bytes.as_slice(), &conf.pass).unwrap(); + let tls_cx = TlsAcceptor::builder(cert).build().unwrap(); + let tls_cx = tokio_tls::TlsAcceptor::from(tls_cx); + let srv = TcpListener::bind(&addr).expect("Error binding local port"); + // Use lower lever hyper API to be able to intercept client connection + let server = Http::new() + .serve_incoming( + srv.incoming().and_then(move |socket| { + tls_cx + .accept(socket) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + }), + router, + ) + .then(|res| match res { + Ok(conn) => Ok(Some(conn)), + Err(e) => { + eprintln!("Error: {}", e); + Ok(None) + } + }) + .for_each(|conn_opt| { + if let Some(conn) = conn_opt { + rt::spawn( + conn.and_then(|c| c.map_err(|e| panic!("Hyper error {}", e))) + .map_err(|e| eprintln!("Connection error {}", e)), + ); + } + Ok(()) + }); + + rt::run(server); + }); + + info!(LOGGER, "HTTPS API server has been started"); + true + } + + /// Stops the API server, it panics in case of error + pub fn stop(&mut self) -> bool { + if self.shutdown_sender.is_some() { + // TODO re-enable stop after investigation + //let tx = mem::replace(&mut self.shutdown_sender, None).unwrap(); + //tx.send(()).expect("Failed to stop API server"); + info!(LOGGER, "API server has been stoped"); + true + } else { + error!( + LOGGER, + "Can't stop API server, it's not running or doesn't spport stop operation" + ); + false + } } } diff --git a/api/src/web.rs b/api/src/web.rs new file mode 100644 index 000000000..c7f487979 --- /dev/null +++ b/api/src/web.rs @@ -0,0 +1,83 @@ +use futures::future::{err, ok}; +use futures::{Future, Stream}; +use hyper::{Body, Request, Response, StatusCode}; +use rest::*; +use router::ResponseFuture; +use serde::{Deserialize, Serialize}; +use serde_json; +use std::fmt::Debug; + +/// Parse request body +pub fn parse_body(req: Request) -> Box + Send> +where + for<'de> T: Deserialize<'de> + Send + 'static, +{ + Box::new( + req.into_body() + .concat2() + .map_err(|e| ErrorKind::RequestError(format!("Failed to read request: {}", e)).into()) + .and_then(|body| match serde_json::from_reader(&body.to_vec()[..]) { + Ok(obj) => ok(obj), + Err(e) => { + err(ErrorKind::RequestError(format!("Invalid request body: {}", e)).into()) + } + }), + ) +} + +/// Convert Result to ResponseFuture +pub fn result_to_response(res: Result) -> ResponseFuture +where + T: Serialize, +{ + match res { + Ok(s) => json_response_pretty(&s), + Err(e) => match e.kind() { + ErrorKind::Argument(msg) => response(StatusCode::BAD_REQUEST, msg.clone()), + ErrorKind::RequestError(msg) => response(StatusCode::BAD_REQUEST, msg.clone()), + ErrorKind::NotFound => response(StatusCode::NOT_FOUND, ""), + ErrorKind::Internal(msg) => response(StatusCode::INTERNAL_SERVER_ERROR, msg.clone()), + ErrorKind::ResponseError(msg) => { + response(StatusCode::INTERNAL_SERVER_ERROR, msg.clone()) + } + }, + } +} + +/// Utility to serialize a struct into JSON and produce a sensible Response +/// out of it. +pub fn json_response(s: &T) -> ResponseFuture +where + T: Serialize, +{ + match serde_json::to_string(s) { + Ok(json) => response(StatusCode::OK, json), + Err(_) => response(StatusCode::INTERNAL_SERVER_ERROR, ""), + } +} + +/// Pretty-printed version of json response as future +pub fn json_response_pretty(s: &T) -> ResponseFuture +where + T: Serialize, +{ + match serde_json::to_string_pretty(s) { + Ok(json) => response(StatusCode::OK, json), + Err(e) => response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("can't create json response: {}", e), + ), + } +} + +/// Text response as HTTP response +pub fn just_response + Debug>(status: StatusCode, text: T) -> Response { + let mut resp = Response::new(text.into()); + *resp.status_mut() = status; + resp +} + +/// Text response as future +pub fn response + Debug>(status: StatusCode, text: T) -> ResponseFuture { + Box::new(ok(just_response(status, text))) +} diff --git a/api/tests/localhost+1.p12 b/api/tests/localhost+1.p12 new file mode 100644 index 000000000..cfda8fad7 Binary files /dev/null and b/api/tests/localhost+1.p12 differ diff --git a/api/tests/rest.rs b/api/tests/rest.rs new file mode 100644 index 000000000..b6d9ca618 --- /dev/null +++ b/api/tests/rest.rs @@ -0,0 +1,68 @@ +extern crate grin_api as api; +extern crate grin_util as util; +extern crate hyper; + +use api::*; +use hyper::{Body, Request}; +use std::net::SocketAddr; +use std::{thread, time}; + +struct IndexHandler { + list: Vec, +} + +impl IndexHandler {} + +impl Handler for IndexHandler { + fn get(&self, _req: Request) -> ResponseFuture { + json_response_pretty(&self.list) + } +} + +fn build_router() -> Router { + let route_list = vec!["get blocks".to_string(), "get chain".to_string()]; + let index_handler = IndexHandler { list: route_list }; + let mut router = Router::new(); + router + .add_route("/v1/*", Box::new(index_handler)) + .expect("add_route failed"); + router +} + +#[test] +fn test_start_api() { + util::init_test_logger(); + let mut server = ApiServer::new(); + let router = build_router(); + let server_addr = "127.0.0.1:14434"; + let addr: SocketAddr = server_addr.parse().expect("unable to parse server address"); + assert!(server.start(addr, router)); + let url = format!("http://{}/v1/", server_addr); + let index = api::client::get::>(url.as_str()).unwrap(); + assert_eq!(index.len(), 2); + assert!(server.stop()); + thread::sleep(time::Duration::from_millis(1_000)); +} + +// To enable this test you need a trusted PKCS12 (p12) certificate bundle +// Hyper-tls client doesn't accept self-signed certificates. The easiest way is to use mkcert +// https://github.com/FiloSottile/mkcert to install CA and generate a certificate on your local machine. +// You need to put the file to api/tests folder +#[ignore] +#[test] +fn test_start_api_tls() { + util::init_test_logger(); + let tls_conf = TLSConfig { + pkcs_bytes: include_bytes!("localhost+1.p12").to_vec(), + pass: "changeit".to_string(), + }; + let mut server = ApiServer::new(); + let router = build_router(); + let server_addr = "127.0.0.1:14444"; + let addr: SocketAddr = server_addr.parse().expect("unable to parse server address"); + assert!(server.start_tls(addr, router, tls_conf)); + let url = format!("https://{}/v1/", server_addr); + let index = api::client::get::>(url.as_str()).unwrap(); + assert_eq!(index.len(), 2); + assert!(!server.stop()); +} diff --git a/wallet/src/libwallet/controller.rs b/wallet/src/libwallet/controller.rs index 5bdd86903..b5fa4c5e9 100644 --- a/wallet/src/libwallet/controller.rs +++ b/wallet/src/libwallet/controller.rs @@ -86,9 +86,7 @@ where let mut apis = ApiServer::new(); info!(LOGGER, "Starting HTTP Owner API server at {}.", addr); let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address"); - apis.start(socket_addr, router).unwrap_or_else(|e| { - error!(LOGGER, "Failed to start API HTTP server: {}.", e); - }); + apis.start(socket_addr, router); Ok(()) } @@ -110,9 +108,7 @@ where let mut apis = ApiServer::new(); info!(LOGGER, "Starting HTTP Foreign API server at {}.", addr); let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address"); - apis.start(socket_addr, router).unwrap_or_else(|e| { - error!(LOGGER, "Failed to start API HTTP server: {}.", e); - }); + apis.start(socket_addr, router); Ok(()) }