diff options
-rw-r--r-- | Cargo.lock | 452 | ||||
-rw-r--r-- | Cargo.toml | 11 | ||||
-rw-r--r-- | src/frontend/mod.rs | 8 | ||||
-rw-r--r-- | src/indieauth.rs | 75 | ||||
-rw-r--r-- | src/main.rs | 28 | ||||
-rw-r--r-- | src/micropub/mod.rs | 105 |
6 files changed, 486 insertions, 193 deletions
diff --git a/Cargo.lock b/Cargo.lock index 5d955ec..7b4a593 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -282,9 +282,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -310,9 +310,9 @@ version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -334,6 +334,15 @@ dependencies = [ [[package]] name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" @@ -554,6 +563,15 @@ dependencies = [ ] [[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] name = "colored" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -732,11 +750,11 @@ dependencies = [ "dtoa-short", "itoa 0.4.8", "matches", - "phf", - "proc-macro2", - "quote", + "phf 0.8.0", + "proc-macro2 1.0.37", + "quote 1.0.18", "smallvec", - "syn", + "syn 1.0.92", ] [[package]] @@ -745,8 +763,8 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" dependencies = [ - "quote", - "syn", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -755,8 +773,8 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ - "quote", - "syn", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -812,10 +830,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2", - "quote", + "proc-macro2 1.0.37", + "quote 1.0.18", "rustc_version 0.4.0", - "syn", + "syn 1.0.92", ] [[package]] @@ -903,7 +921,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a857bc01b5ae04874234f6b5d16b8b8fa86910aa5777479c2669b5df607fce" dependencies = [ - "html5ever", + "html5ever 0.25.2", "kuchiki", "regex 1.5.5", ] @@ -1109,9 +1127,9 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -1307,16 +1325,30 @@ dependencies = [ [[package]] name = "html5ever" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c213fa6a618dc1da552f54f85cba74b05d8e883c92ec4e89067736938084c26e" +dependencies = [ + "log 0.4.17", + "mac", + "markup5ever 0.7.5", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "html5ever" version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" dependencies = [ "log 0.4.17", "mac", - "markup5ever", - "proc-macro2", - "quote", - "syn", + "markup5ever 0.10.1", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -1448,11 +1480,9 @@ checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" dependencies = [ "http", "hyper", - "log 0.4.17", "rustls", "tokio", "tokio-rustls", - "webpki-roots", ] [[package]] @@ -1484,7 +1514,7 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ - "autocfg", + "autocfg 1.1.0", "hashbrown", ] @@ -1595,7 +1625,6 @@ dependencies = [ "http-types", "httpmock", "hyper", - "hyper-rustls", "kittybox-templates", "kittybox-util", "lazy_static", @@ -1604,6 +1633,7 @@ dependencies = [ "markdown", "markup", "mediatype", + "microformats", "mockito", "newbase60", "prometheus", @@ -1653,7 +1683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" dependencies = [ "cssparser", - "html5ever", + "html5ever 0.25.2", "matches", "selectors", ] @@ -1684,10 +1714,10 @@ dependencies = [ "pico-args", "regex 1.5.5", "regex-syntax 0.6.25", - "string_cache", + "string_cache 0.8.4", "term", "tiny-keccak", - "unicode-xid", + "unicode-xid 0.2.3", ] [[package]] @@ -1756,7 +1786,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ - "autocfg", + "autocfg 1.1.0", "scopeguard", ] @@ -1812,9 +1842,25 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5948a1826d7a5ba7c550ff109894bca69b6db05ea72215f2e7d1a929b755f932" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", +] + +[[package]] +name = "markup5ever" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897636f9850c3eef4905a5540683ed53dc9393860f0846cab2c2ddf9939862ff" +dependencies = [ + "phf 0.7.24", + "phf_codegen 0.7.24", + "serde", + "serde_derive", + "serde_json", + "string_cache 0.7.5", + "string_cache_codegen 0.4.4", + "tendril", ] [[package]] @@ -1824,10 +1870,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" dependencies = [ "log 0.4.17", - "phf", - "phf_codegen", - "string_cache", - "string_cache_codegen", + "phf 0.8.0", + "phf_codegen 0.8.0", + "string_cache 0.8.4", + "string_cache_codegen 0.5.2", "tendril", ] @@ -1874,6 +1920,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] +name = "microformats" +version = "0.2.0" +source = "git+https://gitlab.com/maxburon/microformats-parser#bba3f07d86243aec21b378f80db1a8c29d70235d" +dependencies = [ + "chrono", + "html5ever 0.22.5", + "lazy_static", + "log 0.4.17", + "regex 1.5.5", + "serde", + "serde_json", + "thiserror", + "url", +] + +[[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2006,7 +2068,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-traits", ] @@ -2016,7 +2078,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -2053,7 +2115,7 @@ version = "0.9.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" dependencies = [ - "autocfg", + "autocfg 1.1.0", "cc", "libc", "pkg-config", @@ -2132,6 +2194,15 @@ dependencies = [ [[package]] name = "phf" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +dependencies = [ + "phf_shared 0.7.24", +] + +[[package]] +name = "phf" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" @@ -2143,6 +2214,16 @@ dependencies = [ [[package]] name = "phf_codegen" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +dependencies = [ + "phf_generator 0.7.24", + "phf_shared 0.7.24", +] + +[[package]] +name = "phf_codegen" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" @@ -2153,6 +2234,16 @@ dependencies = [ [[package]] name = "phf_generator" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +dependencies = [ + "phf_shared 0.7.24", + "rand 0.6.5", +] + +[[package]] +name = "phf_generator" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" @@ -2180,9 +2271,18 @@ dependencies = [ "phf_generator 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +dependencies = [ + "siphasher 0.2.3", ] [[package]] @@ -2191,7 +2291,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ - "siphasher", + "siphasher 0.3.10", ] [[package]] @@ -2200,7 +2300,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "siphasher", + "siphasher 0.3.10", ] [[package]] @@ -2224,9 +2324,9 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -2297,11 +2397,20 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.3", ] [[package]] @@ -2353,9 +2462,9 @@ checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" dependencies = [ "anyhow", "itertools", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -2382,11 +2491,20 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.37", ] [[package]] @@ -2404,6 +2522,25 @@ dependencies = [ [[package]] name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg 0.1.2", + "rand_xorshift", + "winapi 0.3.9", +] + +[[package]] +name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" @@ -2412,8 +2549,8 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc", - "rand_pcg", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", ] [[package]] @@ -2429,6 +2566,16 @@ dependencies = [ [[package]] name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" @@ -2482,6 +2629,15 @@ dependencies = [ [[package]] name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" @@ -2490,6 +2646,50 @@ dependencies = [ ] [[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi 0.3.9", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi 0.3.9", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] name = "rand_pcg" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2499,6 +2699,15 @@ dependencies = [ ] [[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2775,8 +2984,8 @@ dependencies = [ "fxhash", "log 0.4.17", "matches", - "phf", - "phf_codegen", + "phf 0.8.0", + "phf_codegen 0.8.0", "precomputed-hash", "servo_arc", "smallvec", @@ -2819,9 +3028,9 @@ version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -2975,6 +3184,12 @@ checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" [[package]] name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" + +[[package]] +name = "siphasher" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" @@ -3053,11 +3268,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.37", + "quote 1.0.18", "serde", "serde_derive", - "syn", + "syn 1.0.92", ] [[package]] @@ -3067,13 +3282,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2", - "quote", + "proc-macro2 1.0.37", + "quote 1.0.18", "serde", "serde_derive", "serde_json", "sha1", - "syn", + "syn 1.0.92", ] [[package]] @@ -3084,6 +3299,21 @@ checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" [[package]] name = "string_cache" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "phf_shared 0.7.24", + "precomputed-hash", + "serde", + "string_cache_codegen 0.4.4", + "string_cache_shared", +] + +[[package]] +name = "string_cache" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" @@ -3098,17 +3328,36 @@ dependencies = [ [[package]] name = "string_cache_codegen" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6" +dependencies = [ + "phf_generator 0.7.24", + "phf_shared 0.7.24", + "proc-macro2 1.0.37", + "quote 1.0.18", + "string_cache_shared", +] + +[[package]] +name = "string_cache_codegen" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ "phf_generator 0.10.0", "phf_shared 0.10.0", - "proc-macro2", - "quote", + "proc-macro2 1.0.37", + "quote 1.0.18", ] [[package]] +name = "string_cache_shared" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" + +[[package]] name = "subtle" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3116,13 +3365,24 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2 1.0.37", + "quote 1.0.18", + "unicode-xid 0.2.3", ] [[package]] @@ -3216,9 +3476,9 @@ version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -3292,10 +3552,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" dependencies = [ "proc-macro-hack", - "proc-macro2", - "quote", + "proc-macro2 1.0.37", + "quote 1.0.18", "standback", - "syn", + "syn 1.0.92", ] [[package]] @@ -3359,9 +3619,9 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -3529,9 +3789,9 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", ] [[package]] @@ -3641,6 +3901,12 @@ checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" @@ -3815,9 +4081,9 @@ dependencies = [ "bumpalo", "lazy_static", "log 0.4.17", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", "wasm-bindgen-shared", ] @@ -3839,7 +4105,7 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ - "quote", + "quote 1.0.18", "wasm-bindgen-macro-support", ] @@ -3849,9 +4115,9 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.37", + "quote 1.0.18", + "syn 1.0.92", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 90532eb..b100649 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -104,12 +104,11 @@ version = "^2.11.0" features = ["http"] [dependencies.hyper] version = "^0.14.17" -features = ["client", "stream", "runtime"] -[dependencies.hyper-rustls] -version = "^0.23.0" -default-features = false -features = ["webpki-tokio", "http1", "http2", "tls12", "logging"] +features = ["stream", "runtime"] [dependencies.reqwest] version = "^0.11.10" default-features = false -features = ["rustls-tls-webpki-roots", "gzip", "brotli", "json", "stream"] \ No newline at end of file +features = ["rustls-tls-webpki-roots", "gzip", "brotli", "json", "stream"] +[dependencies.microformats] +version = "^0.2.0" +git = "https://gitlab.com/maxburon/microformats-parser" diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 3c3072d..eec2f85 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -286,8 +286,10 @@ pub fn homepage<D: Storage>(db: D, endpoints: IndiewebEndpoints) -> impl Filter< }) } -pub fn onboarding<D: Storage, T: hyper::client::connect::Connect + Clone + Send + Sync + 'static>( - db: D, endpoints: IndiewebEndpoints, http: hyper::Client<T, hyper::Body> +pub fn onboarding<D: Storage>( + db: D, + endpoints: IndiewebEndpoints, + http: reqwest::Client ) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { let inject_db = move || db.clone(); warp::get() @@ -304,7 +306,7 @@ pub fn onboarding<D: Storage, T: hyper::client::connect::Connect + Clone + Send .and(warp::any().map(inject_db)) .and(warp::body::json::<OnboardingData>()) .and(warp::any().map(move || http.clone())) - .and_then(|host: warp::host::Authority, db: D, body: OnboardingData, http: _| async move { + .and_then(|host: warp::host::Authority, db: D, body: OnboardingData, http: reqwest::Client| async move { let user_uid = format!("https://{}/", host.as_str()); if db.post_exists(&user_uid).await.map_err(FrontendError::from)? { diff --git a/src/indieauth.rs b/src/indieauth.rs index 4dfe11d..57c0301 100644 --- a/src/indieauth.rs +++ b/src/indieauth.rs @@ -62,8 +62,8 @@ impl From<serde_json::Error> for IndieAuthError { } } -impl From<hyper::Error> for IndieAuthError { - fn from(err: hyper::Error) -> Self { +impl From<reqwest::Error> for IndieAuthError { + fn from(err: reqwest::Error) -> Self { Self { msg: format!("{}", err), source: Some(Box::new(err)), @@ -90,11 +90,10 @@ impl User { } } -pub fn require_token<T>(token_endpoint: String, http: hyper::Client<T, hyper::Body>) -> impl Filter<Extract = (User,), Error = Rejection> + Clone -where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { +pub fn require_token(token_endpoint: String, http: reqwest::Client) -> impl Filter<Extract = (User,), Error = Rejection> + Clone { // It might be OK to panic here, because we're still inside the initialisation sequence for now. // Proper error handling on the top of this should be used though. - let token_endpoint_uri = hyper::Uri::try_from(&token_endpoint) + let token_endpoint_uri = url::Url::parse(&token_endpoint) .expect("Couldn't parse the token endpoint URI!"); warp::any() .map(move || token_endpoint_uri.clone()) @@ -110,60 +109,36 @@ where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { Err(err) } }).unify()) - .and_then(|token_endpoint, http: hyper::Client<T, hyper::Body>, token| async move { - let request = hyper::Request::builder() - .method(hyper::Method::GET) - .uri(token_endpoint) - .header("Authorization", token) - .header("Accept", "application/json") - .body(hyper::Body::from("")) - // TODO is it acceptable to panic here? - .unwrap(); - + .and_then(|token_endpoint, http: reqwest::Client, token| async move { use hyper::StatusCode; - match http.request(request).await { - Ok(mut res) => match res.status() { - StatusCode::OK => { - use hyper::body::HttpBody; - use bytes::BufMut; - let mut buf: Vec<u8> = Vec::default(); - while let Some(chunk) = res.body_mut().data().await { - if let Err(err) = chunk { - return Err(IndieAuthError::from(err).into()); - } - buf.put(chunk.unwrap()); - } - match serde_json::from_slice(&buf) { + match http + .get(token_endpoint) + .header("Authorization", token) + .header("Accept", "application/json") + .send() + .await + { + Ok(res) => match res.status() { + StatusCode::OK => match res.json::<serde_json::Value>().await { + Ok(json) => match serde_json::from_value::<User>(json.clone()) { Ok(user) => Ok(user), Err(err) => { - if let Ok(json) = serde_json::from_slice::<serde_json::Value>(&buf) { - if Some(false) == json["active"].as_bool() { - Err(IndieAuthError { - source: None, - kind: ErrorKind::NotAuthorized, - msg: "The token endpoint deemed the token as not \"active\".".to_string() - }.into()) - } else { - Err(IndieAuthError::from(err).into()) - } + if let Some(false) = json["active"].as_bool() { + Err(IndieAuthError { + source: None, + kind: ErrorKind::NotAuthorized, + msg: "The token is not active for this user.".to_owned() + }.into()) } else { Err(IndieAuthError::from(err).into()) } } } + Err(err) => Err(IndieAuthError::from(err).into()) }, StatusCode::BAD_REQUEST => { - use hyper::body::HttpBody; - use bytes::BufMut; - let mut buf: Vec<u8> = Vec::default(); - while let Some(chunk) = res.body_mut().data().await { - if let Err(err) = chunk { - return Err(IndieAuthError::from(err).into()); - } - buf.put(chunk.unwrap()); - } - match serde_json::from_slice::<TokenEndpointError>(&buf) { + match res.json::<TokenEndpointError>().await { Ok(err) => { if err.error == "unauthorized" { Err(IndieAuthError { @@ -211,8 +186,8 @@ mod tests { } #[inline] - fn get_http_client() -> hyper::Client<impl hyper::client::connect::Connect + Clone + Send + Sync + 'static, hyper::Body> { - hyper::Client::new() + fn get_http_client() -> reqwest::Client { + reqwest::Client::new() } #[tokio::test] diff --git a/src/main.rs b/src/main.rs index 0234abc..ed8c8e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,15 @@ use log::{debug, error, info}; use std::{convert::Infallible, env, time::Duration}; use url::Url; -use hyper::client::{HttpConnector,connect::dns::GaiResolver}; -use hyper_rustls::HttpsConnector; use warp::{Filter, host::Authority}; #[tokio::main] async fn main() { + // TODO turn into a feature so I can enable and disable it #[cfg(debug_assertions)] console_subscriber::init(); - // TODO json logging in the future? + + // TODO use tracing instead of log let logger_env = env_logger::Env::new().filter_or("RUST_LOG", "info"); env_logger::init_from_env(logger_env); @@ -97,18 +97,6 @@ async fn main() { } }; - // TODO remove this and see what screams to replace it with reqwest - let http_client: hyper::Client<HttpsConnector<HttpConnector<GaiResolver>>, hyper::Body> = { - let builder = hyper::Client::builder(); - let https = hyper_rustls::HttpsConnectorBuilder::new() - .with_webpki_roots() - .https_only() - .enable_http1() - .enable_http2() - .build(); - builder.build(https) - }; - // This thing handles redirects automatically but is type-incompatible with hyper::Client // Bonus: less generics to be aware of, this thing hides its complexity let http: reqwest::Client = { @@ -119,7 +107,7 @@ async fn main() { "/", env!("CARGO_PKG_VERSION") )); - // TODO add a root certificate if there's an environment variable pointing at it + // TODO: add a root certificate if there's an environment variable pointing at it //builder = builder.add_root_certificate(reqwest::Certificate::from_pem(todo!())); builder.build().unwrap() @@ -155,14 +143,18 @@ async fn main() { let onboarding = warp::path("onboarding") .and(warp::path::end()) - .and(kittybox::frontend::onboarding(database.clone(), endpoints.clone(), http_client.clone())); + .and(kittybox::frontend::onboarding( + database.clone(), + endpoints.clone(), + http.clone() + )); let micropub = warp::path("micropub") .and(warp::path::end() .and(kittybox::micropub::micropub( database.clone(), token_endpoint.to_string(), - http_client.clone() + http.clone() )) .or(warp::get() .and(warp::path("client")) diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs index 7aad51a..7175e56 100644 --- a/src/micropub/mod.rs +++ b/src/micropub/mod.rs @@ -51,7 +51,7 @@ impl From<StorageError> for MicropubError { crate::database::ErrorKind::NotFound => ErrorType::NotFound, _ => ErrorType::InternalServerError }, - error_description: format!("Backend error: {}", err.to_string()) + error_description: format!("Backend error: {}", err) } } } @@ -158,12 +158,12 @@ mod util { } // TODO actually save the post to the database and schedule post-processing -pub(crate) async fn _post<D: Storage, T: hyper::client::connect::Connect + Clone + Send + Sync + 'static>( +pub(crate) async fn _post<D: Storage>( user: crate::indieauth::User, uid: String, mf2: serde_json::Value, db: D, - http: hyper::Client<T, hyper::Body> + http: reqwest::Client ) -> Result<impl warp::Reply, MicropubError> { // Here, we have the following guarantees: // - The user is the same user for this host (guaranteed by ensure_same_user) @@ -248,23 +248,78 @@ pub(crate) async fn _post<D: Storage, T: hyper::client::connect::Connect + Clone use bytes::{Buf, BufMut}; use futures_util::StreamExt; - let mut contextually_significant_posts: Vec<hyper::Uri> = vec![]; + let uid: &str = mf2["properties"]["uid"][0].as_str().unwrap(); + + let mut contextually_significant_posts: Vec<url::Url> = vec![]; for prop in &["in-reply-to", "like-of", "repost-of", "bookmark-of"] { if let Some(array) = mf2["properties"][prop].as_array() { contextually_significant_posts.extend( array .iter() - .filter_map(|v| v.as_str().and_then(|v| v.parse::<hyper::Uri>().ok())), + .filter_map(|v| v.as_str()) + .filter_map(|v| v.parse::<url::Url>().ok()), ); } } + // TODO parse HTML in e-content and add links found here contextually_significant_posts.sort_unstable_by_key(|u| u.to_string()); contextually_significant_posts.dedup(); - // TODO: Make a stream to fetch all these posts and convert them to MF2 - drop(http); + #[derive(Debug)] + #[allow(dead_code)] + struct FetchedPostContext { + url: url::Url, + // TODO see if we can use non-strings for non-UTF-8 HTML + html: String, + mf2: serde_json::Value, + webmention: Option<hyper::Uri> + } + + { + // TODO: Make a stream to fetch all these posts and convert them to MF2 + let post_contexts = { + let http = &http; + tokio_stream::iter(contextually_significant_posts + .into_iter() + ).then(move |url: url::Url| async move { + let html: String = todo!("Fetch the post using {:?}", http); + // We just need to get the following here: + // 1. We need to preserve the URL + // 2. We need to get the HTML for MF2 processing + // 3. We need to get the webmention endpoint address + // All of that can be done in one go. + + // XXX stub! + + dbg!(FetchedPostContext { + url, html, + mf2: serde_json::to_value(microformats::from_html(&html, url).unwrap()).unwrap(), + webmention: None + }) + }) + .collect::<Vec<FetchedPostContext>>() + .await + }; - todo!() + drop(post_contexts); + } + // At this point we can start syndicating the post. + // Currently we don't really support any syndication endpoints, but still! + if let Some(syndicate_to) = mf2["properties"]["mp-syndicate-to"].as_array() { + let http = &http; + tokio_stream::iter(syndicate_to) + .filter_map(|i| futures::future::ready(i.as_str())) + .for_each_concurrent(3, |s: &str| async move { + #[allow(clippy::match_single_binding)] + match s { + _ => { + todo!("Syndicate to generic webmention-aware service {}", s); + } + // TODO special handling for non-webmention-aware services like the birdsite + } + }) + .await; + } }); Ok(reply) @@ -378,11 +433,10 @@ async fn check_auth(host: warp::host::Authority, user: User) -> Result<User, war } #[cfg(any(not(debug_assertions), test))] -fn ensure_same_user_as_host<T>( +fn ensure_same_user_as_host( token_endpoint: String, - http: hyper::Client<T, hyper::Body> -) -> impl Filter<Extract = (User,), Error = warp::Rejection> + Clone -where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { + http: reqwest::Client +) -> impl Filter<Extract = (User,), Error = warp::Rejection> + Clone { crate::util::require_host() .and(crate::indieauth::require_token(token_endpoint, http)) .and_then(check_auth) @@ -443,12 +497,11 @@ async fn dispatch_post_body( } #[cfg_attr(all(debug_assertions, not(test)), allow(unused_variables))] -pub fn post<D: 'static + Storage, T>( +pub fn post<D: 'static + Storage>( db: D, token_endpoint: String, - http: hyper::Client<T, hyper::Body> -) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone -where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { + http: reqwest::Client +) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { let inject_db = warp::any().map(move || db.clone()); #[cfg(all(debug_assertions, not(test)))] let ensure_same_user = warp::any().map(|| crate::indieauth::User::new( @@ -467,7 +520,7 @@ where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { .and(inject_db) .and(warp::any().map(move || http.clone())) .and(ensure_same_user) - .and_then(|body: Either<MicropubAction, serde_json::Value>, db: D, http: hyper::Client<T, hyper::Body>, user: crate::indieauth::User| async move { + .and_then(|body: Either<MicropubAction, serde_json::Value>, db: D, http: reqwest::Client, user: crate::indieauth::User| async move { (match body { Either::Left(action) => { post_action(action, db, user).await.map(|p| Box::new(p) as Box<dyn warp::Reply>) @@ -588,8 +641,11 @@ async fn _query<D: Storage>( } } -pub fn query<D: Storage, T>(db: D, token_endpoint: String, http: hyper::Client<T, hyper::Body>) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone -where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { +pub fn query<D: Storage>( + db: D, + token_endpoint: String, + http: reqwest::Client +) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { warp::get() .map(move || db.clone()) .and(warp::query::<MicropubQuery>()) @@ -626,8 +682,11 @@ pub async fn recover(err: Rejection) -> Result<impl warp::Reply, Infallible> { Ok(warp::reply::with_status(warp::reply::json(&error), error.into())) } -pub fn micropub<D: 'static + Storage, T>(db: D, token_endpoint: String, http: hyper::Client<T, hyper::Body>) -> impl Filter<Extract = (impl warp::Reply,), Error = Infallible> + Clone -where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { +pub fn micropub<D: 'static + Storage>( + db: D, + token_endpoint: String, + http: reqwest::Client +) -> impl Filter<Extract = (impl warp::Reply,), Error = Infallible> + Clone { query(db.clone(), token_endpoint.clone(), http.clone()) .or(post(db, token_endpoint, http)) .or(options()) @@ -685,7 +744,7 @@ mod tests { let (uid, mf2) = super::post::normalize_mf2(post, &user); super::_post( - user, uid, mf2, db, hyper::Client::new() + user, uid, mf2, db, reqwest::Client::new() ).await.map_err(warp::reject::custom) }) ) @@ -730,7 +789,7 @@ mod tests { let (uid, mf2) = super::post::normalize_mf2(post, &user); super::_post( - user, uid, mf2, db, hyper::Client::new() + user, uid, mf2, db, reqwest::Client::new() ).await.map_err(warp::reject::custom) }) ) |