From 104e2ce0a25917dfaaab7e62042cc611fc05125a Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 31 Oct 2020 17:28:56 +0100 Subject: [PATCH 01/49] Add "web" configuration entry --- src/util/config.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/config.rs b/src/util/config.rs index b985114d..a78ef830 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -35,6 +35,8 @@ pub struct Config { pub rpc_tls: Option, pub s3_api: ApiConfig, + + pub s3_web: WebConfig, } #[derive(Deserialize, Debug, Clone)] @@ -50,6 +52,11 @@ pub struct ApiConfig { pub s3_region: String, } +#[derive(Deserialize, Debug, Clone)] +pub struct WebConfig { + pub website_bind_addr: SocketAddr, +} + fn default_max_concurrent_rpc_requests() -> usize { 12 } From cea871d944e36222f5fdabe3e907cb8cf86d26e8 Mon Sep 17 00:00:00 2001 From: Quentin Date: Mon, 2 Nov 2020 15:48:39 +0100 Subject: [PATCH 02/49] Skeleton to the new web API --- Cargo.lock | 1435 +++++++++++++++++++++-------------------- Cargo.toml | 1 + src/garage/server.rs | 6 + src/util/config.rs | 2 +- src/web/Cargo.toml | 43 ++ src/web/lib.rs | 5 + src/web/web_server.rs | 37 ++ 7 files changed, 823 insertions(+), 706 deletions(-) create mode 100644 src/web/Cargo.toml create mode 100644 src/web/lib.rs create mode 100644 src/web/web_server.rs diff --git a/Cargo.lock b/Cargo.lock index 50f809bf..c31bc209 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,1909 +4,1934 @@ name = "aho-corasick" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ - "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "arc-swap" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" [[package]] name = "async-trait" version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi 0.3.9", ] [[package]] name = "autocfg" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "base64" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.3", ] [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.14.3", ] [[package]] name = "block-padding" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools", ] [[package]] name = "bumpalo" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] name = "byte-tools" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ - "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "iovec", ] [[package]] name = "bytes" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" dependencies = [ - "loom 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "loom", ] [[package]] name = "cc" version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe" [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" dependencies = [ - "num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits", + "time", ] [[package]] name = "clap" version = "2.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "textwrap", + "unicode-width", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "crossbeam-epoch" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", ] [[package]] name = "crossbeam-utils" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "cfg-if", + "lazy_static", ] [[package]] name = "crypto-mac" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3", + "subtle", ] [[package]] name = "digest" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3", ] [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.14.3", ] [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "humantime", + "log", + "regex", + "termcolor", ] [[package]] name = "err-derive" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" dependencies = [ - "proc-macro-error 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error", + "proc-macro2", + "quote", + "rustversion", + "syn", + "synstructure", ] [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" dependencies = [ - "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] name = "futures-channel" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" dependencies = [ - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-sink", ] [[package]] name = "futures-core" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" [[package]] name = "futures-executor" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" dependencies = [ - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-task", + "futures-util", ] [[package]] name = "futures-io" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" [[package]] name = "futures-macro" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ - "proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "futures-sink" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" [[package]] name = "futures-task" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" dependencies = [ - "once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell", ] [[package]] name = "futures-util" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" dependencies = [ - "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-nested 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", ] [[package]] name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] name = "garage" version = "0.1.1" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "garage_api 0.1.1", + "bytes 0.4.12", + "futures", + "futures-util", + "garage_api", "garage_model 0.1.1", "garage_rpc 0.1.0", "garage_table 0.1.1", "garage_util 0.1.0", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pretty_env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "log", + "pretty_env_logger", + "rand", + "rmp-serde", + "serde", + "sha2", + "sled", + "structopt", + "tokio", + "toml", ] [[package]] name = "garage_api" version = "0.1.1" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "chrono", + "crypto-mac", + "futures", + "futures-util", "garage_model 0.1.1", "garage_table 0.1.1", "garage_util 0.1.0", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http-range 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "httpdate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "md-5 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "roxmltree 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "hmac", + "http", + "http-range", + "httpdate", + "hyper", + "log", + "md-5", + "percent-encoding", + "roxmltree", + "sha2", + "tokio", + "url", ] [[package]] name = "garage_model" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6403312b28077fd585e5f96184d2d56142f10eb42709d2893294d70a892d73f" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "async-trait", + "bytes 0.4.12", + "futures", + "futures-util", "garage_rpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "garage_table 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "garage_table 0.1.0", "garage_util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "log", + "rand", + "rmp-serde", + "serde", + "serde_bytes", + "sha2", + "sled", + "tokio", ] [[package]] name = "garage_model" version = "0.1.1" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "garage_model 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "async-trait", + "bytes 0.4.12", + "futures", + "futures-util", + "garage_model 0.1.0", "garage_rpc 0.1.0", "garage_table 0.1.1", "garage_util 0.1.0", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "log", + "rand", + "rmp-serde", + "serde", + "serde_bytes", + "sha2", + "sled", + "tokio", ] [[package]] name = "garage_rpc" version = "0.1.0" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "bytes 0.4.12", + "futures", + "futures-util", "garage_util 0.1.0", - "gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gethostname", + "hex", + "http", + "hyper", + "hyper-rustls", + "log", + "rand", + "rmp-serde", + "rustls", + "serde", + "serde_json", + "sha2", + "tokio", + "tokio-rustls", + "webpki", ] [[package]] name = "garage_rpc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef794407808c89f300f73457bdc567c953b323d7fe30534aba686a28ebb4a0d" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "bytes 0.4.12", + "futures", + "futures-util", "garage_util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gethostname", + "hex", + "http", + "hyper", + "hyper-rustls", + "log", + "rand", + "rmp-serde", + "rustls", + "serde", + "serde_json", + "sha2", + "tokio", + "tokio-rustls", + "webpki", ] [[package]] name = "garage_table" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567d7e9f791a1d65d26e36840aa0570b3a2144302c32f62b5e63a39f147cbf57" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "async-trait", + "bytes 0.4.12", + "futures", + "futures-util", "garage_rpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "garage_util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "log", + "rand", + "rmp-serde", + "serde", + "serde_bytes", + "sled", + "tokio", ] [[package]] name = "garage_table" version = "0.1.1" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "async-trait", + "bytes 0.4.12", + "futures", + "futures-util", "garage_rpc 0.1.0", "garage_util 0.1.0", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "log", + "rand", + "rmp-serde", + "serde", + "serde_bytes", + "sled", + "tokio", ] [[package]] name = "garage_util" version = "0.1.0" dependencies = [ - "err-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "roxmltree 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "err-derive", + "futures", + "futures-util", + "hex", + "http", + "hyper", + "log", + "rand", + "rmp-serde", + "roxmltree", + "rustls", + "serde", + "serde_json", + "sha2", + "sled", + "tokio", + "toml", + "webpki", ] [[package]] name = "garage_util" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77de76a4167c041094f3f3415c6d3d773373e0326668fbce70dfd3b024788800" dependencies = [ - "err-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", - "roxmltree 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "err-derive", + "futures", + "futures-util", + "hex", + "http", + "hyper", + "log", + "rand", + "rmp-serde", + "roxmltree", + "rustls", + "serde", + "serde_json", + "sha2", + "sled", + "tokio", + "toml", + "webpki", +] + +[[package]] +name = "garage_web" +version = "0.1.0" +dependencies = [ + "err-derive", + "futures", + "futures-util", + "garage_model 0.1.1", + "garage_table 0.1.1", + "garage_util 0.1.0", + "hex", + "http", + "hyper", + "log", + "rand", + "rmp-serde", + "roxmltree", + "rustls", + "serde", + "serde_json", + "sha2", + "sled", + "tokio", + "toml", + "webpki", ] [[package]] name = "generator" version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" dependencies = [ - "cc 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "log", + "rustc_version", + "winapi 0.3.9", ] [[package]] name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" dependencies = [ - "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum", ] [[package]] name = "generic-array" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" dependencies = [ - "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum", + "version_check", ] [[package]] name = "gethostname" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] [[package]] name = "h2" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "log", + "slab", + "tokio", + "tokio-util", ] [[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" dependencies = [ - "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation", ] [[package]] name = "hermit-abi" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "hex" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" [[package]] name = "hmac" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac", + "digest 0.8.1", ] [[package]] name = "http" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "fnv", + "itoa", ] [[package]] name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "http", ] [[package]] name = "http-range" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2e4003e6fd05ea9109db00415e670b11f511a42e567ff2d5d771cbdfa24e02" [[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] name = "httpdate" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" [[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error", ] [[package]] name = "hyper" version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "log", + "pin-project", + "socket2", + "time", + "tokio", + "tower-service", + "want", ] [[package]] name = "hyper-rustls" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "futures-util", + "hyper", + "log", + "rustls", + "tokio", + "tokio-rustls", + "webpki", ] [[package]] name = "idna" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" dependencies = [ - "matches 0.1.8 (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.13 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "indexmap" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "itoa" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "js-sys" version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916" dependencies = [ - "wasm-bindgen 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" [[package]] name = "lock_api" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" dependencies = [ - "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard", ] [[package]] name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "loom" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "generator 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "generator", + "scoped-tls", ] [[package]] name = "matches" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "md-5" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" dependencies = [ - "block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", ] [[package]] name = "memchr" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] name = "memoffset" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "mio" version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 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.71 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (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.34 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", ] [[package]] name = "mio-uds" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec", + "libc", + "mio", ] [[package]] name = "miow" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] name = "net2" version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "winapi 0.3.9", ] [[package]] name = "num-integer" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "once_cell" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" [[package]] name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "opaque-debug" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "parking_lot" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ - "lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api", + "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", ] [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" dependencies = [ - "pin-project-internal 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal", ] [[package]] name = "pin-project-internal" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "pin-project-lite" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "pretty_env_logger" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger", + "log", ] [[package]] name = "proc-macro-error" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" dependencies = [ - "proc-macro-error-attr 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", ] [[package]] name = "proc-macro-error-attr" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", + "syn-mid", + "version_check", ] [[package]] name = "proc-macro-hack" version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" [[package]] name = "proc-macro-nested" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" [[package]] name = "proc-macro2" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" dependencies = [ - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] name = "rand_chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", + "rand_core", ] [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core", ] [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "regex" version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" dependencies = [ - "aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", ] [[package]] name = "regex-syntax" version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "ring" version = "0.16.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" dependencies = [ - "cc 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.9", ] [[package]] name = "rmp" version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f" dependencies = [ - "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "num-traits", ] [[package]] name = "rmp-serde" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1ee98f14fe8b8e9c5ea13d25da7b2a1796169202c57a09d7288de90d56222b" dependencies = [ - "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "rmp", + "serde", ] [[package]] name = "roxmltree" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5001f134077069d87f77c8b9452b690df2445f7a43f1c7ca4a1af8dd505789d" dependencies = [ - "xmlparser 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "xmlparser", ] [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver", ] [[package]] name = "rustls" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", - "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "base64", + "log", + "ring", + "sct", + "webpki", ] [[package]] name = "rustversion" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "scoped-tls" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sct" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" dependencies = [ - "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ring", + "untrusted", ] [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" dependencies = [ - "serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive", ] [[package]] name = "serde_bytes" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" dependencies = [ - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "serde_derive" version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "serde_json" version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" dependencies = [ - "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "sha2" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", ] [[package]] name = "signal-hook-registry" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" dependencies = [ - "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "libc", ] [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "sled" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb6824dde66ad33bf20c6e8476f5b82b871bc8bc3c129a10ea2f7dae5060fa3" dependencies = [ - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot", ] [[package]] name = "smallvec" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" [[package]] name = "socket2" version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.9", ] [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "structopt" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" dependencies = [ - "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "lazy_static", + "structopt-derive", ] [[package]] name = "structopt-derive" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "subtle" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "syn" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "syn-mid" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "synstructure" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", + "unicode-xid", ] [[package]] name = "termcolor" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" dependencies = [ - "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "thread_local" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", ] [[package]] name = "time" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.9", ] [[package]] name = "tinyvec" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" [[package]] name = "tokio" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-uds", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "slab", + "tokio-macros", + "winapi 0.3.9", ] [[package]] name = "tokio-macros" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "tokio-rustls" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4" dependencies = [ - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "rustls", + "tokio", + "webpki", ] [[package]] name = "tokio-util" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ - "bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.5", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", ] [[package]] name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ - "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "tower-service" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" [[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", ] [[package]] name = "unicode-normalization" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "tinyvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tinyvec", ] [[package]] name = "unicode-segmentation" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "idna", + "matches", + "percent-encoding", ] [[package]] name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log", + "try-lock", ] [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df" dependencies = [ - "bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8" dependencies = [ - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "quote", + "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75" dependencies = [ - "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae" [[package]] name = "web-sys" version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d" dependencies = [ - "js-sys 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "wasm-bindgen", ] [[package]] name = "webpki" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae" dependencies = [ - "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ring", + "untrusted", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "ws2_32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "xmlparser" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" -"checksum arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" -"checksum async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" -"checksum cc 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" -"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -"checksum digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -"checksum err-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" -"checksum futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" -"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" -"checksum futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" -"checksum futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" -"checksum futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" -"checksum futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" -"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" -"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" -"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -"checksum garage_model 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6403312b28077fd585e5f96184d2d56142f10eb42709d2893294d70a892d73f" -"checksum garage_rpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ef794407808c89f300f73457bdc567c953b323d7fe30534aba686a28ebb4a0d" -"checksum garage_table 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567d7e9f791a1d65d26e36840aa0570b3a2144302c32f62b5e63a39f147cbf57" -"checksum garage_util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77de76a4167c041094f3f3415c6d3d773373e0326668fbce70dfd3b024788800" -"checksum generator 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" -"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -"checksum generic-array 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" -"checksum gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -"checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" -"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" -"checksum http-range 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2e4003e6fd05ea9109db00415e670b11f511a42e567ff2d5d771cbdfa24e02" -"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -"checksum httpdate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" -"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f" -"checksum hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" -"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum indexmap 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" -"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" -"checksum js-sys 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" -"checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum loom 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum md-5 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" -"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" -"checksum memoffset 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" -"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" -"checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" -"checksum num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" -"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" -"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" -"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -"checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -"checksum parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)" = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" -"checksum pin-project-internal 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" -"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" -"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" -"checksum pretty_env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -"checksum proc-macro-error 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" -"checksum proc-macro-error-attr 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" -"checksum proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" -"checksum proc-macro-nested 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" -"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" -"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" -"checksum ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)" = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" -"checksum rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f" -"checksum rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1ee98f14fe8b8e9c5ea13d25da7b2a1796169202c57a09d7288de90d56222b" -"checksum roxmltree 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5001f134077069d87f77c8b9452b690df2445f7a43f1c7ca4a1af8dd505789d" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" -"checksum rustversion 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" -"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" -"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" -"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 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" -"checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -"checksum serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" -"checksum serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)" = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" -"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb6824dde66ad33bf20c6e8476f5b82b871bc8bc3c129a10ea2f7dae5060fa3" -"checksum smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" -"checksum socket2 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" -"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -"checksum structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" -"checksum structopt-derive 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" -"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" -"checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -"checksum synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" -"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -"checksum tinyvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" -"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" -"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" -"checksum tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4" -"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" -"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -"checksum untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" -"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" -"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2" -"checksum wasm-bindgen-backend 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df" -"checksum wasm-bindgen-macro 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8" -"checksum wasm-bindgen-macro-support 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75" -"checksum wasm-bindgen-shared 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae" -"checksum web-sys 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)" = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d" -"checksum webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum xmlparser 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5" +checksum = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5" diff --git a/Cargo.toml b/Cargo.toml index 7a8c74e9..739e698e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "src/table", "src/model", "src/api", + "src/web", "src/garage", ] diff --git a/src/garage/server.rs b/src/garage/server.rs index 6caea5eb..8962a8da 100644 --- a/src/garage/server.rs +++ b/src/garage/server.rs @@ -9,6 +9,7 @@ use garage_util::config::*; use garage_util::error::Error; use garage_api::api_server; +use garage_web::web_server; use garage_model::garage::Garage; use garage_rpc::rpc_server::RpcServer; @@ -56,6 +57,7 @@ pub async fn run_server(config_file: PathBuf) -> Result<(), Error> { info!("Initializing RPC and API servers..."); let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone())); let api_server = api_server::run_api_server(garage.clone(), wait_from(watch_cancel.clone())); + let web_server = web_server::run_web_server(garage.clone(), wait_from(watch_cancel.clone())); futures::try_join!( garage @@ -78,6 +80,10 @@ pub async fn run_server(config_file: PathBuf) -> Result<(), Error> { info!("API server exited"); rv }), + web_server.map(|rv| { + info!("Web server exited"); + rv + }), background.run().map(|rv| { info!("Background runner exited"); Ok(rv) diff --git a/src/util/config.rs b/src/util/config.rs index a78ef830..a5fbe4b4 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -54,7 +54,7 @@ pub struct ApiConfig { #[derive(Deserialize, Debug, Clone)] pub struct WebConfig { - pub website_bind_addr: SocketAddr, + pub web_bind_addr: SocketAddr, } fn default_max_concurrent_rpc_requests() -> usize { diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml new file mode 100644 index 00000000..8b3743dc --- /dev/null +++ b/src/web/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "garage_web" +version = "0.1.0" +authors = ["Alex Auvolat ", "Quentin Dufour "] +edition = "2018" +license = "GPL-3.0" +description = "Utility crate for the Garage object store" +repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage" + +[lib] +path = "lib.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +garage_util = { version = "0.1", path = "../util" } +garage_table = { version = "0.1.1", path = "../table" } +garage_model = { version = "0.1.1", path = "../model" } + +rand = "0.7" +hex = "0.3" +sha2 = "0.8" +err-derive = "0.2.3" +log = "0.4" + +sled = "0.31" + +toml = "0.5" +rmp-serde = "0.14.3" +serde = { version = "1.0", default-features = false, features = ["derive", "rc"] } +serde_json = "1.0" + +futures = "0.3" +futures-util = "0.3" +tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] } + +http = "0.2" +hyper = "0.13" +rustls = "0.17" +webpki = "0.21" + +roxmltree = "0.11" + diff --git a/src/web/lib.rs b/src/web/lib.rs new file mode 100644 index 00000000..80957669 --- /dev/null +++ b/src/web/lib.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate log; + +pub mod web_server; + diff --git a/src/web/web_server.rs b/src/web/web_server.rs new file mode 100644 index 00000000..cb81e433 --- /dev/null +++ b/src/web/web_server.rs @@ -0,0 +1,37 @@ +use std::sync::Arc; + +use futures::future::Future; + +use hyper::server::conn::AddrStream; +use hyper::{Body,Request,Response,Server}; +use hyper::service::{make_service_fn, service_fn}; + +use garage_util::error::Error; +use garage_model::garage::Garage; + +pub async fn run_web_server( + garage: Arc, + shutdown_signal: impl Future, +) -> Result<(), Error> { + let addr = &garage.config.s3_web.web_bind_addr; + + let service = make_service_fn(|conn: &AddrStream| { + let garage = garage.clone(); + let client_addr = conn.remote_addr(); + info!("{:?}", client_addr); + async move { + Ok::<_, Error>(service_fn(move |req: Request| { + let garage = garage.clone(); + //handler(garage, req, client_addr) + async move { Ok::, Error>(Response::new(Body::from("hello world\n"))) } + })) + } + }); + + let server = Server::bind(&addr).serve(service); + let graceful = server.with_graceful_shutdown(shutdown_signal); + info!("Web server listening on http://{}", addr); + + graceful.await?; + Ok(()) +} From b3caa3628dbe26c76494333472815c9b59a1104c Mon Sep 17 00:00:00 2001 From: Quentin Date: Mon, 2 Nov 2020 15:57:23 +0100 Subject: [PATCH 03/49] Fix description of the crate --- src/web/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 8b3743dc..796478ae 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Alex Auvolat ", "Quentin Dufour "] edition = "2018" license = "GPL-3.0" -description = "Utility crate for the Garage object store" +description = "S3-like website endpoint crate for the Garage object store" repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage" [lib] From 0d3bc169ee66d937bf88a8b7ee284043ce4a9bcd Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 3 Nov 2020 12:37:16 +0100 Subject: [PATCH 04/49] It compiles! --- Cargo.lock | 1 + src/garage/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c31bc209..6e1c97ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,6 +409,7 @@ dependencies = [ "garage_rpc 0.1.0", "garage_table 0.1.1", "garage_util 0.1.0", + "garage_web", "hex", "log", "pretty_env_logger", diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml index cb16bcd4..39288f40 100644 --- a/src/garage/Cargo.toml +++ b/src/garage/Cargo.toml @@ -19,6 +19,7 @@ garage_rpc = { version = "0.1", path = "../rpc" } garage_table = { version = "0.1.1", path = "../table" } garage_model = { version = "0.1.1", path = "../model" } garage_api = { version = "0.1.1", path = "../api" } +garage_web = { version = "0.1", path = "../web" } bytes = "0.4" rand = "0.7" From 154f71f41003fa9e0e26312ac2aaeff2dcc83082 Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 6 Nov 2020 14:23:56 +0100 Subject: [PATCH 05/49] Fix README + create dev config file --- README.md | 5 ++++- config.dev.toml | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 config.dev.toml diff --git a/README.md b/README.md index 9cde4f6c..b8b0287b 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,10 @@ node_key = "/path/to/garage/pki/garage.key" [s3_api] api_bind_addr = "[::1]:3900" # the S3 API port, HTTP without TLS. Add a reverse proxy for the TLS part. -region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. +s3_region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. + +[s3_web] +web_bind_addr = "[::1]:3902" ``` Build Garage using `cargo build --release`. diff --git a/config.dev.toml b/config.dev.toml new file mode 100644 index 00000000..966bee4b --- /dev/null +++ b/config.dev.toml @@ -0,0 +1,20 @@ +block_size = 1048576 # objects are split in blocks of maximum this number of bytes + +metadata_dir = "/tmp/garage-meta" +data_dir = "/tmp/garage-data" + +rpc_bind_addr = "[::]:3901" # the port other Garage nodes will use to talk to this node + +bootstrap_peers = [] + +max_concurrent_rpc_requests = 12 +data_replication_factor = 3 +meta_replication_factor = 3 +meta_epidemic_fanout = 3 + +[s3_api] +api_bind_addr = "[::1]:3900" # the S3 API port, HTTP without TLS. Add a reverse proxy for the TLS part. +s3_region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. + +[s3_web] +web_bind_addr = "[::1]:3902" From 0791e7164e77147b785232adfe91ec01f5c6c6af Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 8 Nov 2020 15:47:25 +0100 Subject: [PATCH 06/49] Parse host header --- src/web/web_server.rs | 71 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index cb81e433..a615ec8f 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,9 +1,11 @@ use std::sync::Arc; +use std::net::SocketAddr; use futures::future::Future; use hyper::server::conn::AddrStream; -use hyper::{Body,Request,Response,Server}; +use hyper::{Body,Request,Response,Server,Uri}; +use hyper::header::HOST; use hyper::service::{make_service_fn, service_fn}; use garage_util::error::Error; @@ -22,8 +24,7 @@ pub async fn run_web_server( async move { Ok::<_, Error>(service_fn(move |req: Request| { let garage = garage.clone(); - //handler(garage, req, client_addr) - async move { Ok::, Error>(Response::new(Body::from("hello world\n"))) } + handler(garage, req, client_addr) })) } }); @@ -35,3 +36,67 @@ pub async fn run_web_server( graceful.await?; Ok(()) } + +async fn handler( + garage: Arc, + req: Request, + addr: SocketAddr, +) -> Result, Error> { + + // Get http authority string (eg. [::1]:3902) + let authority = req + .headers() + .get(HOST) + .ok_or(Error::BadRequest(format!("HOST header required")))? + .to_str()?; + info!("authority is {}", authority); + + // Get HTTP domain/ip from host + //let domain = host.to_socket_ + + + Ok(Response::new(Body::from("hello world\n"))) +} + +fn authority_to_host(authority: &str) -> Result { + let mut uri_str: String = "fake://".to_owned(); + uri_str.push_str(authority); + + match uri_str.parse::() { + Ok(uri) => { + let host = uri + .host() + .ok_or(Error::BadRequest(format!("Unable to extract host from authority as string")))?; + Ok(String::from(host)) + } + _ => Err(Error::BadRequest(format!("Unable to parse authority (host HTTP header)"))), + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn authority_to_host_with_port() -> Result<(), Error> { + let domain = authority_to_host("[::1]:3902")?; + assert_eq!(domain, "[::1]"); + let domain2 = authority_to_host("garage.tld:65200")?; + assert_eq!(domain2, "garage.tld"); + let domain3 = authority_to_host("127.0.0.1:80")?; + assert_eq!(domain3, "127.0.0.1"); + Ok(()) + } + + #[test] + fn authority_to_host_without_port() -> Result<(), Error> { + let domain = authority_to_host("[::1]")?; + assert_eq!(domain, "[::1]"); + let domain2 = authority_to_host("garage.tld")?; + assert_eq!(domain2, "garage.tld"); + let domain3 = authority_to_host("127.0.0.1")?; + assert_eq!(domain3, "127.0.0.1"); + Ok(()) + } +} From c78df603d7355563c9f726f97bf318273fc5bb83 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 8 Nov 2020 16:02:16 +0100 Subject: [PATCH 07/49] Add some documentation --- src/web/web_server.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index a615ec8f..ce1f7ee1 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -58,7 +58,15 @@ async fn handler( Ok(Response::new(Body::from("hello world\n"))) } +/// Extract host from the authority section given by the HTTP host header +/// +/// The HTTP host contains both a host and a port. +/// Extracting the port is more complex than just finding the colon (:) symbol. +/// An example of a case where it does not work: [::1]:3902 +/// Instead, we use the Uri module provided by Hyper that correctl parses this "authority" section fn authority_to_host(authority: &str) -> Result { + // Hyper can not directly parse authority section so we build a fake URL + // that contains our authority section let mut uri_str: String = "fake://".to_owned(); uri_str.push_str(authority); @@ -66,7 +74,7 @@ fn authority_to_host(authority: &str) -> Result { Ok(uri) => { let host = uri .host() - .ok_or(Error::BadRequest(format!("Unable to extract host from authority as string")))?; + .ok_or(Error::BadRequest(format!("Unable to extract host from authority")))?; Ok(String::from(host)) } _ => Err(Error::BadRequest(format!("Unable to parse authority (host HTTP header)"))), From 09137fd6b5ff30639addcac837bc1c6e6ff78fcf Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 8 Nov 2020 16:06:52 +0100 Subject: [PATCH 08/49] Log host --- src/web/web_server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index ce1f7ee1..a712a5bd 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -52,8 +52,8 @@ async fn handler( info!("authority is {}", authority); // Get HTTP domain/ip from host - //let domain = host.to_socket_ - + let host = authority_to_host(authority)?; + info!("host is {}", host); Ok(Response::new(Body::from("hello world\n"))) } From 4093833ae854df16bc893a21617b0902a5beae47 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 09:57:07 +0100 Subject: [PATCH 09/49] Extract bucket --- Cargo.lock | 1 + src/util/config.rs | 3 ++- src/web/Cargo.toml | 1 + src/web/web_server.rs | 55 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e1c97ae..9a06d31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,6 +661,7 @@ dependencies = [ "http", "hyper", "log", + "percent-encoding", "rand", "rmp-serde", "roxmltree", diff --git a/src/util/config.rs b/src/util/config.rs index a5fbe4b4..72f7c319 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -54,7 +54,8 @@ pub struct ApiConfig { #[derive(Deserialize, Debug, Clone)] pub struct WebConfig { - pub web_bind_addr: SocketAddr, + pub bind_addr: SocketAddr, + pub root_domain: String, } fn default_max_concurrent_rpc_requests() -> usize { diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 796478ae..8eddf047 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -36,6 +36,7 @@ tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt- http = "0.2" hyper = "0.13" +percent-encoding = "2.1.0" rustls = "0.17" webpki = "0.21" diff --git a/src/web/web_server.rs b/src/web/web_server.rs index a712a5bd..432d9752 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -15,7 +15,7 @@ pub async fn run_web_server( garage: Arc, shutdown_signal: impl Future, ) -> Result<(), Error> { - let addr = &garage.config.s3_web.web_bind_addr; + let addr = &garage.config.s3_web.bind_addr; let service = make_service_fn(|conn: &AddrStream| { let garage = garage.clone(); @@ -43,17 +43,23 @@ async fn handler( addr: SocketAddr, ) -> Result, Error> { - // Get http authority string (eg. [::1]:3902) + // Get http authority string (eg. [::1]:3902 or garage.tld:80) let authority = req .headers() .get(HOST) .ok_or(Error::BadRequest(format!("HOST header required")))? .to_str()?; - info!("authority is {}", authority); - // Get HTTP domain/ip from host + // Get bucket let host = authority_to_host(authority)?; - info!("host is {}", host); + let root = &garage.config.s3_web.root_domain; + let bucket = host_to_bucket(&host, root); + + // Get path + let path = req.uri().path().to_string(); + let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; + + info!("host: {}, bucket: {}, key: {}", host, bucket, key); Ok(Response::new(Body::from("hello world\n"))) } @@ -81,6 +87,18 @@ fn authority_to_host(authority: &str) -> Result { } } +fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { + if root.len() >= host.len() || !host.ends_with(root) { + return host; + } + + let len_diff = host.len() - root.len(); + let missing_starting_dot = root.chars().next() != Some('.'); + let cursor = if missing_starting_dot { len_diff - 1 } else { len_diff }; + &host[..cursor] +} + + #[cfg(test)] mod tests { @@ -107,4 +125,31 @@ mod tests { assert_eq!(domain3, "127.0.0.1"); Ok(()) } + + #[test] + fn host_to_bucket_test() { + assert_eq!( + host_to_bucket("john.doe.garage.tld", ".garage.tld"), + "john.doe"); + + assert_eq!( + host_to_bucket("john.doe.garage.tld", "garage.tld"), + "john.doe"); + + assert_eq!( + host_to_bucket("john.doe.com", "garage.tld"), + "john.doe.com"); + + assert_eq!( + host_to_bucket("john.doe.com", ".garage.tld"), + "john.doe.com"); + + assert_eq!( + host_to_bucket("garage.tld", "garage.tld"), + "garage.tld"); + + assert_eq!( + host_to_bucket("garage.tld", ".garage.tld"), + "garage.tld"); + } } From 27795a390ced369a5fda353c046cdd4b7ca98bd0 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 09:59:52 +0100 Subject: [PATCH 10/49] Fix formatting --- src/garage/server.rs | 2 +- src/web/lib.rs | 1 - src/web/web_server.rs | 74 +++++++++++++++++++++---------------------- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/garage/server.rs b/src/garage/server.rs index 8962a8da..ec78c067 100644 --- a/src/garage/server.rs +++ b/src/garage/server.rs @@ -9,9 +9,9 @@ use garage_util::config::*; use garage_util::error::Error; use garage_api::api_server; -use garage_web::web_server; use garage_model::garage::Garage; use garage_rpc::rpc_server::RpcServer; +use garage_web::web_server; use crate::admin_rpc::*; diff --git a/src/web/lib.rs b/src/web/lib.rs index 80957669..c0c668a1 100644 --- a/src/web/lib.rs +++ b/src/web/lib.rs @@ -2,4 +2,3 @@ extern crate log; pub mod web_server; - diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 432d9752..ca9b559a 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,15 +1,15 @@ -use std::sync::Arc; use std::net::SocketAddr; +use std::sync::Arc; use futures::future::Future; -use hyper::server::conn::AddrStream; -use hyper::{Body,Request,Response,Server,Uri}; use hyper::header::HOST; +use hyper::server::conn::AddrStream; use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Request, Response, Server, Uri}; -use garage_util::error::Error; use garage_model::garage::Garage; +use garage_util::error::Error; pub async fn run_web_server( garage: Arc, @@ -21,7 +21,7 @@ pub async fn run_web_server( let garage = garage.clone(); let client_addr = conn.remote_addr(); info!("{:?}", client_addr); - async move { + async move { Ok::<_, Error>(service_fn(move |req: Request| { let garage = garage.clone(); handler(garage, req, client_addr) @@ -42,7 +42,6 @@ async fn handler( req: Request, addr: SocketAddr, ) -> Result, Error> { - // Get http authority string (eg. [::1]:3902 or garage.tld:80) let authority = req .headers() @@ -52,13 +51,13 @@ async fn handler( // Get bucket let host = authority_to_host(authority)?; - let root = &garage.config.s3_web.root_domain; - let bucket = host_to_bucket(&host, root); + let root = &garage.config.s3_web.root_domain; + let bucket = host_to_bucket(&host, root); // Get path let path = req.uri().path().to_string(); let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; - + info!("host: {}, bucket: {}, key: {}", host, bucket, key); Ok(Response::new(Body::from("hello world\n"))) @@ -78,12 +77,14 @@ fn authority_to_host(authority: &str) -> Result { match uri_str.parse::() { Ok(uri) => { - let host = uri - .host() - .ok_or(Error::BadRequest(format!("Unable to extract host from authority")))?; + let host = uri.host().ok_or(Error::BadRequest(format!( + "Unable to extract host from authority" + )))?; Ok(String::from(host)) } - _ => Err(Error::BadRequest(format!("Unable to parse authority (host HTTP header)"))), + _ => Err(Error::BadRequest(format!( + "Unable to parse authority (host HTTP header)" + ))), } } @@ -94,12 +95,14 @@ fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { let len_diff = host.len() - root.len(); let missing_starting_dot = root.chars().next() != Some('.'); - let cursor = if missing_starting_dot { len_diff - 1 } else { len_diff }; - &host[..cursor] + let cursor = if missing_starting_dot { + len_diff - 1 + } else { + len_diff + }; + &host[..cursor] } - - #[cfg(test)] mod tests { use super::*; @@ -128,28 +131,25 @@ mod tests { #[test] fn host_to_bucket_test() { - assert_eq!( - host_to_bucket("john.doe.garage.tld", ".garage.tld"), - "john.doe"); - - assert_eq!( - host_to_bucket("john.doe.garage.tld", "garage.tld"), - "john.doe"); - assert_eq!( - host_to_bucket("john.doe.com", "garage.tld"), - "john.doe.com"); - + host_to_bucket("john.doe.garage.tld", ".garage.tld"), + "john.doe" + ); + + assert_eq!( + host_to_bucket("john.doe.garage.tld", "garage.tld"), + "john.doe" + ); + + assert_eq!(host_to_bucket("john.doe.com", "garage.tld"), "john.doe.com"); + assert_eq!( host_to_bucket("john.doe.com", ".garage.tld"), - "john.doe.com"); - - assert_eq!( - host_to_bucket("garage.tld", "garage.tld"), - "garage.tld"); - - assert_eq!( - host_to_bucket("garage.tld", ".garage.tld"), - "garage.tld"); + "john.doe.com" + ); + + assert_eq!(host_to_bucket("garage.tld", "garage.tld"), "garage.tld"); + + assert_eq!(host_to_bucket("garage.tld", ".garage.tld"), "garage.tld"); } } From 1e52ee9f5b7532df79c16a9c6e71adbcceaed187 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 15:26:48 +0100 Subject: [PATCH 11/49] Rewrite authority to host while staying on stack --- src/web/web_server.rs | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index ca9b559a..f38d8fd2 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -6,7 +6,7 @@ use futures::future::Future; use hyper::header::HOST; use hyper::server::conn::AddrStream; use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Request, Response, Server, Uri}; +use hyper::{Body, Request, Response, Server}; use garage_model::garage::Garage; use garage_util::error::Error; @@ -58,7 +58,7 @@ async fn handler( let path = req.uri().path().to_string(); let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; - info!("host: {}, bucket: {}, key: {}", host, bucket, key); + info!("Selected bucket: {}, selected key: {}", bucket, key); Ok(Response::new(Body::from("hello world\n"))) } @@ -66,28 +66,29 @@ async fn handler( /// Extract host from the authority section given by the HTTP host header /// /// The HTTP host contains both a host and a port. -/// Extracting the port is more complex than just finding the colon (:) symbol. -/// An example of a case where it does not work: [::1]:3902 -/// Instead, we use the Uri module provided by Hyper that correctl parses this "authority" section -fn authority_to_host(authority: &str) -> Result { - // Hyper can not directly parse authority section so we build a fake URL - // that contains our authority section - let mut uri_str: String = "fake://".to_owned(); - uri_str.push_str(authority); +/// Extracting the port is more complex than just finding the colon (:) symbol due to IPv6 +/// we do not use the collect pattern as there is no way in std rust to collect over a stack allocated value +/// check here: https://docs.rs/collect_slice/1.2.0/collect_slice/ +fn authority_to_host(authority: &str) -> Result<&str, Error> { + let mut iter = authority.chars().enumerate(); + let split = match iter.next() { + Some((_, '[')) => { + let mut niter = iter.skip_while(|(_, c)| c != &']'); + niter.next().ok_or(Error::BadRequest(format!("Authority {} has an illegal format", authority)))?; + niter.next() + }, + Some((_, _)) => iter.skip_while(|(_, c)| c != &':').next(), + None => return Err(Error::BadRequest(format!("Authority is empty"))), + }; - match uri_str.parse::() { - Ok(uri) => { - let host = uri.host().ok_or(Error::BadRequest(format!( - "Unable to extract host from authority" - )))?; - Ok(String::from(host)) - } - _ => Err(Error::BadRequest(format!( - "Unable to parse authority (host HTTP header)" - ))), + match split { + Some((i, ':')) => Ok(&authority[..i]), + None => Ok(authority), + Some((_, _)) => Err(Error::BadRequest(format!("Authority {} has an illegal format", authority))), } } + fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { if root.len() >= host.len() || !host.ends_with(root) { return host; From 8797eed0abdefac9a550b7ef55f60ba5899a17bf Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 15:32:04 +0100 Subject: [PATCH 12/49] Fixes due to integration tests --- config.dev.toml | 3 ++- src/web/web_server.rs | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config.dev.toml b/config.dev.toml index 966bee4b..88378e50 100644 --- a/config.dev.toml +++ b/config.dev.toml @@ -17,4 +17,5 @@ api_bind_addr = "[::1]:3900" # the S3 API port, HTTP without TLS. Add a reverse s3_region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. [s3_web] -web_bind_addr = "[::1]:3902" +bind_addr = "[::1]:3902" +root_domain = ".garage.tld" diff --git a/src/web/web_server.rs b/src/web/web_server.rs index f38d8fd2..2c6185a1 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -20,7 +20,6 @@ pub async fn run_web_server( let service = make_service_fn(|conn: &AddrStream| { let garage = garage.clone(); let client_addr = conn.remote_addr(); - info!("{:?}", client_addr); async move { Ok::<_, Error>(service_fn(move |req: Request| { let garage = garage.clone(); @@ -58,7 +57,7 @@ async fn handler( let path = req.uri().path().to_string(); let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; - info!("Selected bucket: {}, selected key: {}", bucket, key); + info!("Selected bucket: \"{}\", selected key: \"{}\"", bucket, key); Ok(Response::new(Body::from("hello world\n"))) } From ab62c59acb49d1f3563d546eb6af13bf40739c2f Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 15:40:33 +0100 Subject: [PATCH 13/49] Fix indent again --- src/web/web_server.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 2c6185a1..cda7f52e 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -71,23 +71,28 @@ async fn handler( fn authority_to_host(authority: &str) -> Result<&str, Error> { let mut iter = authority.chars().enumerate(); let split = match iter.next() { - Some((_, '[')) => { + Some((_, '[')) => { let mut niter = iter.skip_while(|(_, c)| c != &']'); - niter.next().ok_or(Error::BadRequest(format!("Authority {} has an illegal format", authority)))?; + niter.next().ok_or(Error::BadRequest(format!( + "Authority {} has an illegal format", + authority + )))?; niter.next() - }, + } Some((_, _)) => iter.skip_while(|(_, c)| c != &':').next(), None => return Err(Error::BadRequest(format!("Authority is empty"))), }; - match split { + match split { Some((i, ':')) => Ok(&authority[..i]), None => Ok(authority), - Some((_, _)) => Err(Error::BadRequest(format!("Authority {} has an illegal format", authority))), + Some((_, _)) => Err(Error::BadRequest(format!( + "Authority {} has an illegal format", + authority + ))), } } - fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { if root.len() >= host.len() || !host.ends_with(root) { return host; From d1b2fcc1e7d54025625c62bff7ef8cb573fab456 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 15:48:40 +0100 Subject: [PATCH 14/49] Rewrite for clarity --- src/web/web_server.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index cda7f52e..e4d15872 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -66,21 +66,24 @@ async fn handler( /// /// The HTTP host contains both a host and a port. /// Extracting the port is more complex than just finding the colon (:) symbol due to IPv6 -/// we do not use the collect pattern as there is no way in std rust to collect over a stack allocated value +/// We do not use the collect pattern as there is no way in std rust to collect over a stack allocated value /// check here: https://docs.rs/collect_slice/1.2.0/collect_slice/ fn authority_to_host(authority: &str) -> Result<&str, Error> { let mut iter = authority.chars().enumerate(); - let split = match iter.next() { - Some((_, '[')) => { - let mut niter = iter.skip_while(|(_, c)| c != &']'); - niter.next().ok_or(Error::BadRequest(format!( + let (_, first_char) = iter + .next() + .ok_or(Error::BadRequest(format!("Authority is empty")))?; + + let split = match first_char { + '[' => { + let mut iter = iter.skip_while(|(_, c)| c != &']'); + iter.next().ok_or(Error::BadRequest(format!( "Authority {} has an illegal format", authority )))?; - niter.next() + iter.next() } - Some((_, _)) => iter.skip_while(|(_, c)| c != &':').next(), - None => return Err(Error::BadRequest(format!("Authority is empty"))), + _ => iter.skip_while(|(_, c)| c != &':').next(), }; match split { From cacf8ddf2da9c80574647aeb0d61dd15f9f8c5d5 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 15:52:20 +0100 Subject: [PATCH 15/49] Panic when it is a logical error --- src/web/web_server.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index e4d15872..73aa6648 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -77,10 +77,7 @@ fn authority_to_host(authority: &str) -> Result<&str, Error> { let split = match first_char { '[' => { let mut iter = iter.skip_while(|(_, c)| c != &']'); - iter.next().ok_or(Error::BadRequest(format!( - "Authority {} has an illegal format", - authority - )))?; + iter.next().expect("Authority parsing logic error"); iter.next() } _ => iter.skip_while(|(_, c)| c != &':').next(), From 3cb3994cd2005231f8cc60ce02c55762a7b293f3 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 10 Nov 2020 17:05:10 +0100 Subject: [PATCH 16/49] Add documentation to host_to_bucket --- src/web/web_server.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 73aa6648..2440857d 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -93,6 +93,12 @@ fn authority_to_host(authority: &str) -> Result<&str, Error> { } } +/// Host to bucket +/// +/// Convert a host, like "bucket.garage-site.tld" or "john.doe.com" +/// to the corresponding bucket, resp. "bucket" and "john.doe.com" +/// considering that ".garage-site.tld" is the "root domain". +/// This behavior has been chosen to follow AWS S3 semantic. fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { if root.len() >= host.len() || !host.ends_with(root) { return host; From d445c4ef9cd6835ec7e2e543e9e462adcd0f58bf Mon Sep 17 00:00:00 2001 From: Quentin Date: Wed, 11 Nov 2020 15:24:25 +0100 Subject: [PATCH 17/49] WIP fetch object --- src/web/web_server.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 2440857d..cbb2aaac 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -57,6 +57,13 @@ async fn handler( let path = req.uri().path().to_string(); let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; + // Get bucket descriptor + let object = garage + .object_table + .get(&bucket.to_string(), &key.to_string()) + .await? + .ok_or(Error::NotFound)?; + info!("Selected bucket: \"{}\", selected key: \"{}\"", bucket, key); Ok(Response::new(Body::from("hello world\n"))) From 2765291796de1b94401e462dc5136fdfce867596 Mon Sep 17 00:00:00 2001 From: Quentin Date: Wed, 11 Nov 2020 19:48:01 +0100 Subject: [PATCH 18/49] Build path correctly --- README.md | 4 +++- config.dev.toml | 1 + src/util/config.rs | 1 + src/web/web_server.rs | 40 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 816a1c95..fed129d5 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,9 @@ api_bind_addr = "[::1]:3900" # the S3 API port, HTTP without TLS. Add a reverse s3_region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. [s3_web] -web_bind_addr = "[::1]:3902" +bind_addr = "[::1]:3902" +root_domain = ".garage.tld" +index = "index.html" ``` Build Garage using `cargo build --release`. diff --git a/config.dev.toml b/config.dev.toml index 88378e50..215bc50c 100644 --- a/config.dev.toml +++ b/config.dev.toml @@ -19,3 +19,4 @@ s3_region = "garage" # set this to anything. S3 API calls will fail if they a [s3_web] bind_addr = "[::1]:3902" root_domain = ".garage.tld" +index = "index.html" diff --git a/src/util/config.rs b/src/util/config.rs index 72f7c319..f4c841b7 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -56,6 +56,7 @@ pub struct ApiConfig { pub struct WebConfig { pub bind_addr: SocketAddr, pub root_domain: String, + pub index: String, } fn default_max_concurrent_rpc_requests() -> usize { diff --git a/src/web/web_server.rs b/src/web/web_server.rs index cbb2aaac..16b27cef 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::net::SocketAddr; use std::sync::Arc; @@ -55,17 +56,18 @@ async fn handler( // Get path let path = req.uri().path().to_string(); - let key = percent_encoding::percent_decode_str(&path).decode_utf8()?; + let index = &garage.config.s3_web.index; + let key = path_to_key(&path, &index)?; - // Get bucket descriptor + info!("Selected bucket: \"{}\", selected key: \"{}\"", bucket, key); + + // Get bucket descriptor let object = garage .object_table .get(&bucket.to_string(), &key.to_string()) .await? .ok_or(Error::NotFound)?; - info!("Selected bucket: \"{}\", selected key: \"{}\"", bucket, key); - Ok(Response::new(Body::from("hello world\n"))) } @@ -121,6 +123,27 @@ fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { &host[..cursor] } +/// Path to key +/// +/// Convert the provided path to the internal key +/// When a path ends with "/", we append the index name to match traditional web server behavior +/// which is also AWS S3 behavior. +fn path_to_key<'a>(path: &'a str, index: &str) -> Result, Error> { + let path_utf8 = percent_encoding::percent_decode_str(&path).decode_utf8()?; + match path_utf8.chars().last() { + None => Err(Error::BadRequest(format!( + "Path must have at least a character" + ))), + Some('/') => { + let mut key = String::with_capacity(path_utf8.len() + index.len()); + key.push_str(&path_utf8); + key.push_str(index); + Ok(key.into()) + } + Some(_) => Ok(path_utf8.into()), + } +} + #[cfg(test)] mod tests { use super::*; @@ -170,4 +193,13 @@ mod tests { assert_eq!(host_to_bucket("garage.tld", ".garage.tld"), "garage.tld"); } + + #[test] + fn path_to_key_test() -> Result<(), Error> { + assert_eq!(path_to_key("/file%20.jpg", "index.html")?, "/file .jpg"); + assert_eq!(path_to_key("/%20t/", "index.html")?, "/ t/index.html"); + assert_eq!(path_to_key("/", "index.html")?, "/index.html"); + assert!(path_to_key("", "index.html").is_err()); + Ok(()) + } } From 6076d869b14aa38059d54a2dece222ad7b9da3bc Mon Sep 17 00:00:00 2001 From: Quentin Date: Wed, 11 Nov 2020 21:17:34 +0100 Subject: [PATCH 19/49] Build error --- src/web/web_server.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 16b27cef..3cc0fa43 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::convert::Infallible; use std::net::SocketAddr; use std::sync::Arc; @@ -24,7 +25,7 @@ pub async fn run_web_server( async move { Ok::<_, Error>(service_fn(move |req: Request| { let garage = garage.clone(); - handler(garage, req, client_addr) + handle_request(garage, req, client_addr) })) } }); @@ -37,11 +38,29 @@ pub async fn run_web_server( Ok(()) } -async fn handler( +async fn handle_request( garage: Arc, req: Request, addr: SocketAddr, -) -> Result, Error> { +) -> Result, Infallible> { + info!("{} {} {}", addr, req.method(), req.uri()); + let res = serve_file(garage, req).await; + match &res { + Ok(r) => debug!("{} {:?}", r.status(), r.headers()), + Err(e) => warn!("Response: error {}, {}", e.http_status_code(), e), + } + + Ok(res.unwrap_or_else(error_to_res)) +} + +fn error_to_res(e: Error) -> Response { + let body: Body = Body::from(format!("{}\n", e)); + let mut http_error = Response::new(body); + *http_error.status_mut() = e.http_status_code(); + http_error +} + +async fn serve_file(garage: Arc, req: Request) -> Result, Error> { // Get http authority string (eg. [::1]:3902 or garage.tld:80) let authority = req .headers() From 04f455ff7f673ae9449b374183b8aafb9347581f Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 19 Nov 2020 14:56:00 +0100 Subject: [PATCH 20/49] Make it compile again --- Cargo.lock | 1 + src/web/error.rs | 51 +++++++++++++++++++++++++++++++++++++++++++ src/web/lib.rs | 2 ++ src/web/web_server.rs | 5 +++-- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/web/error.rs diff --git a/Cargo.lock b/Cargo.lock index 9a06d31d..4e1ad32f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,6 +430,7 @@ dependencies = [ "bytes 0.4.12", "chrono", "crypto-mac", + "err-derive", "futures", "futures-util", "garage_model 0.1.1", diff --git a/src/web/error.rs b/src/web/error.rs new file mode 100644 index 00000000..094b22d0 --- /dev/null +++ b/src/web/error.rs @@ -0,0 +1,51 @@ +use err_derive::Error; +use hyper::StatusCode; + +use garage_util::error::Error as GarageError; + +#[derive(Debug, Error)] +pub enum Error { + // Category: internal error + #[error(display = "Internal error: {}", _0)] + InternalError(#[error(source)] GarageError), + + #[error(display = "Internal error (Hyper error): {}", _0)] + Hyper(#[error(source)] hyper::Error), + + #[error(display = "Internal error (HTTP error): {}", _0)] + HTTP(#[error(source)] http::Error), + + // Category: cannot process + #[error(display = "Forbidden: {}", _0)] + Forbidden(String), + + #[error(display = "Not found")] + NotFound, + + // Category: bad request + #[error(display = "Invalid UTF-8: {}", _0)] + InvalidUTF8(#[error(source)] std::str::Utf8Error), + + #[error(display = "Invalid XML: {}", _0)] + InvalidXML(#[error(source)] roxmltree::Error), + + #[error(display = "Invalid header value: {}", _0)] + InvalidHeader(#[error(source)] hyper::header::ToStrError), + + #[error(display = "Bad request: {}", _0)] + BadRequest(String), +} + +impl Error { + pub fn http_status_code(&self) -> StatusCode { + match self { + Error::NotFound => StatusCode::NOT_FOUND, + Error::Forbidden(_) => StatusCode::FORBIDDEN, + Error::InternalError(GarageError::RPC(_)) => StatusCode::SERVICE_UNAVAILABLE, + Error::InternalError(_) | Error::Hyper(_) | Error::HTTP(_) => { + StatusCode::INTERNAL_SERVER_ERROR + } + _ => StatusCode::BAD_REQUEST, + } + } +} diff --git a/src/web/lib.rs b/src/web/lib.rs index c0c668a1..f28937b9 100644 --- a/src/web/lib.rs +++ b/src/web/lib.rs @@ -1,4 +1,6 @@ #[macro_use] extern crate log; +pub mod error; + pub mod web_server; diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 3cc0fa43..4771d209 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -11,12 +11,13 @@ use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response, Server}; use garage_model::garage::Garage; -use garage_util::error::Error; +use garage_util::error::Error as GarageError; +use crate::error::*; pub async fn run_web_server( garage: Arc, shutdown_signal: impl Future, -) -> Result<(), Error> { +) -> Result<(), GarageError> { let addr = &garage.config.s3_web.bind_addr; let service = make_service_fn(|conn: &AddrStream| { From ab710481761fd6b1814b404362a74b7cf3e89572 Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 19 Nov 2020 15:10:04 +0100 Subject: [PATCH 21/49] Fix example --- example/dev-cluster.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/dev-cluster.sh b/example/dev-cluster.sh index e896b6ba..d0d4326e 100755 --- a/example/dev-cluster.sh +++ b/example/dev-cluster.sh @@ -37,7 +37,9 @@ api_bind_addr = "127.0.0.$count:3900" # the S3 API port, HTTP without TLS. Add a s3_region = "garage" # set this to anything. S3 API calls will fail if they are not made against the region set here. [s3_web] -web_bind_addr = "127.0.0.$count:3902" +bind_addr = "127.0.0.$count:3902" +root_domain = ".garage.tld" +index = "index.html" EOF echo -en "$LABEL configuration written to $CONF_PATH\n" From 5b363626f4803b3e43cdb450fd6ee04ac9429c4d Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 20 Nov 2020 21:23:32 +0100 Subject: [PATCH 22/49] Support punnycode --- Cargo.lock | 1 + src/web/Cargo.toml | 2 +- src/web/web_server.rs | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e1ad32f..9e0a1bb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,6 +661,7 @@ dependencies = [ "hex", "http", "hyper", + "idna", "log", "percent-encoding", "rand", diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 8eddf047..252ee58d 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -41,4 +41,4 @@ rustls = "0.17" webpki = "0.21" roxmltree = "0.11" - +idna = "0.2" diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 4771d209..1c5619fa 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -10,6 +10,8 @@ use hyper::server::conn::AddrStream; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response, Server}; +use idna::domain_to_unicode; + use garage_model::garage::Garage; use garage_util::error::Error as GarageError; use crate::error::*; @@ -70,7 +72,7 @@ async fn serve_file(garage: Arc, req: Request) -> Result Date: Sat, 21 Nov 2020 12:01:02 +0100 Subject: [PATCH 23/49] Fix host to key --- src/web/web_server.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 1c5619fa..7172f222 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -152,17 +152,29 @@ fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { /// which is also AWS S3 behavior. fn path_to_key<'a>(path: &'a str, index: &str) -> Result, Error> { let path_utf8 = percent_encoding::percent_decode_str(&path).decode_utf8()?; + + if path_utf8.chars().next() != Some('/') { + return Err(Error::BadRequest(format!( + "Path must start with a / (slash)" + ))) + } + match path_utf8.chars().last() { None => Err(Error::BadRequest(format!( "Path must have at least a character" ))), Some('/') => { let mut key = String::with_capacity(path_utf8.len() + index.len()); - key.push_str(&path_utf8); + key.push_str(&path_utf8[1..]); key.push_str(index); Ok(key.into()) } - Some(_) => Ok(path_utf8.into()), + Some(_) => { + match path_utf8 { + Cow::Borrowed(pu8) => Ok((&pu8[1..]).into()), + Cow::Owned(pu8) => Ok((&pu8[1..]).to_string().into()), + } + } } } @@ -218,10 +230,12 @@ mod tests { #[test] fn path_to_key_test() -> Result<(), Error> { - assert_eq!(path_to_key("/file%20.jpg", "index.html")?, "/file .jpg"); - assert_eq!(path_to_key("/%20t/", "index.html")?, "/ t/index.html"); - assert_eq!(path_to_key("/", "index.html")?, "/index.html"); + assert_eq!(path_to_key("/file%20.jpg", "index.html")?, "file .jpg"); + assert_eq!(path_to_key("/%20t/", "index.html")?, " t/index.html"); + assert_eq!(path_to_key("/", "index.html")?, "index.html"); + assert_eq!(path_to_key("/hello", "index.html")?, "hello"); assert!(path_to_key("", "index.html").is_err()); + assert!(path_to_key("i/am/relative", "index.html").is_err()); Ok(()) } } From 0f33231ee6154a2b08f67f8107cc686ee9e9c678 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 15:15:25 +0100 Subject: [PATCH 24/49] We are able to serve a file --- Cargo.lock | 1 + src/web/Cargo.toml | 2 + src/web/web_server.rs | 111 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e0a1bb0..a36cdf83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -660,6 +660,7 @@ dependencies = [ "garage_util 0.1.0", "hex", "http", + "httpdate", "hyper", "idna", "log", diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 252ee58d..819b51c1 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -42,3 +42,5 @@ webpki = "0.21" roxmltree = "0.11" idna = "0.2" + +httpdate = "0.3" diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 7172f222..8a222738 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -2,17 +2,23 @@ use std::borrow::Cow; use std::convert::Infallible; use std::net::SocketAddr; use std::sync::Arc; +use std::time::{Duration, UNIX_EPOCH}; use futures::future::Future; +use futures::stream::*; -use hyper::header::HOST; -use hyper::server::conn::AddrStream; -use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Request, Response, Server}; +use hyper::{ + header::HOST, + body::Bytes, + server::conn::AddrStream, + service::{make_service_fn, service_fn}, + Body, Request, Response, Server, StatusCode}; use idna::domain_to_unicode; use garage_model::garage::Garage; +use garage_model::object_table::*; +use garage_table::EmptyKey; use garage_util::error::Error as GarageError; use crate::error::*; @@ -90,7 +96,102 @@ async fn serve_file(garage: Arc, req: Request) -> Result x, + _ => unreachable!(), + }; + + // Get metadata from version + let last_v_meta = match last_v_data { + ObjectVersionData::DeleteMarker => return Err(Error::NotFound), + ObjectVersionData::Inline(meta, _) => meta, + ObjectVersionData::FirstBlock(meta, _) => meta, + }; + + // @FIXME Support range + + + // Set headers + let resp_builder = object_headers(&last_v, last_v_meta).status(StatusCode::OK); + + + // Stream body + match &last_v_data { + ObjectVersionData::DeleteMarker => unreachable!(), + ObjectVersionData::Inline(_, bytes) => { + let body: Body = Body::from(bytes.to_vec()); + Ok(resp_builder.body(body)?) + } + ObjectVersionData::FirstBlock(_, first_block_hash) => { + let read_first_block = garage.block_manager.rpc_get_block(&first_block_hash); + let get_next_blocks = garage.version_table.get(&last_v.uuid, &EmptyKey); + + let (first_block, version) = futures::try_join!(read_first_block, get_next_blocks)?; + let version = version.ok_or(Error::NotFound)?; + + let mut blocks = version + .blocks() + .iter() + .map(|vb| (vb.hash, None)) + .collect::>(); + blocks[0].1 = Some(first_block); + + let body_stream = futures::stream::iter(blocks) + .map(move |(hash, data_opt)| { + let garage = garage.clone(); + async move { + if let Some(data) = data_opt { + Ok(Bytes::from(data)) + } else { + garage + .block_manager + .rpc_get_block(&hash) + .await + .map(Bytes::from) + } + } + }) + .buffered(2); + //let body: Body = Box::new(StreamBody::new(Box::pin(body_stream))); + let body = hyper::body::Body::wrap_stream(body_stream); + Ok(resp_builder.body(body)?) + } + } +} + +// Copied from api/s3_get.rs +fn object_headers( + version: &ObjectVersion, + version_meta: &ObjectVersionMeta, +) -> http::response::Builder { + let date = UNIX_EPOCH + Duration::from_millis(version.timestamp); + let date_str = httpdate::fmt_http_date(date); + + let mut resp = Response::builder() + .header( + "Content-Type", + version_meta.headers.content_type.to_string(), + ) + .header("Content-Length", format!("{}", version_meta.size)) + .header("ETag", version_meta.etag.to_string()) + .header("Last-Modified", date_str) + .header("Accept-Ranges", format!("bytes")); + + for (k, v) in version_meta.headers.other.iter() { + resp = resp.header(k, v.to_string()); + } + + resp } /// Extract host from the authority section given by the HTTP host header From 92ab3eedfc03a6cd770e36745373ca188ed9ee20 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 15:44:09 +0100 Subject: [PATCH 25/49] Use awscli instead of s3cmd --- README.md | 6 +++--- script/dev-bucket.sh | 6 +++--- script/dev-env.sh | 13 +++++-------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7c2cffaf..6d2600e4 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ Our main use case is to provide a distributed storage layer for small-scale self We propose the following quickstart to setup a full dev. environment as quickly as possible: - 1. Setup a rust/cargo environment and install s3cmd. eg. `dnf install rust cargo s3cmd` + 1. Setup a rust/cargo environment and install `awscli`. eg. `dnf install rust cargo awscli` 2. Run `cargo build` to build the project 3. Run `./script/dev-cluster.sh` to launch a test cluster (feel free to read the script) 4. Run `./script/dev-configure.sh` to configure your test cluster with default values (same datacenter, 100 tokens) - 5. Run `./script/dev-bucket.sh` to create a bucket named `éprouvette` and an API key that will be stored in `/tmp/garage.s3` + 5. Run `./script/dev-bucket.sh` to create a bucket named `eprouvette` and an API key that will be stored in `/tmp/garage.s3` 6. Run `source ./script/dev-env.sh` to configure your CLI environment 7. You can use `garage` to manage the cluster. Try `garage --help`. - 8. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg put /proc/cpuinfo s3://éprouvette/cpuinfo.txt`, `s3grg ls s3://éprouvette`. `s3grg` is a wrapper on `s3cmd` configured with the previously generated API key (the one in `/tmp/garage.s3`). + 8. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg cp /proc/cpuinfo s3://eprouvette/cpuinfo.txt`, `s3grg ls s3://eprouvette`. `s3grg` is a wrapper on `s3cmd` configured with the previously generated API key (the one in `/tmp/garage.s3`). Now you should be ready to start hacking on garage! diff --git a/script/dev-bucket.sh b/script/dev-bucket.sh index f07263f5..8c0ef4e4 100755 --- a/script/dev-bucket.sh +++ b/script/dev-bucket.sh @@ -6,11 +6,11 @@ GARAGE_DEBUG="${REPO_FOLDER}/target/debug/" GARAGE_RELEASE="${REPO_FOLDER}/target/release/" PATH="${GARAGE_DEBUG}:${GARAGE_RELEASE}:$PATH" -garage bucket create éprouvette +garage bucket create eprouvette KEY_INFO=`garage key new --name opérateur` ACCESS_KEY=`echo $KEY_INFO|grep -Po 'GK[a-f0-9]+'` SECRET_KEY=`echo $KEY_INFO|grep -Po 'secret_key: "[a-f0-9]+'|grep -Po '[a-f0-9]+$'` -garage bucket allow éprouvette --read --write --key $ACCESS_KEY +garage bucket allow eprouvette --read --write --key $ACCESS_KEY echo "$ACCESS_KEY $SECRET_KEY" > /tmp/garage.s3 -echo "Bucket s3://éprouvette created. Credentials stored in /tmp/garage.s3." +echo "Bucket s3://eprouvette created. Credentials stored in /tmp/garage.s3." diff --git a/script/dev-env.sh b/script/dev-env.sh index 7e8ffc50..61c8618f 100755 --- a/script/dev-env.sh +++ b/script/dev-env.sh @@ -6,13 +6,10 @@ GARAGE_DEBUG="${REPO_FOLDER}/target/debug/" GARAGE_RELEASE="${REPO_FOLDER}/target/release/" PATH="${GARAGE_DEBUG}:${GARAGE_RELEASE}:$PATH" -ACCESS_KEY=`cat /tmp/garage.s3 |cut -d' ' -f1` -SECRET_KEY=`cat /tmp/garage.s3 |cut -d' ' -f2` +export AWS_ACCESS_KEY_ID=`cat /tmp/garage.s3 |cut -d' ' -f1` +export AWS_SECRET_ACCESS_KEY=`cat /tmp/garage.s3 |cut -d' ' -f2` +export AWS_DEFAULT_REGION='garage' -alias s3grg="s3cmd \ - --host 127.0.0.1:3900 \ - --access_key=$ACCESS_KEY \ - --secret_key=$SECRET_KEY \ - --region=garage \ - --no-ssl" +alias s3grg="aws s3 \ + --endpoint-url http://127.0.0.1:3900" From 78be2b363f6747f8dae9c8c86e96c88ae8a054b3 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 15:45:52 +0100 Subject: [PATCH 26/49] Remove s3cmd mention --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d2600e4..9325bcae 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ We propose the following quickstart to setup a full dev. environment as quickly 5. Run `./script/dev-bucket.sh` to create a bucket named `eprouvette` and an API key that will be stored in `/tmp/garage.s3` 6. Run `source ./script/dev-env.sh` to configure your CLI environment 7. You can use `garage` to manage the cluster. Try `garage --help`. - 8. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg cp /proc/cpuinfo s3://eprouvette/cpuinfo.txt`, `s3grg ls s3://eprouvette`. `s3grg` is a wrapper on `s3cmd` configured with the previously generated API key (the one in `/tmp/garage.s3`). + 8. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg cp /proc/cpuinfo s3://eprouvette/cpuinfo.txt`, `s3grg ls s3://eprouvette`. `s3grg` is a wrapper on the `aws s3` subcommand configured with the previously generated API key (the one in `/tmp/garage.s3`). Now you should be ready to start hacking on garage! From a88fd49f71844f04013970a678201a65ab89fb19 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 17:50:19 +0100 Subject: [PATCH 27/49] Use handle_get --- Cargo.lock | 1 + src/api/s3_put.rs | 2 +- src/model/block.rs | 2 +- src/model/bucket_table.rs | 1 - src/table/lib.rs | 2 +- src/table/schema.rs | 4 -- src/web/Cargo.toml | 1 + src/web/error.rs | 3 + src/web/web_server.rs | 136 ++++---------------------------------- 9 files changed, 22 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a36cdf83..53b1874d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -655,6 +655,7 @@ dependencies = [ "err-derive", "futures", "futures-util", + "garage_api", "garage_model 0.1.1", "garage_table 0.1.1", "garage_util 0.1.0", diff --git a/src/api/s3_put.rs b/src/api/s3_put.rs index 72613323..a1681d77 100644 --- a/src/api/s3_put.rs +++ b/src/api/s3_put.rs @@ -322,7 +322,7 @@ pub async fn handle_put_part( let (object, first_block) = futures::try_join!(get_object_fut, get_first_block_fut)?; // Check object is valid and multipart block can be accepted - let first_block = first_block.ok_or(Error::BadRequest(format!("Empty body")))?; + let first_block = first_block.ok_or(Error::BadRequest(format!("Empty body")))?; let object = object.ok_or(Error::BadRequest(format!("Object not found")))?; if !object diff --git a/src/model/block.rs b/src/model/block.rs index 6a5d9c5b..8a513a3c 100644 --- a/src/model/block.rs +++ b/src/model/block.rs @@ -20,7 +20,7 @@ use garage_rpc::rpc_client::*; use garage_rpc::rpc_server::*; use garage_table::table_sharded::TableShardedReplication; -use garage_table::{TableReplication, DeletedFilter}; +use garage_table::{DeletedFilter, TableReplication}; use crate::block_ref_table::*; diff --git a/src/model/bucket_table.rs b/src/model/bucket_table.rs index 35c0cc27..11f853f9 100644 --- a/src/model/bucket_table.rs +++ b/src/model/bucket_table.rs @@ -104,7 +104,6 @@ impl Entry for Bucket { pub struct BucketTable; - #[async_trait] impl TableSchema for BucketTable { type P = EmptyKey; diff --git a/src/table/lib.rs b/src/table/lib.rs index 7684fe9d..a10f78c2 100644 --- a/src/table/lib.rs +++ b/src/table/lib.rs @@ -12,5 +12,5 @@ pub mod table_sharded; pub mod table_sync; pub use schema::*; -pub use util::*; pub use table::*; +pub use util::*; diff --git a/src/table/schema.rs b/src/table/schema.rs index 49cede0a..d2ec9450 100644 --- a/src/table/schema.rs +++ b/src/table/schema.rs @@ -20,7 +20,6 @@ impl PartitionKey for Hash { } } - pub trait SortKey { fn sort_key(&self) -> &[u8]; } @@ -37,7 +36,6 @@ impl SortKey for Hash { } } - pub trait Entry: PartialEq + Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync { @@ -47,7 +45,6 @@ pub trait Entry: fn merge(&mut self, other: &Self); } - #[async_trait] pub trait TableSchema: Send + Sync { type P: PartitionKey + Clone + PartialEq + Serialize + for<'de> Deserialize<'de> + Send + Sync; @@ -66,4 +63,3 @@ pub trait TableSchema: Send + Sync { true } } - diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 819b51c1..0d08fdbf 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -16,6 +16,7 @@ path = "lib.rs" garage_util = { version = "0.1", path = "../util" } garage_table = { version = "0.1.1", path = "../table" } garage_model = { version = "0.1.1", path = "../model" } +garage_api = { version = "0.1.1", path = "../api" } rand = "0.7" hex = "0.3" diff --git a/src/web/error.rs b/src/web/error.rs index 094b22d0..59810f0f 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -5,6 +5,9 @@ use garage_util::error::Error as GarageError; #[derive(Debug, Error)] pub enum Error { + #[error(display = "API error: {}", _0)] + ApiError(#[error(source)] garage_api::error::Error), + // Category: internal error #[error(display = "Internal error: {}", _0)] InternalError(#[error(source)] GarageError), diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 8a222738..4f79a9ec 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,26 +1,20 @@ -use std::borrow::Cow; -use std::convert::Infallible; -use std::net::SocketAddr; -use std::sync::Arc; -use std::time::{Duration, UNIX_EPOCH}; +use std::{borrow::Cow, convert::Infallible, net::SocketAddr, sync::Arc}; use futures::future::Future; -use futures::stream::*; use hyper::{ header::HOST, - body::Bytes, server::conn::AddrStream, service::{make_service_fn, service_fn}, - Body, Request, Response, Server, StatusCode}; + Body, Request, Response, Server, +}; use idna::domain_to_unicode; -use garage_model::garage::Garage; -use garage_model::object_table::*; -use garage_table::EmptyKey; -use garage_util::error::Error as GarageError; use crate::error::*; +use garage_api::s3_get::handle_get; +use garage_model::garage::Garage; +use garage_util::error::Error as GarageError; pub async fn run_web_server( garage: Arc, @@ -89,109 +83,9 @@ async fn serve_file(garage: Arc, req: Request) -> Result x, - _ => unreachable!(), - }; - - // Get metadata from version - let last_v_meta = match last_v_data { - ObjectVersionData::DeleteMarker => return Err(Error::NotFound), - ObjectVersionData::Inline(meta, _) => meta, - ObjectVersionData::FirstBlock(meta, _) => meta, - }; - - // @FIXME Support range - - - // Set headers - let resp_builder = object_headers(&last_v, last_v_meta).status(StatusCode::OK); - - - // Stream body - match &last_v_data { - ObjectVersionData::DeleteMarker => unreachable!(), - ObjectVersionData::Inline(_, bytes) => { - let body: Body = Body::from(bytes.to_vec()); - Ok(resp_builder.body(body)?) - } - ObjectVersionData::FirstBlock(_, first_block_hash) => { - let read_first_block = garage.block_manager.rpc_get_block(&first_block_hash); - let get_next_blocks = garage.version_table.get(&last_v.uuid, &EmptyKey); - - let (first_block, version) = futures::try_join!(read_first_block, get_next_blocks)?; - let version = version.ok_or(Error::NotFound)?; - - let mut blocks = version - .blocks() - .iter() - .map(|vb| (vb.hash, None)) - .collect::>(); - blocks[0].1 = Some(first_block); - - let body_stream = futures::stream::iter(blocks) - .map(move |(hash, data_opt)| { - let garage = garage.clone(); - async move { - if let Some(data) = data_opt { - Ok(Bytes::from(data)) - } else { - garage - .block_manager - .rpc_get_block(&hash) - .await - .map(Bytes::from) - } - } - }) - .buffered(2); - //let body: Body = Box::new(StreamBody::new(Box::pin(body_stream))); - let body = hyper::body::Body::wrap_stream(body_stream); - Ok(resp_builder.body(body)?) - } - } -} - -// Copied from api/s3_get.rs -fn object_headers( - version: &ObjectVersion, - version_meta: &ObjectVersionMeta, -) -> http::response::Builder { - let date = UNIX_EPOCH + Duration::from_millis(version.timestamp); - let date_str = httpdate::fmt_http_date(date); - - let mut resp = Response::builder() - .header( - "Content-Type", - version_meta.headers.content_type.to_string(), - ) - .header("Content-Length", format!("{}", version_meta.size)) - .header("ETag", version_meta.etag.to_string()) - .header("Last-Modified", date_str) - .header("Accept-Ranges", format!("bytes")); - - for (k, v) in version_meta.headers.other.iter() { - resp = resp.header(k, v.to_string()); - } - - resp + Ok(r) } /// Extract host from the authority section given by the HTTP host header @@ -253,11 +147,11 @@ fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str { /// which is also AWS S3 behavior. fn path_to_key<'a>(path: &'a str, index: &str) -> Result, Error> { let path_utf8 = percent_encoding::percent_decode_str(&path).decode_utf8()?; - + if path_utf8.chars().next() != Some('/') { return Err(Error::BadRequest(format!( "Path must start with a / (slash)" - ))) + ))); } match path_utf8.chars().last() { @@ -270,12 +164,10 @@ fn path_to_key<'a>(path: &'a str, index: &str) -> Result, Error> { key.push_str(index); Ok(key.into()) } - Some(_) => { - match path_utf8 { - Cow::Borrowed(pu8) => Ok((&pu8[1..]).into()), - Cow::Owned(pu8) => Ok((&pu8[1..]).to_string().into()), - } - } + Some(_) => match path_utf8 { + Cow::Borrowed(pu8) => Ok((&pu8[1..]).into()), + Cow::Owned(pu8) => Ok((&pu8[1..]).to_string().into()), + }, } } From b7a377308bbcbb7285a5b11cdcb07361eff93a28 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 17:58:14 +0100 Subject: [PATCH 28/49] Handle HEAD --- src/web/web_server.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 4f79a9ec..f8a5cd14 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -6,13 +6,13 @@ use hyper::{ header::HOST, server::conn::AddrStream, service::{make_service_fn, service_fn}, - Body, Request, Response, Server, + Body, Method, Request, Response, Server, }; use idna::domain_to_unicode; use crate::error::*; -use garage_api::s3_get::handle_get; +use garage_api::s3_get::{handle_get, handle_head}; use garage_model::garage::Garage; use garage_util::error::Error as GarageError; @@ -83,9 +83,13 @@ async fn serve_file(garage: Arc, req: Request) -> Result handle_head(garage, &bucket, &key).await?, + &Method::GET => handle_get(garage, &req, bucket, &key).await?, + _ => return Err(Error::BadRequest(format!("HTTP method not supported"))), + }; - Ok(r) + Ok(res) } /// Extract host from the authority section given by the HTTP host header From fb18f5e17a34830d094fc591ee1d8accde2a85ad Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 21 Nov 2020 18:14:02 +0100 Subject: [PATCH 29/49] Fix wrong http status code --- src/web/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/web/error.rs b/src/web/error.rs index 59810f0f..220bacfe 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -43,6 +43,7 @@ impl Error { pub fn http_status_code(&self) -> StatusCode { match self { Error::NotFound => StatusCode::NOT_FOUND, + Error::ApiError(e) => e.http_status_code(), Error::Forbidden(_) => StatusCode::FORBIDDEN, Error::InternalError(GarageError::RPC(_)) => StatusCode::SERVICE_UNAVAILABLE, Error::InternalError(_) | Error::Hyper(_) | Error::HTTP(_) => { From 54c3a023f0febb68824be51a9b35a2457373ad07 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 29 Nov 2020 17:27:49 +0100 Subject: [PATCH 30/49] Use aws cli version 2 --- README.md | 17 +++++++++-------- script/test-smoke.sh | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9325bcae..a33e2850 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,15 @@ Our main use case is to provide a distributed storage layer for small-scale self We propose the following quickstart to setup a full dev. environment as quickly as possible: - 1. Setup a rust/cargo environment and install `awscli`. eg. `dnf install rust cargo awscli` - 2. Run `cargo build` to build the project - 3. Run `./script/dev-cluster.sh` to launch a test cluster (feel free to read the script) - 4. Run `./script/dev-configure.sh` to configure your test cluster with default values (same datacenter, 100 tokens) - 5. Run `./script/dev-bucket.sh` to create a bucket named `eprouvette` and an API key that will be stored in `/tmp/garage.s3` - 6. Run `source ./script/dev-env.sh` to configure your CLI environment - 7. You can use `garage` to manage the cluster. Try `garage --help`. - 8. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg cp /proc/cpuinfo s3://eprouvette/cpuinfo.txt`, `s3grg ls s3://eprouvette`. `s3grg` is a wrapper on the `aws s3` subcommand configured with the previously generated API key (the one in `/tmp/garage.s3`). + 1. Setup a rust/cargo environment. eg. `dnf install rust cargo` + 2. Install awscli v2 by following the guide [here](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html). + 3. Run `cargo build` to build the project + 4. Run `./script/dev-cluster.sh` to launch a test cluster (feel free to read the script) + 5. Run `./script/dev-configure.sh` to configure your test cluster with default values (same datacenter, 100 tokens) + 6. Run `./script/dev-bucket.sh` to create a bucket named `eprouvette` and an API key that will be stored in `/tmp/garage.s3` + 7. Run `source ./script/dev-env.sh` to configure your CLI environment + 8. You can use `garage` to manage the cluster. Try `garage --help`. + 9. You can use `s3grg` to add, remove, and delete files. Try `s3grg --help`, `s3grg cp /proc/cpuinfo s3://eprouvette/cpuinfo.txt`, `s3grg ls s3://eprouvette`. `s3grg` is a wrapper on the `aws s3` subcommand configured with the previously generated API key (the one in `/tmp/garage.s3`). Now you should be ready to start hacking on garage! diff --git a/script/test-smoke.sh b/script/test-smoke.sh index 7b462b00..7faf2a07 100755 --- a/script/test-smoke.sh +++ b/script/test-smoke.sh @@ -15,8 +15,8 @@ source ${SCRIPT_FOLDER}/dev-env.sh dd if=/dev/urandom of=/tmp/garage.rnd bs=1M count=10 -s3grg put /tmp/garage.rnd s3://eprouvette/ +s3grg cp /tmp/garage.rnd s3://eprouvette/ s3grg ls s3://eprouvette -s3grg get s3://eprouvette/garage.rnd /tmp/garage.dl +s3grg cp s3://eprouvette/garage.rnd /tmp/garage.dl diff /tmp/garage.rnd /tmp/garage.dl From 8df0b322aba3360e7ff1fdca805f93e05cda963a Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 29 Nov 2020 17:40:36 +0100 Subject: [PATCH 31/49] Fix merge error --- script/dev-env.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/script/dev-env.sh b/script/dev-env.sh index 71fbd208..15f08e2e 100755 --- a/script/dev-env.sh +++ b/script/dev-env.sh @@ -6,7 +6,6 @@ GARAGE_DEBUG="${REPO_FOLDER}/target/debug/" GARAGE_RELEASE="${REPO_FOLDER}/target/release/" PATH="${GARAGE_DEBUG}:${GARAGE_RELEASE}:$PATH" -<<<<<<< HEAD export AWS_ACCESS_KEY_ID=`cat /tmp/garage.s3 |cut -d' ' -f1` export AWS_SECRET_ACCESS_KEY=`cat /tmp/garage.s3 |cut -d' ' -f2` export AWS_DEFAULT_REGION='garage' From 51d0c14e440f00f24dbed6c3bce915a183a2bb65 Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 10 Dec 2020 18:13:32 +0100 Subject: [PATCH 32/49] CLI structure --- src/garage/admin_rpc.rs | 3 +++ src/garage/main.rs | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index a23d3e95..65bd24c0 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -155,6 +155,9 @@ impl AdminRpcHandler { &query.key_id, &query.bucket, allow_read, allow_write ))) } + BucketOperation::Website(query) => { + Ok(AdminRPC::Ok(format!("test"))) + } } } diff --git a/src/garage/main.rs b/src/garage/main.rs index 1185871f..7996d1f9 100644 --- a/src/garage/main.rs +++ b/src/garage/main.rs @@ -141,6 +141,21 @@ pub enum BucketOperation { /// Allow key to read or write to bucket #[structopt(name = "deny")] Deny(PermBucketOpt), + + /// Expose as website or not + #[structopt(name = "website")] + Website(WebsiteOpt), +} + +#[derive(Serialize, Deserialize, StructOpt, Debug)] +pub struct WebsiteOpt { + /// Create + #[structopt(long = "create")] + pub create: bool, + + /// Delete + #[structopt(long = "delete")] + pub delete: bool, } #[derive(Serialize, Deserialize, StructOpt, Debug)] From 1119d466e762b6fe11eb939811c4f24b27a0404f Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 10 Dec 2020 20:19:22 +0100 Subject: [PATCH 33/49] Fix S3 command --- script/dev-env-s3cmd.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/script/dev-env-s3cmd.sh b/script/dev-env-s3cmd.sh index 15f08e2e..88d2941f 100644 --- a/script/dev-env-s3cmd.sh +++ b/script/dev-env-s3cmd.sh @@ -6,9 +6,14 @@ GARAGE_DEBUG="${REPO_FOLDER}/target/debug/" GARAGE_RELEASE="${REPO_FOLDER}/target/release/" PATH="${GARAGE_DEBUG}:${GARAGE_RELEASE}:$PATH" -export AWS_ACCESS_KEY_ID=`cat /tmp/garage.s3 |cut -d' ' -f1` -export AWS_SECRET_ACCESS_KEY=`cat /tmp/garage.s3 |cut -d' ' -f2` -export AWS_DEFAULT_REGION='garage' +ACCESS_KEY=`cat /tmp/garage.s3 |cut -d' ' -f1` +SECRET_KEY=`cat /tmp/garage.s3 |cut -d' ' -f2` + +alias s3grg="s3cmd \ + --host 127.0.0.1:3911 \ + --host-bucket 127.0.0.1:3911 \ + --access_key=$ACCESS_KEY \ + --secret_key=$SECRET_KEY \ + --region=garage \ + --no-ssl" -alias s3grg="aws s3 \ - --endpoint-url http://127.0.0.1:3911" From e1ce2b228aaacd5984bf4e1b73a0a6c1276f78e5 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 12 Dec 2020 17:00:31 +0100 Subject: [PATCH 34/49] WIP table migration --- src/garage/admin_rpc.rs | 33 ++++++++++++++++++++++++++++++++- src/garage/main.rs | 8 ++++---- src/model/bucket_table.rs | 28 ++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 65bd24c0..f9d398c2 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -156,7 +156,36 @@ impl AdminRpcHandler { ))) } BucketOperation::Website(query) => { - Ok(AdminRPC::Ok(format!("test"))) + let bucket = self.get_existing_bucket(&query.bucket).await?; + if query.allow && query.deny { + return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket"))); + } + + if query.allow || query.deny { + let exposed = query.allow; + if let BucketState::Present(ak) = bucket.state.get_mut() { + let old_ak = ak.take_and_clear(); + ak.merge(&old_ak.update_mutator( + key_id.to_string(), + PermissionSet { + allow_read, + allow_write, + }, + )); + } else { + return Err(Error::Message(format!( + "Bucket is deleted in update_bucket_key" + ))); + } + } + + let msg = if bucket.exposed { + "Bucket is exposed as a website." + } else { + "Bucket is not exposed." + }; + + Ok(AdminRPC::Ok(msg)) } } } @@ -240,6 +269,7 @@ impl AdminRpcHandler { .unwrap_or(Err(Error::BadRPC(format!("Key {} does not exist", id)))) } + /// Update **bucket table** to inform of the new linked key async fn update_bucket_key( &self, mut bucket: Bucket, @@ -265,6 +295,7 @@ impl AdminRpcHandler { Ok(()) } + /// Update **key table** to inform of the new linked bucket async fn update_key_bucket( &self, mut key: Key, diff --git a/src/garage/main.rs b/src/garage/main.rs index 7996d1f9..d97ca3b8 100644 --- a/src/garage/main.rs +++ b/src/garage/main.rs @@ -150,12 +150,12 @@ pub enum BucketOperation { #[derive(Serialize, Deserialize, StructOpt, Debug)] pub struct WebsiteOpt { /// Create - #[structopt(long = "create")] - pub create: bool, + #[structopt(long = "allow")] + pub allow: bool, /// Delete - #[structopt(long = "delete")] - pub delete: bool, + #[structopt(long = "deny")] + pub deny: bool, } #[derive(Serialize, Deserialize, StructOpt, Debug)] diff --git a/src/model/bucket_table.rs b/src/model/bucket_table.rs index b7f24d71..b6b0fceb 100644 --- a/src/model/bucket_table.rs +++ b/src/model/bucket_table.rs @@ -21,27 +21,43 @@ pub struct Bucket { #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] pub enum BucketState { Deleted, - Present(crdt::LWWMap), + Present(BucketParams), } impl CRDT for BucketState { fn merge(&mut self, o: &Self) { match o { BucketState::Deleted => *self = BucketState::Deleted, - BucketState::Present(other_ak) => { - if let BucketState::Present(ak) = self { - ak.merge(other_ak); + BucketState::Present(other_params) => { + if let BucketState::Present(params) = self { + params.merge(other_params); } } } } } +#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] +pub struct BucketParams { + pub authorized_keys: crdt::LWWMap, + pub website: crdt::LWW +} + +impl CRDT for BucketParams { + fn merge(&mut self, o: &Self) { + self.authorized_keys.merge(&o.authorized_keys); + self.website.merge(&o.website); + } +} + impl Bucket { pub fn new(name: String) -> Self { Bucket { name, - state: crdt::LWW::new(BucketState::Present(crdt::LWWMap::new())), + state: crdt::LWW::new(BucketState::Present(BucketParams { + authorized_keys: crdt::LWWMap::new(), + website: crdt::LWW::new(false) + })), } } pub fn is_deleted(&self) -> bool { @@ -50,7 +66,7 @@ impl Bucket { pub fn authorized_keys(&self) -> &[(String, u64, PermissionSet)] { match self.state.get() { BucketState::Deleted => &[], - BucketState::Present(ak) => ak.items(), + BucketState::Present(state) => state.authorized_keys.items(), } } } From 96388acf230d48877a037b21931f61e2c63d2574 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 12 Dec 2020 21:35:29 +0100 Subject: [PATCH 35/49] Implement migration --- src/garage/admin_rpc.rs | 9 +++++---- src/model/bucket_table.rs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index f9d398c2..6ebd04a9 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -156,14 +156,15 @@ impl AdminRpcHandler { ))) } BucketOperation::Website(query) => { - let bucket = self.get_existing_bucket(&query.bucket).await?; + /*let bucket = self.get_existing_bucket(&query.bucket).await?; if query.allow && query.deny { return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket"))); } if query.allow || query.deny { let exposed = query.allow; - if let BucketState::Present(ak) = bucket.state.get_mut() { + if let BucketState::Present(state) = bucket.state.get_mut() { + let ak = state.authorized_keys; let old_ak = ak.take_and_clear(); ak.merge(&old_ak.update_mutator( key_id.to_string(), @@ -183,9 +184,9 @@ impl AdminRpcHandler { "Bucket is exposed as a website." } else { "Bucket is not exposed." - }; + };*/ - Ok(AdminRPC::Ok(msg)) + Ok(AdminRPC::Ok(/*msg*/"".to_string())) } } } diff --git a/src/model/bucket_table.rs b/src/model/bucket_table.rs index b6b0fceb..08d0d168 100644 --- a/src/model/bucket_table.rs +++ b/src/model/bucket_table.rs @@ -10,6 +10,11 @@ use crate::key_table::PermissionSet; use model010::bucket_table as prev; +/// A bucket is a collection of objects +/// +/// Its parameters are not directly accessible as: +/// - It must be possible to merge paramaters, hence the use of a LWW CRDT. +/// - A bucket has 2 states, Present or Deleted and parameters make sense only if present. #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] pub struct Bucket { // Primary key @@ -123,9 +128,15 @@ impl TableSchema for BucketTable { }, )); } + + let params = BucketParams { + authorized_keys: keys, + website: crdt::LWW::new(false) + }; + Some(Bucket { name: old.name, - state: crdt::LWW::migrate_from_raw(old.timestamp, BucketState::Present(keys)), + state: crdt::LWW::migrate_from_raw(old.timestamp, BucketState::Present(params)), }) } } From d0eb6a457f6f83c8f49d262adf6150964a1249b2 Mon Sep 17 00:00:00 2001 From: Quentin Date: Mon, 14 Dec 2020 21:46:49 +0100 Subject: [PATCH 36/49] Migrate RPC to new schema --- src/garage/admin_rpc.rs | 6 ++++-- src/model/bucket_table.rs | 14 ++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 6ebd04a9..8bf1dec2 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -89,7 +89,7 @@ impl AdminRpcHandler { } bucket .state - .update(BucketState::Present(crdt::LWWMap::new())); + .update(BucketState::Present(BucketParams::new())); bucket } None => Bucket::new(query.name.clone()), @@ -157,6 +157,7 @@ impl AdminRpcHandler { } BucketOperation::Website(query) => { /*let bucket = self.get_existing_bucket(&query.bucket).await?; + if query.allow && query.deny { return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket"))); } @@ -278,7 +279,8 @@ impl AdminRpcHandler { allow_read: bool, allow_write: bool, ) -> Result<(), Error> { - if let BucketState::Present(ak) = bucket.state.get_mut() { + if let BucketState::Present(params) = bucket.state.get_mut() { + let ak = &mut params.authorized_keys; let old_ak = ak.take_and_clear(); ak.merge(&old_ak.update_mutator( key_id.to_string(), diff --git a/src/model/bucket_table.rs b/src/model/bucket_table.rs index 08d0d168..609490cb 100644 --- a/src/model/bucket_table.rs +++ b/src/model/bucket_table.rs @@ -55,14 +55,20 @@ impl CRDT for BucketParams { } } +impl BucketParams { + pub fn new() -> Self { + BucketParams { + authorized_keys: crdt::LWWMap::new(), + website: crdt::LWW::new(false) + } + } +} + impl Bucket { pub fn new(name: String) -> Self { Bucket { name, - state: crdt::LWW::new(BucketState::Present(BucketParams { - authorized_keys: crdt::LWWMap::new(), - website: crdt::LWW::new(false) - })), + state: crdt::LWW::new(BucketState::Present(BucketParams::new())), } } pub fn is_deleted(&self) -> bool { From a3566e49da406db9499a58a754af725a54d332af Mon Sep 17 00:00:00 2001 From: Quentin Date: Mon, 14 Dec 2020 21:50:40 +0100 Subject: [PATCH 37/49] Start to implement Website CLI --- src/garage/admin_rpc.rs | 5 ++--- src/garage/main.rs | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 8bf1dec2..1e363677 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -156,12 +156,11 @@ impl AdminRpcHandler { ))) } BucketOperation::Website(query) => { - /*let bucket = self.get_existing_bucket(&query.bucket).await?; - + let bucket = self.get_existing_bucket(&query.bucket).await?; if query.allow && query.deny { return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket"))); } - + /* if query.allow || query.deny { let exposed = query.allow; if let BucketState::Present(state) = bucket.state.get_mut() { diff --git a/src/garage/main.rs b/src/garage/main.rs index d97ca3b8..7c8899a0 100644 --- a/src/garage/main.rs +++ b/src/garage/main.rs @@ -156,6 +156,9 @@ pub struct WebsiteOpt { /// Delete #[structopt(long = "deny")] pub deny: bool, + + /// Bucket name + pub bucket: String, } #[derive(Serialize, Deserialize, StructOpt, Debug)] From 3bc4d57a0f4a600c788a3c7ff51d633d1b7e6f09 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 15 Dec 2020 12:48:24 +0100 Subject: [PATCH 38/49] First implementation of the CLI --- src/garage/admin_rpc.rs | 47 ++++++++++++++++----------------------- src/model/bucket_table.rs | 8 +++---- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 1e363677..602e0b09 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -156,37 +156,28 @@ impl AdminRpcHandler { ))) } BucketOperation::Website(query) => { - let bucket = self.get_existing_bucket(&query.bucket).await?; - if query.allow && query.deny { - return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket"))); + let mut bucket = self.get_existing_bucket(&query.bucket).await?; + + if !(query.allow ^ query.deny) { + return Err(Error::Message(format!( + "You must specify exactly one flag, either --allow or --deny" + ))); } - /* - if query.allow || query.deny { - let exposed = query.allow; - if let BucketState::Present(state) = bucket.state.get_mut() { - let ak = state.authorized_keys; - let old_ak = ak.take_and_clear(); - ak.merge(&old_ak.update_mutator( - key_id.to_string(), - PermissionSet { - allow_read, - allow_write, - }, - )); + + if let BucketState::Present(state) = bucket.state.get_mut() { + state.website.update(query.allow); + let msg = if query.allow { + format!("Website access allowed for {}", &query.bucket) } else { - return Err(Error::Message(format!( - "Bucket is deleted in update_bucket_key" - ))); - } - } + format!("Website access denied for {}", &query.bucket) + }; - let msg = if bucket.exposed { - "Bucket is exposed as a website." + Ok(AdminRPC::Ok(msg.to_string())) } else { - "Bucket is not exposed." - };*/ - - Ok(AdminRPC::Ok(/*msg*/"".to_string())) + return Err(Error::Message(format!( + "Bucket is deleted in update_bucket_key" + ))); + } } } } @@ -270,7 +261,7 @@ impl AdminRpcHandler { .unwrap_or(Err(Error::BadRPC(format!("Key {} does not exist", id)))) } - /// Update **bucket table** to inform of the new linked key + /// Update **bucket table** to inform of the new linked key async fn update_bucket_key( &self, mut bucket: Bucket, diff --git a/src/model/bucket_table.rs b/src/model/bucket_table.rs index 609490cb..78b0416f 100644 --- a/src/model/bucket_table.rs +++ b/src/model/bucket_table.rs @@ -45,7 +45,7 @@ impl CRDT for BucketState { #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] pub struct BucketParams { pub authorized_keys: crdt::LWWMap, - pub website: crdt::LWW + pub website: crdt::LWW, } impl CRDT for BucketParams { @@ -59,7 +59,7 @@ impl BucketParams { pub fn new() -> Self { BucketParams { authorized_keys: crdt::LWWMap::new(), - website: crdt::LWW::new(false) + website: crdt::LWW::new(false), } } } @@ -134,10 +134,10 @@ impl TableSchema for BucketTable { }, )); } - + let params = BucketParams { authorized_keys: keys, - website: crdt::LWW::new(false) + website: crdt::LWW::new(false), }; Some(Bucket { From 011ff87b5fd7cd1eea8713c7e21fcd827b69c149 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 15 Dec 2020 13:23:22 +0100 Subject: [PATCH 39/49] Push update --- src/garage/admin_rpc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 602e0b09..39dc0ed8 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -166,6 +166,7 @@ impl AdminRpcHandler { if let BucketState::Present(state) = bucket.state.get_mut() { state.website.update(query.allow); + self.garage.bucket_table.insert(&bucket).await?; let msg = if query.allow { format!("Website access allowed for {}", &query.bucket) } else { From 3132deca5808905ce3956b40a6175b7714e11819 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 17 Dec 2020 20:43:14 +0100 Subject: [PATCH 40/49] Web server access control --- src/web/web_server.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index f8a5cd14..9effa86c 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -13,6 +13,8 @@ use idna::domain_to_unicode; use crate::error::*; use garage_api::s3_get::{handle_get, handle_head}; +use garage_table::*; +use garage_model::bucket_table::*; use garage_model::garage::Garage; use garage_util::error::Error as GarageError; @@ -76,6 +78,20 @@ async fn serve_file(garage: Arc, req: Request) -> Result Err(Error::NotFound), + BucketState::Present(params) if !params.website.get() => Err(Error::NotFound), + _ => Ok(()), + }?; + // Get path let path = req.uri().path().to_string(); let index = &garage.config.s3_web.index; From 086e5be290b329b898206397ad95c82964fbf499 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 17 Dec 2020 21:04:59 +0100 Subject: [PATCH 41/49] Update testing script --- script/test-smoke.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/script/test-smoke.sh b/script/test-smoke.sh index 111afac9..a2ffcea1 100755 --- a/script/test-smoke.sh +++ b/script/test-smoke.sh @@ -6,6 +6,7 @@ shopt -s expand_aliases SCRIPT_FOLDER="`dirname \"$0\"`" REPO_FOLDER="${SCRIPT_FOLDER}/../" +echo "setup" cargo build ${SCRIPT_FOLDER}/dev-clean.sh ${SCRIPT_FOLDER}/dev-cluster.sh > /tmp/garage.log 2>&1 & @@ -22,6 +23,7 @@ dd if=/dev/urandom of=/tmp/garage.1.rnd bs=1k count=2 # < INLINE_THRESHOLD = 307 dd if=/dev/urandom of=/tmp/garage.2.rnd bs=1M count=5 dd if=/dev/urandom of=/tmp/garage.3.rnd bs=1M count=10 +echo "s3 api testing..." for idx in $(seq 1 3); do # AWS sends awsgrg cp /tmp/garage.$idx.rnd s3://eprouvette/garage.$idx.aws @@ -55,6 +57,18 @@ for idx in $(seq 1 3); do done rm /tmp/garage.{1,2,3}.rnd +echo "website testing" +echo "

hello world

" > /tmp/garage-index.html +awsgrg cp /tmp/garage-index.html s3://eprouvette/index.html +[ `curl -s -o /dev/null -w "%{http_code}" --header "Host: eprouvette.garage.tld" http://127.0.0.1:3923/ ` == 404 ] +garage bucket website --allow eprouvette +[ `curl -s -o /dev/null -w "%{http_code}" --header "Host: eprouvette.garage.tld" http://127.0.0.1:3923/ ` == 200 ] +garage bucket website --deny eprouvette +[ `curl -s -o /dev/null -w "%{http_code}" --header "Host: eprouvette.garage.tld" http://127.0.0.1:3923/ ` == 404 ] +awsgrg rm s3://eprouvette/index.html +rm /tmp/garage-index.html + +echo "teardown" garage bucket deny --read --write eprouvette --key $AWS_ACCESS_KEY_ID garage bucket delete --yes eprouvette garage key delete --yes $AWS_ACCESS_KEY_ID From 2f4378a9c42cc3a78b992905e980e8977e6c5e58 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 17 Dec 2020 22:51:44 +0100 Subject: [PATCH 42/49] Fix formatting --- src/web/web_server.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 9effa86c..25a7cd5f 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -13,9 +13,9 @@ use idna::domain_to_unicode; use crate::error::*; use garage_api::s3_get::{handle_get, handle_head}; -use garage_table::*; use garage_model::bucket_table::*; use garage_model::garage::Garage; +use garage_table::*; use garage_util::error::Error as GarageError; pub async fn run_web_server( @@ -78,19 +78,19 @@ async fn serve_file(garage: Arc, req: Request) -> Result Err(Error::NotFound), - BucketState::Present(params) if !params.website.get() => Err(Error::NotFound), - _ => Ok(()), - }?; + // Check bucket is exposed as a website + let bucket_desc = garage + .bucket_table + .get(&EmptyKey, &bucket.to_string()) + .await? + .filter(|b| !b.is_deleted()) + .ok_or(Error::NotFound)?; + + match bucket_desc.state.get() { + BucketState::Deleted => Err(Error::NotFound), + BucketState::Present(params) if !params.website.get() => Err(Error::NotFound), + _ => Ok(()), + }?; // Get path let path = req.uri().path().to_string(); From f496e41ef4298a579810046bcff794a24cdb7e07 Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 15:44:44 +0100 Subject: [PATCH 43/49] Replace an already done check by unreachable!() --- src/garage/admin_rpc.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs index 39dc0ed8..e1981e3a 100644 --- a/src/garage/admin_rpc.rs +++ b/src/garage/admin_rpc.rs @@ -175,9 +175,7 @@ impl AdminRpcHandler { Ok(AdminRPC::Ok(msg.to_string())) } else { - return Err(Error::Message(format!( - "Bucket is deleted in update_bucket_key" - ))); + unreachable!(); } } } From c441a358cdc8447d7ff7c6ff8b066ae2d0d99409 Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 16:16:32 +0100 Subject: [PATCH 44/49] Remove unused dependencies --- Cargo.lock | 13 ------------- src/web/Cargo.toml | 19 ------------------- 2 files changed, 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39a876f1..3ed35ef5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -673,29 +673,16 @@ version = "0.1.0" dependencies = [ "err-derive", "futures", - "futures-util", "garage_api", "garage_model 0.1.1", "garage_table 0.1.1", "garage_util 0.1.0", - "hex", "http", - "httpdate", "hyper", "idna", "log", "percent-encoding", - "rand", - "rmp-serde", "roxmltree", - "rustls", - "serde", - "serde_json", - "sha2", - "sled", - "tokio", - "toml", - "webpki", ] [[package]] diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 0d08fdbf..751b9ace 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -18,30 +18,11 @@ garage_table = { version = "0.1.1", path = "../table" } garage_model = { version = "0.1.1", path = "../model" } garage_api = { version = "0.1.1", path = "../api" } -rand = "0.7" -hex = "0.3" -sha2 = "0.8" err-derive = "0.2.3" log = "0.4" - -sled = "0.31" - -toml = "0.5" -rmp-serde = "0.14.3" -serde = { version = "1.0", default-features = false, features = ["derive", "rc"] } -serde_json = "1.0" - futures = "0.3" -futures-util = "0.3" -tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] } - http = "0.2" hyper = "0.13" percent-encoding = "2.1.0" -rustls = "0.17" -webpki = "0.21" - roxmltree = "0.11" idna = "0.2" - -httpdate = "0.3" From 11a79a95dd9b2f2e0dd2d9dc999abd24f4ee232b Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 16:24:27 +0100 Subject: [PATCH 45/49] Simplify Error file --- src/web/error.rs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/web/error.rs b/src/web/error.rs index 220bacfe..14bc3b75 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -12,16 +12,6 @@ pub enum Error { #[error(display = "Internal error: {}", _0)] InternalError(#[error(source)] GarageError), - #[error(display = "Internal error (Hyper error): {}", _0)] - Hyper(#[error(source)] hyper::Error), - - #[error(display = "Internal error (HTTP error): {}", _0)] - HTTP(#[error(source)] http::Error), - - // Category: cannot process - #[error(display = "Forbidden: {}", _0)] - Forbidden(String), - #[error(display = "Not found")] NotFound, @@ -29,9 +19,6 @@ pub enum Error { #[error(display = "Invalid UTF-8: {}", _0)] InvalidUTF8(#[error(source)] std::str::Utf8Error), - #[error(display = "Invalid XML: {}", _0)] - InvalidXML(#[error(source)] roxmltree::Error), - #[error(display = "Invalid header value: {}", _0)] InvalidHeader(#[error(source)] hyper::header::ToStrError), @@ -44,11 +31,8 @@ impl Error { match self { Error::NotFound => StatusCode::NOT_FOUND, Error::ApiError(e) => e.http_status_code(), - Error::Forbidden(_) => StatusCode::FORBIDDEN, Error::InternalError(GarageError::RPC(_)) => StatusCode::SERVICE_UNAVAILABLE, - Error::InternalError(_) | Error::Hyper(_) | Error::HTTP(_) => { - StatusCode::INTERNAL_SERVER_ERROR - } + Error::InternalError(_) => StatusCode::INTERNAL_SERVER_ERROR, _ => StatusCode::BAD_REQUEST, } } From 1e10c6a61cf59c11d72e941c5a6d4ea6e159b8ce Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 17:03:38 +0100 Subject: [PATCH 46/49] Doc tests that do not compile/work must be tagged with ignore --- src/table/crdt.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/table/crdt.rs b/src/table/crdt.rs index 386e478b..4cba10ce 100644 --- a/src/table/crdt.rs +++ b/src/table/crdt.rs @@ -239,7 +239,7 @@ where /// /// Typically, to update the value associated to a key in the map, you would do the following: /// - /// ``` + /// ```ignore /// let my_update = my_crdt.update_mutator(key_to_modify, new_value); /// my_crdt.merge(&my_update); /// ``` @@ -261,7 +261,7 @@ where /// empty map. This is very usefull to produce in-place a new map that contains only a delta /// that modifies a certain value: /// - /// ``` + /// ```ignore /// let mut a = get_my_crdt_value(); /// let old_a = a.take_and_clear(); /// a.merge(&old_a.update_mutator(key_to_modify, new_value)); @@ -273,7 +273,7 @@ where /// but in the case where the map is a field in a struct for instance (as is always the case), /// this becomes very handy: /// - /// ``` + /// ```ignore /// let mut a = get_my_crdt_value(); /// let old_a_map = a.map_field.take_and_clear(); /// a.map_field.merge(&old_a_map.update_mutator(key_to_modify, new_value)); From fad7bc405bd8b3cf1dc9a9319a7e3ee0e1eb3461 Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 17:03:54 +0100 Subject: [PATCH 47/49] Behavior problem: do not panic anymore + add tests --- src/web/web_server.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 25a7cd5f..246c045f 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -87,9 +87,8 @@ async fn serve_file(garage: Arc, req: Request) -> Result Err(Error::NotFound), - BucketState::Present(params) if !params.website.get() => Err(Error::NotFound), - _ => Ok(()), + BucketState::Present(params) if *params.website.get() => Ok(()), + _ => Err(Error::NotFound), }?; // Get path @@ -123,8 +122,10 @@ fn authority_to_host(authority: &str) -> Result<&str, Error> { let split = match first_char { '[' => { let mut iter = iter.skip_while(|(_, c)| c != &']'); - iter.next().expect("Authority parsing logic error"); - iter.next() + match iter.next() { + Some((_, ']')) => iter.next(), + _ => None, + } } _ => iter.skip_while(|(_, c)| c != &':').next(), }; @@ -214,6 +215,10 @@ mod tests { assert_eq!(domain2, "garage.tld"); let domain3 = authority_to_host("127.0.0.1")?; assert_eq!(domain3, "127.0.0.1"); + let domain4 = authority_to_host("[")?; + assert_eq!(domain4, "["); + let domain5 = authority_to_host("[hello")?; + assert_eq!(domain5, "[hello"); Ok(()) } From f8a40e8c4f69c20045aaffc4caf51158d697e792 Mon Sep 17 00:00:00 2001 From: Quentin Date: Fri, 15 Jan 2021 17:11:15 +0100 Subject: [PATCH 48/49] Explicitly set code path unreachable --- src/web/web_server.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 246c045f..aab7e8de 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -176,9 +176,7 @@ fn path_to_key<'a>(path: &'a str, index: &str) -> Result, Error> { } match path_utf8.chars().last() { - None => Err(Error::BadRequest(format!( - "Path must have at least a character" - ))), + None => unreachable!(), Some('/') => { let mut key = String::with_capacity(path_utf8.len() + index.len()); key.push_str(&path_utf8[1..]); From 851893a3f299da9eeb0ef3c745be1f30164fd6cf Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 15 Jan 2021 17:49:10 +0100 Subject: [PATCH 49/49] Do not accept domains such as [hello --- src/web/web_server.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/web/web_server.rs b/src/web/web_server.rs index aab7e8de..24d111a9 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -124,7 +124,12 @@ fn authority_to_host(authority: &str) -> Result<&str, Error> { let mut iter = iter.skip_while(|(_, c)| c != &']'); match iter.next() { Some((_, ']')) => iter.next(), - _ => None, + _ => { + return Err(Error::BadRequest(format!( + "Authority {} has an illegal format", + authority + ))) + } } } _ => iter.skip_while(|(_, c)| c != &':').next(), @@ -213,10 +218,8 @@ mod tests { assert_eq!(domain2, "garage.tld"); let domain3 = authority_to_host("127.0.0.1")?; assert_eq!(domain3, "127.0.0.1"); - let domain4 = authority_to_host("[")?; - assert_eq!(domain4, "["); - let domain5 = authority_to_host("[hello")?; - assert_eq!(domain5, "[hello"); + assert!(authority_to_host("[").is_err()); + assert!(authority_to_host("[hello").is_err()); Ok(()) }