diff --git a/Cargo.lock b/Cargo.lock index af0200a..b1e1b4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,8 @@ +[[package]] +name = "antidote" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" version = "0.4.7" @@ -36,6 +41,15 @@ dependencies = [ "rusttype 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "base64" version = "0.9.0" @@ -231,6 +245,24 @@ name = "httparse" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "hyper" +version = "0.10.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.4 (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.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper" version = "0.11.22" @@ -255,6 +287,16 @@ dependencies = [ "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper-native-tls" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper-tls" version = "0.1.3" @@ -269,6 +311,16 @@ dependencies = [ "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.1.4" +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.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.0" @@ -286,6 +338,11 @@ dependencies = [ "winapi 0.2.8 (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.0" @@ -359,6 +416,11 @@ dependencies = [ "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "maud" version = "0.17.2" @@ -387,6 +449,14 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.3.5" @@ -613,6 +683,20 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "reqwest" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "route-recognizer" version = "0.1.12" @@ -623,6 +707,16 @@ name = "rustc-demangle" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustsec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rusttype" version = "0.4.3" @@ -710,6 +804,11 @@ name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.33" @@ -735,6 +834,17 @@ dependencies = [ "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_json" +version = "0.9.10" +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)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.13" @@ -746,6 +856,17 @@ dependencies = [ "serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_urlencoded" +version = "0.4.3" +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 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "shared_failure" version = "0.1.0" @@ -770,6 +891,7 @@ dependencies = [ "maud 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rustsec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "sass-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -999,6 +1121,14 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "toml" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.4.5" @@ -1007,6 +1137,11 @@ dependencies = [ "serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "try_future" version = "0.1.2" @@ -1015,6 +1150,19 @@ dependencies = [ "futures 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicase" version = "2.1.0" @@ -1023,6 +1171,19 @@ dependencies = [ "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.0.4" @@ -1041,6 +1202,16 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vcpkg" version = "0.2.2" @@ -1095,9 +1266,11 @@ dependencies = [ ] [metadata] +"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" @@ -1125,10 +1298,14 @@ dependencies = [ "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" +"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" "checksum hyper 0.11.22 (registry+https://github.com/rust-lang/crates.io-index)" = "d595f999e90624f64d2c4bc74c72adb0f3e0f773dc5692ca91338363b3568fa0" +"checksum hyper-native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72332e4a35d3059583623b50e98e491b78f8b96c5521fcb3f428167955aa56e8" "checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" +"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum indexmap 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9378f1f3923647a9aea6af4c6b5de68cc8a71415459ad25ef191191c48f5b7" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum itoa 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92a9df60778f789c37f76778ae8d0a2471c41baa8b059d98a5873c978f549587" "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" @@ -1141,10 +1318,12 @@ dependencies = [ "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 lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" +"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum maud 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c0023c814f4a545946ab612ad64a4edce8126d4fe4f0abc5f319b80877112048" "checksum maud_htmlescape 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fb85bccffc42302ad1e1ed8679f6a39d1317f775a37fbc3f79bdfbe054bfb7" "checksum maud_macros 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8377d77c1995044b8ad67a59d15b434c8b7de470ac743de4916ee2bd9fce55" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "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" @@ -1171,8 +1350,10 @@ dependencies = [ "checksum relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e614f96449605730b4f7ad2c019e88c1652d730634b4eba07b810801856635e3" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24" +"checksum reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bef9ed8fdfcc30947d6b774938dc0c3f369a474efe440df2c7f278180b2d2e6" "checksum route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3255338088df8146ba63d60a9b8e3556f1146ce2973bc05a75181a42ce2256" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" +"checksum rustsec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fb074a338f1f966f5d86eaef9aa85b544207ed138986e60a33e08202c5c4492" "checksum rusttype 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "11ff03da02f6d340bbee5ec55eed03ff9abd6ea013b93bc7c35973cc28f65999" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum sass-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90f8cf6e645aa843ffffcbdc1e8752b1f221dfa314c81895aeb229a77aea7e05" @@ -1184,10 +1365,13 @@ dependencies = [ "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "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 serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" "checksum serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe95aa0d46f04ce5c3a88bdcd4114ecd6144ed0b2725ebca2f1127744357807" "checksum serde_derive 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "23b163a6ce7e1aa897919f9d8e40bd1f8a6f95342ed57727ae31387a01a7a356" "checksum serde_derive_internals 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "370aa477297975243dc914d0b0e1234927520ec311de507a560fbd1c80f7ab8c" +"checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" "checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74" +"checksum serde_urlencoded 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "68f06ece1408d3221d11a9da11953ad0c94daa48cfa42026471306f895b91bc8" "checksum shared_failure 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95950ce835eb54ad4d85f5f597a3d7f78cb0f6622f65dabc2dac915d9edc404a" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" @@ -1211,12 +1395,19 @@ dependencies = [ "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8656c45ae7893c9090ac5c98749e7ff904932973fabd541463f82628efacb" "checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" +"checksum toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd86ad9ebee246fdedd610e0f6d0587b754a3d81438db930a244d0480ed7878f" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try_future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5991a93204dab99f8f1f8ac657eb070315dbd71a79f15fa4f86d983fa880545" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +"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.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "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 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" +"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "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" diff --git a/Cargo.toml b/Cargo.toml index 2248878..b304980 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ lru-cache = "0.1.1" maud = "0.17.2" relative-path = { version = "0.3.7", features = ["serde"] } route-recognizer = "0.1.12" +rustsec = "0.6.0" semver = { version = "0.9.0", features = ["serde"] } serde = "1.0.27" serde_derive = "1.0.27" diff --git a/src/engine/futures/analyze.rs b/src/engine/futures/analyze.rs index 61563b5..f08870d 100644 --- a/src/engine/futures/analyze.rs +++ b/src/engine/futures/analyze.rs @@ -12,27 +12,29 @@ pub struct AnalyzeDependenciesFuture { } impl AnalyzeDependenciesFuture { - pub fn new(engine: &Engine, deps: CrateDeps) -> Self { - let analyzer = DependencyAnalyzer::new(&deps); + pub fn new(engine: Engine, deps: CrateDeps) -> Self { + let future = engine.fetch_advisory_db().and_then(move |advisory_db| { + let analyzer = DependencyAnalyzer::new(&deps, advisory_db); - let main_deps = deps.main.into_iter().filter_map(|(name, dep)| { - if dep.is_external() { Some(name) } else { None } - }); - let dev_deps = deps.dev.into_iter().filter_map(|(name, dep)| { - if dep.is_external() { Some(name) } else { None } - }); - let build_deps = deps.build.into_iter().filter_map(|(name, dep)| { - if dep.is_external() { Some(name) } else { None } - }); + let main_deps = deps.main.into_iter().filter_map(|(name, dep)| { + if dep.is_external() { Some(name) } else { None } + }); + let dev_deps = deps.dev.into_iter().filter_map(|(name, dep)| { + if dep.is_external() { Some(name) } else { None } + }); + let build_deps = deps.build.into_iter().filter_map(|(name, dep)| { + if dep.is_external() { Some(name) } else { None } + }); - let release_futures = engine.fetch_releases(main_deps.chain(dev_deps).chain(build_deps)); + let release_futures = engine.fetch_releases(main_deps.chain(dev_deps).chain(build_deps)); - let analyzed_deps_future = futures_unordered(release_futures) - .fold(analyzer, |mut analyzer, releases| { analyzer.process(releases); Ok(analyzer) as Result<_, Error> }) - .map(|analyzer| analyzer.finalize()); + futures_unordered(release_futures) + .fold(analyzer, |mut analyzer, releases| { analyzer.process(releases); Ok(analyzer) as Result<_, Error> }) + .map(|analyzer| analyzer.finalize()) + }); AnalyzeDependenciesFuture { - inner: Box::new(analyzed_deps_future) + inner: Box::new(future) } } } diff --git a/src/engine/machines/analyzer.rs b/src/engine/machines/analyzer.rs index cc2dd3d..daa62f8 100644 --- a/src/engine/machines/analyzer.rs +++ b/src/engine/machines/analyzer.rs @@ -1,19 +1,24 @@ +use std::sync::Arc; + +use rustsec::db::AdvisoryDatabase; use semver::Version; -use ::models::crates::{CrateDeps, CrateRelease, AnalyzedDependency, AnalyzedDependencies}; +use ::models::crates::{CrateDeps, CrateRelease, CrateName, AnalyzedDependency, AnalyzedDependencies}; pub struct DependencyAnalyzer { - deps: AnalyzedDependencies + deps: AnalyzedDependencies, + advisory_db: Arc } impl DependencyAnalyzer { - pub fn new(deps: &CrateDeps) -> DependencyAnalyzer { + pub fn new(deps: &CrateDeps, advisory_db: Arc) -> DependencyAnalyzer { DependencyAnalyzer { - deps: AnalyzedDependencies::new(deps) + deps: AnalyzedDependencies::new(deps), + advisory_db } } - fn process_single(dep: &mut AnalyzedDependency, ver: &Version) { + fn process_single(name: &CrateName, dep: &mut AnalyzedDependency, ver: &Version, advisory_db: &AdvisoryDatabase) { if dep.required.matches(&ver) { if let Some(ref mut current_latest_that_matches) = dep.latest_that_matches { if *current_latest_that_matches < *ver { @@ -22,6 +27,10 @@ impl DependencyAnalyzer { } else { dep.latest_that_matches = Some(ver.clone()); } + + if !advisory_db.find_vulns_for_crate(name.as_ref(), ver).is_empty() { + dep.insecure = true; + } } if !ver.is_prerelease() { if let Some(ref mut current_latest) = dep.latest { @@ -37,13 +46,13 @@ impl DependencyAnalyzer { pub fn process>(&mut self, releases: I) { for release in releases.into_iter().filter(|r| !r.yanked) { if let Some(main_dep) = self.deps.main.get_mut(&release.name) { - DependencyAnalyzer::process_single(main_dep, &release.version) + DependencyAnalyzer::process_single(&release.name, main_dep, &release.version, &self.advisory_db) } if let Some(dev_dep) = self.deps.dev.get_mut(&release.name) { - DependencyAnalyzer::process_single(dev_dep, &release.version) + DependencyAnalyzer::process_single(&release.name, dev_dep, &release.version, &self.advisory_db) } if let Some(build_dep) = self.deps.build.get_mut(&release.name) { - DependencyAnalyzer::process_single(build_dep, &release.version) + DependencyAnalyzer::process_single(&release.name, build_dep, &release.version, &self.advisory_db) } } } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index ba6f76d..7988c8e 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -11,6 +11,7 @@ use hyper::Client; use hyper::client::HttpConnector; use hyper_tls::HttpsConnector; use relative_path::{RelativePath, RelativePathBuf}; +use rustsec::db::AdvisoryDatabase; use semver::VersionReq; use slog::Logger; use tokio_service::Service; @@ -25,7 +26,8 @@ use ::models::crates::{CrateName, CratePath, CrateRelease, AnalyzedDependencies} use ::interactors::crates::{QueryCrate, GetPopularCrates}; use ::interactors::RetrieveFileAtPath; -use ::interactors::github::{GetPopularRepos}; +use ::interactors::github::GetPopularRepos; +use ::interactors::rustsec::FetchAdvisoryDatabase; use self::futures::AnalyzeDependenciesFuture; use self::futures::CrawlManifestFuture; @@ -41,7 +43,8 @@ pub struct Engine { query_crate: Arc>>, get_popular_crates: Arc>>, get_popular_repos: Arc>>, - retrieve_file_at_path: Arc> + retrieve_file_at_path: Arc>, + fetch_advisory_db: Arc>> } impl Engine { @@ -51,6 +54,7 @@ impl Engine { let query_crate = Cache::new(QueryCrate(client.clone()), Duration::from_secs(300), 500); let get_popular_crates = Cache::new(GetPopularCrates(client.clone()), Duration::from_secs(10), 1); let get_popular_repos = Cache::new(GetPopularRepos(client.clone()), Duration::from_secs(10), 1); + let fetch_advisory_db = Cache::new(FetchAdvisoryDatabase(client.clone()), Duration::from_secs(300), 1); Engine { client: client.clone(), logger, metrics, @@ -58,7 +62,8 @@ impl Engine { query_crate: Arc::new(query_crate), get_popular_crates: Arc::new(get_popular_crates), get_popular_repos: Arc::new(get_popular_repos), - retrieve_file_at_path: Arc::new(RetrieveFileAtPath(client)) + retrieve_file_at_path: Arc::new(RetrieveFileAtPath(client)), + fetch_advisory_db: Arc::new(fetch_advisory_db) } } @@ -77,6 +82,10 @@ impl AnalyzeDependenciesOutcome { self.crates.iter().any(|&(_, ref deps)| deps.any_outdated()) } + pub fn any_insecure(&self) -> bool { + self.crates.iter().any(|&(_, ref deps)| deps.count_insecure() > 0) + } + pub fn outdated_ratio(&self) -> (usize, usize) { self.crates.iter().fold((0, 0), |(outdated, total), &(_, ref deps)| { (outdated + deps.count_outdated(), total + deps.count_total()) @@ -115,7 +124,7 @@ impl Engine { manifest_future.and_then(move |manifest_output| { let engine_for_analyze = engine.clone(); let futures = manifest_output.crates.into_iter().map(move |(crate_name, deps)| { - let analyzed_deps_future = AnalyzeDependenciesFuture::new(&engine_for_analyze, deps); + let analyzed_deps_future = AnalyzeDependenciesFuture::new(engine_for_analyze.clone(), deps); analyzed_deps_future.map(move |analyzed_deps| (crate_name, analyzed_deps)) }); @@ -147,7 +156,7 @@ impl Engine { match query_response.releases.iter().find(|release| release.version == crate_path.version) { None => future::Either::A(future::err(format_err!("could not find crate release with version {}", crate_path.version))), Some(release) => { - let analyzed_deps_future = AnalyzeDependenciesFuture::new(&engine, release.deps.clone()); + let analyzed_deps_future = AnalyzeDependenciesFuture::new(engine.clone(), release.deps.clone()); future::Either::B(analyzed_deps_future.map(move |analyzed_deps| { let crates = vec![(crate_path.name, analyzed_deps)].into_iter().collect(); @@ -190,6 +199,12 @@ impl Engine { let manifest_path = path.join(RelativePath::new("Cargo.toml")); self.retrieve_file_at_path.call((repo_path.clone(), manifest_path)) } + + fn fetch_advisory_db(&self) -> + impl Future, Error=Error> + { + self.fetch_advisory_db.call(()).from_err().map(|db| db.clone()) + } } lazy_static! { diff --git a/src/interactors/mod.rs b/src/interactors/mod.rs index 42b680f..bf4288d 100644 --- a/src/interactors/mod.rs +++ b/src/interactors/mod.rs @@ -10,7 +10,7 @@ pub mod bitbucket; pub mod crates; pub mod github; pub mod gitlab; - +pub mod rustsec; #[derive(Debug, Clone)] pub struct RetrieveFileAtPath(pub S); diff --git a/src/interactors/rustsec.rs b/src/interactors/rustsec.rs new file mode 100644 index 0000000..b651c15 --- /dev/null +++ b/src/interactors/rustsec.rs @@ -0,0 +1,44 @@ +use std::str; +use std::sync::Arc; + +use failure::Error; +use futures::{Future, IntoFuture, Stream, future}; +use hyper::{Error as HyperError, Method, Request, Response}; +use rustsec::ADVISORY_DB_URL; +use rustsec::db::AdvisoryDatabase; +use tokio_service::Service; + +#[derive(Debug, Clone)] +pub struct FetchAdvisoryDatabase(pub S); + +impl Service for FetchAdvisoryDatabase + where S: Service + Clone + 'static, + S::Future: 'static +{ + type Request = (); + type Response = Arc; + type Error = Error; + type Future = Box>; + + fn call(&self, _req: ()) -> Self::Future { + let service = self.0.clone(); + + let uri_future = ADVISORY_DB_URL.parse().into_future().from_err(); + + Box::new(uri_future.and_then(move |uri| { + let request = Request::new(Method::Get, uri); + + service.call(request).from_err().and_then(|response| { + let status = response.status(); + if !status.is_success() { + future::Either::A(future::err(format_err!("Status code {} when fetching advisory db", status))) + } else { + let body_future = response.body().concat2().from_err(); + let decode_future = body_future + .and_then(|body| Ok(Arc::new(AdvisoryDatabase::from_toml(str::from_utf8(&body)?)?))); + future::Either::B(decode_future) + } + }) + })) + } +} diff --git a/src/main.rs b/src/main.rs index 4811c16..873bbdd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ extern crate lru_cache; extern crate maud; extern crate relative_path; extern crate route_recognizer; +extern crate rustsec; extern crate semver; #[macro_use] extern crate serde_derive; extern crate serde; diff --git a/src/models/crates.rs b/src/models/crates.rs index e499cda..3fc60ed 100644 --- a/src/models/crates.rs +++ b/src/models/crates.rs @@ -93,7 +93,8 @@ pub struct CrateDeps { pub struct AnalyzedDependency { pub required: VersionReq, pub latest_that_matches: Option, - pub latest: Option + pub latest: Option, + pub insecure: bool } impl AnalyzedDependency { @@ -101,7 +102,8 @@ impl AnalyzedDependency { AnalyzedDependency { required, latest_that_matches: None, - latest: None + latest: None, + insecure: false } } @@ -158,6 +160,19 @@ impl AnalyzedDependencies { .filter(|&(_, dep)| dep.is_outdated()) .count(); main_outdated + dev_outdated + build_outdated + } + + pub fn count_insecure(&self) -> usize { + let main_insecure = self.main.iter() + .filter(|&(_, dep)| dep.insecure) + .count(); + let dev_insecure = self.dev.iter() + .filter(|&(_, dep)| dep.insecure) + .count(); + let build_insecure = self.build.iter() + .filter(|&(_, dep)| dep.insecure) + .count(); + main_insecure + dev_insecure + build_insecure } pub fn any_outdated(&self) -> bool { diff --git a/src/server/views/badge.rs b/src/server/views/badge.rs index b2be7ef..cb9139c 100644 --- a/src/server/views/badge.rs +++ b/src/server/views/badge.rs @@ -7,25 +7,33 @@ use ::engine::AnalyzeDependenciesOutcome; pub fn badge(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Badge { let opts = match analysis_outcome { Some(outcome) => { - let (outdated, total) = outcome.outdated_ratio(); - - if outdated > 0 { + if outcome.any_insecure() { BadgeOptions { subject: "dependencies".into(), - status: format!("{} of {} outdated", outdated, total), - color: "#dfb317".into() - } - } else if total > 0 { - BadgeOptions { - subject: "dependencies".into(), - status: "up to date".into(), - color: "#4c1".into() + status: "insecure".into(), + color: "#e05d44".into() } } else { - BadgeOptions { - subject: "dependencies".into(), - status: "none".into(), - color: "#4c1".into() + let (outdated, total) = outcome.outdated_ratio(); + + if outdated > 0 { + BadgeOptions { + subject: "dependencies".into(), + status: format!("{} of {} outdated", outdated, total), + color: "#dfb317".into() + } + } else if total > 0 { + BadgeOptions { + subject: "dependencies".into(), + status: "up to date".into(), + color: "#4c1".into() + } + } else { + BadgeOptions { + subject: "dependencies".into(), + status: "none".into(), + color: "#4c1".into() + } } } }, diff --git a/src/server/views/html/status.rs b/src/server/views/html/status.rs index 2342cc4..91b83be 100644 --- a/src/server/views/html/status.rs +++ b/src/server/views/html/status.rs @@ -36,12 +36,15 @@ fn dependency_tables(crate_name: CrateName, deps: AnalyzedDependencies) -> Marku fn dependency_table(title: &str, deps: IndexMap) -> Markup { let count_total = deps.len(); + let count_insecure = deps.iter().filter(|&(_, dep)| dep.insecure).count(); let count_outdated = deps.iter().filter(|&(_, dep)| dep.is_outdated()).count(); html! { h3 class="title is-4" (title) p class="subtitle is-5" { - @if count_outdated > 0 { + @if count_insecure > 0 { + (format!(" ({} total, {} insecure)", count_total, count_insecure)) + } @else if count_outdated > 0 { (format!(" ({} total, {} up-to-date, {} outdated)", count_total, count_total - count_outdated, count_outdated)) } @else { (format!(" ({} total, all up-to-date)", count_total)) @@ -72,7 +75,9 @@ fn dependency_table(title: &str, deps: IndexMap) } } td class="has-text-right" { - @if dep.is_outdated() { + @if dep.insecure { + span class="tag is-danger" "insecure" + } @else if dep.is_outdated() { span class="tag is-warning" "out of date" } @else { span class="tag is-success" "up to date" @@ -150,7 +155,9 @@ fn render_success(analysis_outcome: AnalyzeDependenciesOutcome, subject_path: Su let status_data_uri = badge::badge(Some(&analysis_outcome)).to_svg_data_uri(); - let hero_class = if analysis_outcome.any_outdated() { + let hero_class = if analysis_outcome.any_insecure() { + "is-danger" + } else if analysis_outcome.any_outdated() { "is-warning" } else { "is-success"