diff options
-rw-r--r-- | Cargo.lock | 1357 | ||||
-rw-r--r-- | Cargo.toml | 38 | ||||
-rw-r--r-- | indieauth/Cargo.toml | 4 | ||||
-rw-r--r-- | src/database/postgres/mod.rs | 4 | ||||
-rw-r--r-- | src/indieauth/mod.rs | 11 | ||||
-rw-r--r-- | src/indieauth/webauthn.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 23 | ||||
-rw-r--r-- | src/media/mod.rs | 8 | ||||
-rw-r--r-- | src/micropub/mod.rs | 34 | ||||
-rw-r--r-- | src/webmentions/check.rs | 23 | ||||
-rw-r--r-- | src/webmentions/check/rcdom.rs | 515 | ||||
-rw-r--r-- | templates-neo/Cargo.toml | 9 | ||||
-rw-r--r-- | templates-neo/src/mf2.rs | 69 | ||||
-rw-r--r-- | templates/Cargo.toml | 11 | ||||
-rw-r--r-- | templates/src/lib.rs | 81 | ||||
-rw-r--r-- | util/Cargo.toml | 6 |
17 files changed, 1442 insertions, 760 deletions
diff --git a/Cargo.lock b/Cargo.lock index 744e9bd..a2b49cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,16 @@ version = 3 [[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] name = "addr2line" version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -30,7 +40,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.15", "once_cell", "version_check", "zerocopy 0.7.35", @@ -137,6 +146,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] name = "argon2" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -170,8 +185,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 1.0.109", "synstructure", ] @@ -182,8 +197,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -198,14 +213,15 @@ dependencies = [ ] [[package]] -name = "async-channel" -version = "1.9.0" +name = "ast_node" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +checksum = "f9184f2b369b3e8625712493c89b785881f27eedc6cde480a81883cef78868b2" dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.72", ] [[package]] @@ -228,8 +244,8 @@ version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -243,12 +259,20 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "0.1.8" +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "auto_impl" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "autocfg 1.3.0", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] @@ -259,20 +283,20 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.6.20" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", "axum-macros", - "bitflags 1.3.2", "bytes", "futures-util", - "headers", "http", "http-body", + "http-body-util", "hyper", + "hyper-util", "itoa 1.0.11", "matchit", "memchr", @@ -285,61 +309,68 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes", "futures-util", "http", "http-body", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-extra" -version = "0.7.7" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93e433be9382c737320af3924f7d5fc6f89c155cf2bf88949d8f5126fab283f" +checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733" dependencies = [ "axum", "axum-core", "bytes", "cookie", "futures-util", + "headers", "http", "http-body", + "http-body-util", "mime", "pin-project-lite", "serde", - "tokio", "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-macros" -version = "0.3.8" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" +checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -371,6 +402,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] name = "base64ct" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -388,6 +425,26 @@ dependencies = [ ] [[package]] +name = "base64urlsafedata" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a56894edf5cd1efa7068d7454adeb7ce0b3da4ffa5ab08cfc06165bbc62f0c7" +dependencies = [ + "base64 0.21.7", + "paste", + "serde", +] + +[[package]] +name = "better_scoped_tls" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de" +dependencies = [ + "scoped-tls", +] + +[[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -515,8 +572,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -527,15 +584,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] name = "colorchoice" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -562,14 +610,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7aa76ef19968577838a34d02848136bb9b6bdbfd7675fb968fe9c931bc434b33" dependencies = [ "base64 0.13.1", - "base64urlsafedata", + "base64urlsafedata 0.1.3", "hex", "openssl", "serde", "serde_json", "tracing", "url", - "uuid 1.10.0", + "uuid", ] [[package]] @@ -595,11 +643,11 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "hmac", "percent-encoding", "rand 0.8.5", @@ -703,8 +751,8 @@ dependencies = [ "itoa 0.4.8", "matches", "phf 0.8.0", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "smallvec", "syn 1.0.109", ] @@ -715,7 +763,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ - "quote 1.0.36", + "quote", "syn 2.0.72", ] @@ -733,14 +781,13 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deadpool" -version = "0.9.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" dependencies = [ "async-trait", "deadpool-runtime", "num_cpus", - "retain_mut", "tokio", ] @@ -782,6 +829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -791,8 +839,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "rustc_version", "syn 2.0.72", ] @@ -821,8 +869,8 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -914,9 +962,14 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "faker_rand" @@ -931,15 +984,6 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" @@ -996,10 +1040,15 @@ dependencies = [ ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "from_variant" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4" +dependencies = [ + "proc-macro2", + "swc_macros_common", + "syn 2.0.72", +] [[package]] name = "futf" @@ -1071,28 +1120,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] name = "futures-macro" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -1109,12 +1143,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" - -[[package]] name = "futures-util" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1181,15 +1209,15 @@ checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" -version = "0.3.26" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap", "slab", @@ -1216,18 +1244,18 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown", ] [[package]] name = "headers" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ "base64 0.21.7", "bytes", @@ -1235,14 +1263,14 @@ dependencies = [ "http", "httpdate", "mime", - "sha1 0.10.6", + "sha1", ] [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ "http", ] @@ -1252,9 +1280,6 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] [[package]] name = "heck" @@ -1302,6 +1327,20 @@ dependencies = [ ] [[package]] +name = "hstr" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96274be293b8877e61974a607105d09c84caebe9620b47774aa8a6b942042dd4" +dependencies = [ + "hashbrown", + "new_debug_unreachable", + "once_cell", + "phf 0.11.2", + "rustc-hash", + "triomphe", +] + +[[package]] name = "html" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1318,37 +1357,37 @@ checksum = "13eca55667a5657dd1b86db77c5fe2d1810e3f9413e9555a2c4c461733dd2573" [[package]] name = "html5ever" -version = "0.22.5" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c213fa6a618dc1da552f54f85cba74b05d8e883c92ec4e89067736938084c26e" +checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" dependencies = [ "log", "mac", - "markup5ever 0.7.5", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", + "markup5ever 0.10.1", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "html5ever" -version = "0.25.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" dependencies = [ "log", "mac", - "markup5ever 0.10.1", - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 1.0.109", + "markup5ever 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1357,40 +1396,25 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", - "pin-project-lite", ] [[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - -[[package]] -name = "http-types" -version = "2.12.0" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "anyhow", - "async-channel", - "base64 0.13.1", - "futures-lite", + "bytes", + "futures-util", "http", - "infer", + "http-body", "pin-project-lite", - "rand 0.7.3", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "url", ] [[package]] @@ -1407,13 +1431,12 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", @@ -1422,38 +1445,63 @@ dependencies = [ "httpdate", "itoa 1.0.11", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http", "hyper", - "rustls", + "hyper-util", + "rustls 0.23.12", + "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", + "webpki-roots 0.26.3", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -1504,8 +1552,8 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", ] [[package]] @@ -1519,27 +1567,24 @@ dependencies = [ ] [[package]] -name = "infer" -version = "0.2.3" +name = "ipnet" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "instant" -version = "0.1.13" +name = "is-macro" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" dependencies = [ - "cfg-if", + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1575,7 +1620,7 @@ dependencies = [ "async-trait", "axum", "axum-extra", - "base64 0.21.7", + "base64 0.22.1", "bytes", "chrono", "clap", @@ -1586,6 +1631,7 @@ dependencies = [ "futures", "futures-util", "hex", + "html5ever 0.27.0", "hyper", "kittybox-frontend-renderer", "kittybox-indieauth", @@ -1615,12 +1661,12 @@ dependencies = [ "tower", "tower-http", "tracing", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", "tracing-test", "tracing-tree", "url", - "uuid 1.10.0", + "uuid", "webauthn-rs", "wiremock", ] @@ -1642,6 +1688,7 @@ dependencies = [ "microformats", "rand 0.8.5", "serde_json", + "time", "walkdir", ] @@ -1663,6 +1710,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "thiserror", + "time", "url", "walkdir", ] @@ -1695,7 +1743,7 @@ dependencies = [ "serde_json", "sqlx", "tokio", - "uuid 1.10.0", + "uuid", ] [[package]] @@ -1757,9 +1805,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" dependencies = [ "cc", "pkg-config", @@ -1774,12 +1822,12 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "listenfd" -version = "0.5.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02b14f35d9f5f082fd0b1b34aa0ef32e3354c859c721d7f3325b3f79a42ba54" +checksum = "e0500463acd96259d219abb05dc57e5a076ef04b2db9a2112846929b5f174c96" dependencies = [ "libc", - "uuid 0.8.2", + "uuid", "winapi", ] @@ -1789,7 +1837,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ - "autocfg 1.3.0", + "autocfg", "scopeguard", ] @@ -1816,52 +1864,49 @@ dependencies = [ [[package]] name = "markup" -version = "0.13.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9196a235d499738d04f6a2466ce2610bf6b84730610efea8bee1b90d028b0d" +checksum = "74a887ad620fe1022257343ac77fcdd3720e92888e1b2e66e1b7a4707f453898" dependencies = [ - "itoa 1.0.11", "markup-proc-macro", ] [[package]] name = "markup-proc-macro" -version = "0.13.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a927f0e237dcbdd8c1a8ab03c4e1e8b1999804c448ebf06ff3b5512506c8150" +checksum = "9ab6ee21fd1855134cacf2f41afdf45f1bc456c7d7f6165d763b4647062dd2be" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] name = "markup5ever" -version = "0.7.5" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897636f9850c3eef4905a5540683ed53dc9393860f0846cab2c2ddf9939862ff" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" 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", + "log", + "phf 0.8.0", + "phf_codegen 0.8.0", + "string_cache", + "string_cache_codegen", "tendril", ] [[package]] name = "markup5ever" -version = "0.10.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" dependencies = [ "log", - "phf 0.8.0", - "phf_codegen 0.8.0", - "string_cache 0.8.7", - "string_cache_codegen 0.5.2", + "phf 0.11.2", + "phf_codegen 0.11.2", + "string_cache", + "string_cache_codegen", "tendril", ] @@ -1904,18 +1949,39 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "microformats" -version = "0.3.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e7fccd15cba21880e824d71b8354e9e67561c9cd2bf3ec09b21dba26392ecb" +checksum = "ed8bbf237d3068b89f1e445b9789bd0e5731638a018227722348cfc84b967fb8" dependencies = [ - "chrono", - "html5ever 0.22.5", "lazy_static", - "log", + "microformats-types", "regex", "serde", "serde_json", + "swc_common", + "swc_html_ast", + "swc_html_codegen", + "swc_html_parser", + "swc_html_visit", "thiserror", + "time", + "tracing", + "tracing-unwrap", + "url", +] + +[[package]] +name = "microformats-types" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4e0d8cf1d664df99cf57e6bcff23e4ee3e8676da1ede5c15ecb398783fe72a" +dependencies = [ + "lazy_static", + "regex", + "serde", + "serde_json", + "thiserror", + "time", "url", ] @@ -1954,16 +2020,15 @@ dependencies = [ [[package]] name = "multer" -version = "2.1.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ "bytes", "encoding_rs", "futures-util", "http", "httparse", - "log", "memchr", "mime", "spin", @@ -2026,6 +2091,15 @@ dependencies = [ ] [[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] name = "num-bigint" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2073,7 +2147,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ - "autocfg 1.3.0", + "autocfg", "num-integer", "num-traits", ] @@ -2084,7 +2158,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg 1.3.0", + "autocfg", "libm", ] @@ -2143,8 +2217,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -2235,15 +2309,6 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[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" @@ -2254,13 +2319,12 @@ dependencies = [ ] [[package]] -name = "phf_codegen" -version = "0.7.24" +name = "phf" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_generator 0.7.24", - "phf_shared 0.7.24", + "phf_shared 0.11.2", ] [[package]] @@ -2274,13 +2338,13 @@ dependencies = [ ] [[package]] -name = "phf_generator" -version = "0.7.24" +name = "phf_codegen" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ - "phf_shared 0.7.24", - "rand 0.6.5", + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -2304,6 +2368,16 @@ dependencies = [ ] [[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] name = "phf_macros" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2312,36 +2386,36 @@ dependencies = [ "phf_generator 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "phf_shared" -version = "0.7.24" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ - "siphasher 0.2.3", + "siphasher", ] [[package]] name = "phf_shared" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "siphasher 0.3.11", + "siphasher", ] [[package]] name = "phf_shared" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ - "siphasher 0.3.11", + "siphasher", ] [[package]] @@ -2359,8 +2433,8 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -2432,15 +2506,6 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[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.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" @@ -2495,40 +2560,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] -name = "quote" -version = "0.6.13" +name = "quinn" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" dependencies = [ - "proc-macro2 0.4.30", + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.12", + "thiserror", + "tokio", + "tracing", ] [[package]] -name = "quote" -version = "1.0.36" +name = "quinn-proto" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" dependencies = [ - "proc-macro2 1.0.86", + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls 0.23.12", + "slab", + "thiserror", + "tinyvec", + "tracing", ] [[package]] -name = "rand" -version = "0.6.5" +name = "quinn-udp" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" 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", + "once_cell", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", ] [[package]] @@ -2541,8 +2624,8 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", + "rand_hc", + "rand_pcg", ] [[package]] @@ -2558,16 +2641,6 @@ 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" @@ -2588,21 +2661,6 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" @@ -2621,15 +2679,6 @@ 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" @@ -2638,50 +2687,6 @@ 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", -] - -[[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", -] - -[[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" @@ -2691,38 +2696,23 @@ 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" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] name = "redis" -version = "0.21.7" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "152f3863635cbb76b73bc247845781098302c6c9ad2060e1a9a7de56840346b6" +checksum = "8cc5b667390cb038bc65fc4b18c06e2550469f7e06a02d886f1a018a11f63563" dependencies = [ + "arc-swap", "async-trait", "bytes", "combine", "futures-util", "itoa 1.0.11", + "num-bigint", "percent-encoding", "pin-project-lite", "ryu", - "sha1 0.6.1", + "sha1_smol", + "socket2", "tokio", "tokio-util", "url", @@ -2798,22 +2788,22 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "async-compression", - "base64 0.21.7", + "base64 0.22.1", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", "http", "http-body", + "http-body-util", "hyper", "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", @@ -2822,13 +2812,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "quinn", + "rustls 0.23.12", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "sync_wrapper 1.0.1", "tokio", "tokio-native-tls", "tokio-rustls", @@ -2839,17 +2830,11 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.26.3", "winreg", ] [[package]] -name = "retain_mut" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" - -[[package]] name = "ring" version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2897,6 +2882,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2933,13 +2924,26 @@ version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ - "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] [[package]] +name = "rustls" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.6", + "subtle", + "zeroize", +] + +[[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2949,6 +2953,22 @@ dependencies = [ ] [[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2959,6 +2979,17 @@ dependencies = [ ] [[package]] +name = "rustls-webpki" +version = "0.102.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2989,6 +3020,12 @@ dependencies = [ ] [[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3078,8 +3115,8 @@ version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -3106,17 +3143,6 @@ dependencies = [ ] [[package]] -name = "serde_qs" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", -] - -[[package]] name = "serde_urlencoded" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3149,15 +3175,6 @@ dependencies = [ [[package]] name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - -[[package]] -name = "sha1" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" @@ -3214,12 +3231,6 @@ dependencies = [ [[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.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" @@ -3230,7 +3241,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "autocfg 1.3.0", + "autocfg", ] [[package]] @@ -3238,6 +3249,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -3291,9 +3305,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +checksum = "27144619c6e5802f1380337a209d2ac1c431002dd74c6e60aebff3c506dc4f0c" dependencies = [ "sqlx-core", "sqlx-macros", @@ -3304,11 +3318,10 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +checksum = "a999083c1af5b5d6c071d34a708a19ba3e02106ad82ef7bbd69f5e48266b613b" dependencies = [ - "ahash", "atoi", "byteorder", "bytes", @@ -3322,6 +3335,7 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", + "hashbrown", "hashlink", "hex", "indexmap", @@ -3331,8 +3345,8 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls", - "rustls-pemfile", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "sha2", @@ -3343,36 +3357,36 @@ dependencies = [ "tokio-stream", "tracing", "url", - "uuid 1.10.0", - "webpki-roots", + "uuid", + "webpki-roots 0.25.4", ] [[package]] name = "sqlx-macros" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +checksum = "a23217eb7d86c584b8cbe0337b9eacf12ab76fe7673c513141ec42565698bb88" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "sqlx-macros-core" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck 0.5.0", "hex", "once_cell", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "serde", "serde_json", "sha2", @@ -3380,7 +3394,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", + "syn 2.0.72", "tempfile", "tokio", "url", @@ -3388,12 +3402,12 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +checksum = "5afe4c38a9b417b6a9a5eeffe7235d0a106716495536e7727d1c7f4b1ff3eba6" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "byteorder", "bytes", @@ -3419,25 +3433,25 @@ dependencies = [ "rand 0.8.5", "rsa", "serde", - "sha1 0.10.6", + "sha1", "sha2", "smallvec", "sqlx-core", "stringprep", "thiserror", "tracing", - "uuid 1.10.0", + "uuid", "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +checksum = "b1dbb157e65f10dbe01f729339c06d239120221c9ad9fa0ba8408c4cc18ecf21" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "byteorder", "chrono", @@ -3466,15 +3480,15 @@ dependencies = [ "stringprep", "thiserror", "tracing", - "uuid 1.10.0", + "uuid", "whoami", ] [[package]] name = "sqlx-sqlite" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +checksum = "9b2cdd83c008a622d94499c0006d8ee5f821f36c89b7d625c900e5dc30b5c5ee" dependencies = [ "atoi", "chrono", @@ -3488,11 +3502,11 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", "tracing", "url", - "urlencoding", - "uuid 1.10.0", + "uuid", ] [[package]] @@ -3503,21 +3517,6 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[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.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" @@ -3532,34 +3531,27 @@ 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.86", - "quote 1.0.36", - "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 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", ] [[package]] -name = "string_cache_shared" -version = "0.3.0" +name = "string_enum" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" +checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.72", +] [[package]] name = "stringprep" @@ -3585,14 +3577,164 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "syn" -version = "0.15.44" +name = "swc_atoms" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", + "hstr", + "once_cell", + "rustc-hash", + "serde", +] + +[[package]] +name = "swc_common" +version = "0.33.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f9706038906e66f3919028f9f7a37f3ed552f1b85578e93f4468742e2da438" +dependencies = [ + "ast_node", + "better_scoped_tls", + "cfg-if", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "rustc-hash", + "serde", + "siphasher", + "swc_atoms", + "swc_eq_ignore_macros", + "swc_visit", + "tracing", + "unicode-width", + "url", +] + +[[package]] +name = "swc_eq_ignore_macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "swc_html_ast" +version = "0.33.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59957df8048be691db04e6e358b29c6ff1274cd60ee2b4c2141e1d90b598d24e" +dependencies = [ + "is-macro", + "serde", + "string_enum", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_html_codegen" +version = "0.42.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c28899c6d01596124686dae5d139412488f4066d013a6c5691e497f5e9a98f" +dependencies = [ + "auto_impl", + "bitflags 2.6.0", + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_html_ast", + "swc_html_codegen_macros", + "swc_html_utils", +] + +[[package]] +name = "swc_html_codegen_macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e593a6cbb3a49230fbab3171d4493f7d0fb1e20a34d9a9f9e972550690408ba8" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.72", +] + +[[package]] +name = "swc_html_parser" +version = "0.39.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06cda5fcfd7c979a473be215cb7263e13bb7707bec46d0b6fbf364d203eea2d" +dependencies = [ + "swc_atoms", + "swc_common", + "swc_html_ast", + "swc_html_utils", +] + +[[package]] +name = "swc_html_utils" +version = "0.18.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406d1fcf69915a6726065060a9e85e7f36d66239708901d9bd0ad4d4b4e935a8" +dependencies = [ + "once_cell", + "serde", + "serde_json", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_html_visit" +version = "0.33.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cffd11c6331e830a6f954597edd612d9393b6a4edb6e88004e5d7e84ee73b570" +dependencies = [ + "serde", + "swc_atoms", + "swc_common", + "swc_html_ast", + "swc_visit", +] + +[[package]] +name = "swc_macros_common" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "swc_visit" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" +dependencies = [ + "either", + "swc_visit_macros", +] + +[[package]] +name = "swc_visit_macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.72", ] [[package]] @@ -3601,8 +3743,8 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "unicode-ident", ] @@ -3612,8 +3754,8 @@ version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "unicode-ident", ] @@ -3624,36 +3766,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 1.0.109", - "unicode-xid 0.2.4", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "unicode-xid", ] [[package]] @@ -3663,7 +3790,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand", "rustix", "windows-sys 0.52.0", ] @@ -3700,8 +3827,8 @@ version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -3786,8 +3913,8 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -3803,11 +3930,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls", + "rustls 0.23.12", + "rustls-pki-types", "tokio", ] @@ -3853,17 +3981,16 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", - "futures-core", "futures-util", "http", "http-body", - "http-range-header", + "http-body-util", "pin-project-lite", "tower-layer", "tower-service", @@ -3900,8 +4027,8 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -3917,17 +4044,6 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-log" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" @@ -3954,7 +4070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", - "nu-ansi-term", + "nu-ansi-term 0.46.0", "once_cell", "regex", "serde", @@ -3964,7 +4080,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log 0.2.0", + "tracing-log", "tracing-serde", ] @@ -3985,23 +4101,42 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ - "quote 1.0.36", + "quote", "syn 2.0.72", ] [[package]] name = "tracing-tree" -version = "0.2.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d" +checksum = "f459ca79f1b0d5f71c54ddfde6debfc59c8b6eeb46808ae492077f739dc7b49c" dependencies = [ - "nu-ansi-term", + "nu-ansi-term 0.50.1", "tracing-core", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", ] [[package]] +name = "tracing-unwrap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4e33415be97f5ae70322d6fefc696bbc08887d8835400d6c77f059469b30354" +dependencies = [ + "tracing", +] + +[[package]] +name = "triomphe" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4053,10 +4188,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] -name = "unicode-xid" -version = "0.1.0" +name = "unicode-width" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -4089,12 +4224,6 @@ dependencies = [ ] [[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4108,12 +4237,6 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" - -[[package]] -name = "uuid" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" @@ -4141,12 +4264,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - -[[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4202,8 +4319,8 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", "wasm-bindgen-shared", ] @@ -4226,7 +4343,7 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote 1.0.36", + "quote", "wasm-bindgen-macro-support", ] @@ -4236,8 +4353,8 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -4273,50 +4390,67 @@ dependencies = [ ] [[package]] +name = "webauthn-attestation-ca" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b0f2ebaf5650ca15b515a761f31ed6477fa2312491cf632a71102ac22b82784" +dependencies = [ + "base64urlsafedata 0.5.0", + "openssl", + "serde", + "tracing", + "uuid", +] + +[[package]] name = "webauthn-rs" -version = "0.4.8" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db00711c712414e93b019c4596315085792215bc2ac2d5872f9e8913b0a6316" +checksum = "fb9d7cdc9ec26e3e06f7e8ee1433e6fa3627c6c075ab3effbc3a2280c2f526c0" dependencies = [ - "base64urlsafedata", + "base64urlsafedata 0.5.0", "serde", "tracing", "url", - "uuid 1.10.0", + "uuid", "webauthn-rs-core", ] [[package]] name = "webauthn-rs-core" -version = "0.4.9" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "294c78c83f12153a51e1cf1e6970b5da1397645dada39033a9c3173a8fc4fc2b" +checksum = "cf1ee1dc7f4138b8fd05a74a6eae93ddaf504c5a60861f1eb95d9de3172900b3" dependencies = [ - "base64 0.13.1", - "base64urlsafedata", + "base64 0.21.7", + "base64urlsafedata 0.5.0", "compact_jwt", "der-parser", + "hex", "nom", "openssl", "rand 0.8.5", + "rand_chacha 0.3.1", "serde", "serde_cbor_2", "serde_json", "thiserror", "tracing", "url", - "uuid 1.10.0", + "uuid", + "webauthn-attestation-ca", "webauthn-rs-proto", "x509-parser", ] [[package]] name = "webauthn-rs-proto" -version = "0.4.9" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24e638361a63ba5c0a0be6a60229490fcdf33740ed63df5bb6bdb627b52a138" +checksum = "1f1c6dc254607f48eec3bdb35b86b377202436859ca1e4c9290afafd7349dcc3" dependencies = [ - "base64urlsafedata", + "base64 0.21.7", + "base64urlsafedata 0.5.0", "serde", "serde_json", "url", @@ -4329,6 +4463,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] +name = "webpki-roots" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] + +[[package]] name = "whoami" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4519,9 +4662,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if", "windows-sys 0.48.0", @@ -4529,24 +4672,26 @@ dependencies = [ [[package]] name = "wiremock" -version = "0.5.22" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a3a53eaf34f390dd30d7b1b078287dd05df2aa2e21a589ccb80f5c7253c2e9" +checksum = "6a59f8ae78a4737fb724f20106fb35ccb7cfe61ff335665d3042b3aa98e34717" dependencies = [ "assert-json-diff", "async-trait", "base64 0.21.7", "deadpool", "futures", - "futures-timer", - "http-types", + "http", + "http-body-util", "hyper", + "hyper-util", "log", "once_cell", "regex", "serde", "serde_json", "tokio", + "url", ] [[package]] @@ -4592,8 +4737,8 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] @@ -4603,8 +4748,8 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.36", + "proc-macro2", + "quote", "syn 2.0.72", ] diff --git a/Cargo.toml b/Cargo.toml index 974bb67..9062cfe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ default = ["rustls", "postgres"] #util = ["anyhow"] #migration = ["util"] webauthn = ["openssl", "dep:webauthn"] -openssl = ["reqwest/native-tls-crate", "reqwest/native-tls-alpn", "sqlx/tls-native-tls"] +openssl = ["reqwest/native-tls", "reqwest/native-tls-alpn", "sqlx/tls-native-tls"] rustls = ["reqwest/rustls-tls-webpki-roots", "sqlx/tls-rustls"] cli = ["clap"] postgres = ["sqlx", "kittybox-util/sqlx"] @@ -71,7 +71,7 @@ features = ["axum"] [dev-dependencies] tempfile = "^3.4.0" # Temporary file managment -wiremock = "^0.5.14" +wiremock = "^0.6.1" faker_rand = "^0.1.1" # Seedable, rand-compatible generators of fake data rand = "^0.8.5" # Utilities for random number generation tracing-test = "^0.2.2" @@ -87,8 +87,7 @@ futures = "^0.3.14" # An implementation of futures and streams futures-util = "^0.3.14" # Common utilities and extension traits for the futures-rs library hex = "^0.4.3" lazy_static = "^1.4.0" # A macro for declaring lazily evaluated statics in Rust -listenfd = "^0.5.0" # A simple library to work with listenfds passed from the outside (systemd/catflap socket activation) -#log = "^0.4.14" # A lightweight logging facade for Rust +listenfd = "^1.0.1" # A simple library to work with listenfds passed from the outside (systemd/catflap socket activation) markdown = "^1.0.0-alpha.7" # Native Rust library for parsing Markdown and (outputting HTML) newbase60 = "^0.1.3" # A library that implements Tantek Çelik's New Base 60 rand = "^0.8.4" # Random number generators. @@ -99,13 +98,14 @@ relative-path = "^1.5.0" # Portable relative paths for Rust sha2 = "^0.10.7" # SHA-2 series of algorithms for Rust uuid = "^1.3.3" tracing = { version = "0.1.34", features = [] } -tracing-tree = "0.2.1" -tracing-log = "0.1.3" +tracing-tree = "0.4.0" +tracing-log = "0.2.0" tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] } -tower-http = { version = "0.3.3", features = ["trace", "cors", "catch-panic", "sensitive-headers"] } +tower-http = { version = "0.5.0", features = ["trace", "cors", "catch-panic", "sensitive-headers"] } tower = { version = "0.4.12", features = ["tracing"] } -webauthn = { version = "0.4.5", package = "webauthn-rs", features = ["danger-allow-state-serialisation"], optional = true } -base64 = "0.21.2" +webauthn = { version = "0.5.0", package = "webauthn-rs", features = ["danger-allow-state-serialisation"], optional = true } +base64 = "0.22.1" +html5ever = "0.27.0" [dependencies.tokio] version = "^1.29.1" features = ["full", "tracing"] # TODO determine if my app doesn't need some features @@ -121,16 +121,16 @@ features = ["io-util"] version = "^1.0.42" optional = true [dependencies.axum] -version = "^0.6.18" -features = ["multipart", "json", "headers", "form", "macros"] +version = "^0.7.5" +features = ["multipart", "json", "form", "macros"] [dependencies.axum-extra] -version = "^0.7.4" -features = ["cookie", "cookie-signed"] +version = "^0.9.3" +features = ["cookie", "cookie-signed", "typed-header"] [dependencies.chrono] # Date and time library for Rust version = "^0.4.19" features = ["serde"] [dependencies.redis] -version = "^0.21.3" +version = "^0.26.0" optional = true features = ["aio", "tokio-comp"] [dependencies.prometheus] # Prometheus instrumentation library for Rust applications @@ -143,14 +143,14 @@ features = ["derive"] version = "^2.2.1" features = ["serde"] [dependencies.hyper] -version = "^0.14.17" -features = ["stream", "runtime"] +version = "^1.4.1" +features = [] [dependencies.reqwest] -version = "^0.11.10" +version = "^0.12.5" default-features = false features = ["gzip", "brotli", "json", "stream"] [dependencies.microformats] -version = "^0.3.0" +version = "^0.9.1" #git = "https://gitlab.com/maxburon/microformats-parser" [dependencies.clap] @@ -160,7 +160,7 @@ optional = true [dependencies.thiserror] version = "1.0.35" [dependencies.sqlx] -version = "^0.7" +version = "^0.8" features = ["uuid", "chrono", "json", "postgres", "runtime-tokio"] optional = true [dependencies.sqlparser] diff --git a/indieauth/Cargo.toml b/indieauth/Cargo.toml index 8d2dc90..2c30aed 100644 --- a/indieauth/Cargo.toml +++ b/indieauth/Cargo.toml @@ -21,11 +21,11 @@ features = ["serde"] version = "^1.0.170" features = ["derive"] [dependencies.axum-core] -version = "^0.3.4" +version = "^0.4.3" optional = true [dependencies.serde_json] version = "^1.0.64" optional = true [dependencies.http] -version = "^0.2.7" +version = "^1.0" optional = true \ No newline at end of file diff --git a/src/database/postgres/mod.rs b/src/database/postgres/mod.rs index 0ebaffb..7f788a8 100644 --- a/src/database/postgres/mod.rs +++ b/src/database/postgres/mod.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::str::FromStr; use kittybox_util::{MicropubChannel, MentionType}; use sqlx::{ConnectOptions, Executor, PgPool}; @@ -30,6 +29,7 @@ impl From<sqlx::migrate::MigrateError> for StorageError { } } +/// Micropub storage that uses a PostgreSQL database. #[derive(Debug, Clone)] pub struct PostgresStorage { db: PgPool @@ -38,7 +38,7 @@ pub struct PostgresStorage { impl PostgresStorage { /// Construct a [`PostgresStorage`] from a [`sqlx::PgPool`], /// running appropriate migrations. - pub async fn from_pool(db: sqlx::PgPool) -> Result<Self> { + pub(crate) async fn from_pool(db: sqlx::PgPool) -> Result<Self> { db.execute(sqlx::query("CREATE SCHEMA IF NOT EXISTS kittybox")).await?; MIGRATOR.run(&db).await?; Ok(Self { db }) diff --git a/src/indieauth/mod.rs b/src/indieauth/mod.rs index 2550df0..de4c367 100644 --- a/src/indieauth/mod.rs +++ b/src/indieauth/mod.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; - use microformats::types::Class; use tracing::error; use serde::Deserialize; use axum::{ - extract::{Form, FromRef, Host, Json, Query, State}, headers::{authorization::Bearer, Authorization}, http::StatusCode, response::{Html, IntoResponse, Response}, Extension, TypedHeader + extract::{Form, FromRef, Host, Json, Query, State}, http::StatusCode, response::{Html, IntoResponse, Response}, Extension }; #[cfg_attr(not(feature = "webauthn"), allow(unused_imports))] use axum_extra::extract::cookie::{CookieJar, Cookie}; +use axum_extra::{TypedHeader, headers::{authorization::Bearer, Authorization}}; use crate::database::Storage; use kittybox_indieauth::{ Metadata, IntrospectionEndpointAuthMethod, RevocationEndpointAuthMethod, @@ -17,7 +17,6 @@ use kittybox_indieauth::{ TokenIntrospectionRequest, TokenIntrospectionResponse, TokenRevocationRequest, TokenData }; use std::str::FromStr; -use std::ops::Deref; pub mod backend; #[cfg(feature = "webauthn")] @@ -174,7 +173,7 @@ async fn authorization_endpoint_get<A: AuthBackend, D: Storage + 'static>( mf2.items .iter() - .find(|&i| (**i).borrow().r#type.iter() + .find(|&i| i.r#type.iter() .any(|i| { *i == Class::from_str("h-app").unwrap() || *i == Class::from_str("h-x-app").unwrap() @@ -182,7 +181,7 @@ async fn authorization_endpoint_get<A: AuthBackend, D: Storage + 'static>( ) .cloned() .map(|i| { - serde_json::to_value(i.borrow().deref()).unwrap() + serde_json::to_value(&i).unwrap() }) }, Err(err) => { @@ -315,7 +314,7 @@ async fn authorization_endpoint_confirm<A: AuthBackend>( (StatusCode::NO_CONTENT, [("Location", location.as_str())], #[cfg(feature = "webauthn")] - cookies.remove(Cookie::named(webauthn::CHALLENGE_ID_COOKIE)) + cookies.remove(Cookie::from(webauthn::CHALLENGE_ID_COOKIE)) ) .into_response() } diff --git a/src/indieauth/webauthn.rs b/src/indieauth/webauthn.rs index ea3ad3d..b7d8c71 100644 --- a/src/indieauth/webauthn.rs +++ b/src/indieauth/webauthn.rs @@ -1,9 +1,10 @@ use axum::{ extract::{Json, Host}, response::{IntoResponse, Response}, - http::StatusCode, Extension, TypedHeader, headers::{authorization::Bearer, Authorization} + http::StatusCode, Extension }; use axum_extra::extract::cookie::{CookieJar, Cookie}; +use axum_extra::{TypedHeader, headers::{authorization::Bearer, Authorization}}; use super::backend::AuthBackend; use crate::database::Storage; @@ -66,7 +67,7 @@ pub async fn webauthn_pre_register<A: AuthBackend, D: Storage + 'static>( match auth.persist_registration_challenge(&uid_url, state).await { Ok(challenge_id) => ( cookies.add( - Cookie::build(CHALLENGE_ID_COOKIE, challenge_id) + Cookie::build((CHALLENGE_ID_COOKIE, challenge_id)) .secure(true) .finish() ), diff --git a/src/lib.rs b/src/lib.rs index 2d15423..495591d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,10 +7,10 @@ use axum::extract::FromRef; use axum_extra::extract::cookie::Key; use database::{FileStorage, PostgresStorage, Storage}; use indieauth::backend::{AuthBackend, FileBackend as FileAuthBackend}; -use kittybox_util::queue::{JobItem, JobQueue}; +use kittybox_util::queue::JobQueue; use media::storage::{MediaStore, file::FileStore as FileMediaStore}; use tokio::{sync::Mutex, task::JoinSet}; -use webmentions::queue::{PostgresJobItem, PostgresJobQueue}; +use webmentions::queue::PostgresJobQueue; /// Database abstraction layer for Kittybox, allowing the CMS to work with any kind of database. pub mod database; diff --git a/src/main.rs b/src/main.rs index 4af8a81..f683c38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use base64::Engine; use kittybox::{database::Storage, indieauth::backend::AuthBackend, media::storage::MediaStore, webmentions::Webmention, compose_kittybox}; use tokio::{sync::Mutex, task::JoinSet}; -use std::{env, time::Duration, sync::Arc}; +use std::{env, future::IntoFuture, sync::Arc}; use tracing::error; @@ -208,7 +208,7 @@ async fn main() { } }; - let mut servers: Vec<hyper::server::Server<hyper::server::conn::AddrIncoming, _>> = vec![]; + let mut servers: Vec<axum::serve::Serve<_, _>> = vec![]; let build_hyper = |tcp: std::net::TcpListener| { tracing::info!("Listening on {}", tcp.local_addr().unwrap()); @@ -216,10 +216,14 @@ async fn main() { // properly -- this is the async magic! tcp.set_nonblocking(true).unwrap(); - hyper::server::Server::from_tcp(tcp).unwrap() - // Otherwise Chrome keeps connections open for too long - .tcp_keepalive(Some(Duration::from_secs(30 * 60))) - .serve(router.clone().into_make_service()) + //hyper::server::Server::from_tcp(tcp).unwrap() + // // Otherwise Chrome keeps connections open for too long + // .tcp_keepalive(Some(Duration::from_secs(30 * 60))) + // .serve(router.clone().into_make_service()) + axum::serve( + tokio::net::TcpListener::from_std(tcp).unwrap(), + router.clone() + ) }; let mut listenfd = listenfd::ListenFd::from_env(); @@ -286,19 +290,20 @@ async fn main() { .map( #[cfg(not(tokio_unstable))] |server| tokio::task::spawn( server.with_graceful_shutdown(cancellation_token.clone().cancelled_owned()) + .into_future() ), #[cfg(tokio_unstable)] |server| { tokio::task::Builder::new() - .name(format!("Kittybox HTTP acceptor: {}", server.local_addr()).as_str()) + .name(format!("Kittybox HTTP acceptor: {:?}", server).as_str()) .spawn( server.with_graceful_shutdown( cancellation_token.clone().cancelled_owned() - ) + ).into_future() ) .unwrap() } ) - .collect::<futures_util::stream::FuturesUnordered<tokio::task::JoinHandle<Result<(), hyper::Error>>>>() + .collect::<futures_util::stream::FuturesUnordered<tokio::task::JoinHandle<Result<(), std::io::Error>>>>() ); #[cfg(not(unix))] diff --git a/src/media/mod.rs b/src/media/mod.rs index 47f456a..7884ef8 100644 --- a/src/media/mod.rs +++ b/src/media/mod.rs @@ -1,6 +1,8 @@ use axum::{ - extract::{multipart::Multipart, FromRef, Host, Path, State}, headers::{HeaderMapExt, HeaderValue, IfNoneMatch}, response::{IntoResponse, Response}, TypedHeader + extract::{multipart::Multipart, FromRef, Host, Path, State}, response::{IntoResponse, Response} }; +use axum_extra::headers::{HeaderMapExt, HeaderValue, IfNoneMatch}; +use axum_extra::TypedHeader; use kittybox_util::error::{MicropubError, ErrorType}; use kittybox_indieauth::Scope; use crate::indieauth::{backend::AuthBackend, User}; @@ -74,7 +76,7 @@ pub(crate) async fn serve<S: MediaStore>( tracing::debug!("Metadata: {:?}", metadata); let etag = if let Some(etag) = metadata.etag { - let etag = format!("\"{}\"", etag).parse::<axum::headers::ETag>().unwrap(); + let etag = format!("\"{}\"", etag).parse::<axum_extra::headers::ETag>().unwrap(); if let Some(TypedHeader(if_none_match)) = if_none_match { tracing::debug!("If-None-Match: {:?}", if_none_match); @@ -110,7 +112,7 @@ pub(crate) async fn serve<S: MediaStore>( headers.typed_insert(etag); } } - r.body(axum::body::StreamBody::new(stream)) + r.body(axum::body::Body::from_stream(stream)) .unwrap() .into_response() }, diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs index fc5dd10..63b81c5 100644 --- a/src/micropub/mod.rs +++ b/src/micropub/mod.rs @@ -5,12 +5,12 @@ use std::sync::Arc; use crate::database::{MicropubChannel, Storage, StorageError}; use crate::indieauth::backend::AuthBackend; use crate::indieauth::User; -use crate::media::storage::MediaStore; use crate::micropub::util::form_to_mf2_json; -use axum::extract::{BodyStream, FromRef, Host, Query, State}; -use axum::headers::ContentType; +use axum::extract::{FromRef, Host, Query, State}; +use axum::body::Body as BodyStream; +use axum_extra::headers::ContentType; use axum::response::{IntoResponse, Response}; -use axum::TypedHeader; +use axum_extra::TypedHeader; use axum::http::StatusCode; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -136,10 +136,10 @@ async fn background_processing<D: 'static + Storage>( // TODO parse link headers let links = response .headers() - .get_all(hyper::http::header::LINK) + .get_all(reqwest::header::LINK) .iter() .cloned() - .collect::<Vec<hyper::http::HeaderValue>>(); + .collect::<Vec<reqwest::header::HeaderValue>>(); let html = response.text().await; if html.is_err() { return None; @@ -330,9 +330,9 @@ pub(crate) async fn _post<D: 'static + Storage>( IntoResponse::into_response((StatusCode::ACCEPTED, [("Location", uid.as_str())])); #[cfg(not(tokio_unstable))] - jobset.lock().await.spawn(background_processing(db, mf2, http)); + let _ = jobset.lock().await.spawn(background_processing(db, mf2, http)); #[cfg(tokio_unstable)] - jobset.lock().await.build_task() + let _ = jobset.lock().await.build_task() .name(format!("Kittybox background processing for post {}", uid.as_str()).as_str()) .spawn(background_processing(db, mf2, http)); @@ -459,7 +459,7 @@ enum PostBody { #[tracing::instrument] async fn dispatch_body( - mut body: BodyStream, + body: BodyStream, content_type: ContentType, ) -> Result<PostBody, MicropubError> { let body: Vec<u8> = { @@ -467,6 +467,7 @@ async fn dispatch_body( use tokio_stream::StreamExt; let mut buf = Vec::default(); + let mut body = body.into_data_stream(); while let Some(chunk) = body.next().await { buf.extend_from_slice(&chunk.unwrap()) } @@ -673,7 +674,7 @@ where { axum::routing::get(query::<S, A>) .post(post::<S, A>) - .layer::<_, _, std::convert::Infallible>(tower_http::cors::CorsLayer::new() + .layer::<_, _>(tower_http::cors::CorsLayer::new() .allow_methods([ axum::http::Method::GET, axum::http::Method::POST, @@ -704,7 +705,8 @@ mod tests { use std::sync::Arc; use crate::{database::Storage, micropub::MicropubError}; - use hyper::body::HttpBody; + use bytes::Bytes; + use futures::StreamExt; use serde_json::json; use tokio::sync::Mutex; @@ -861,7 +863,15 @@ mod tests { .await; assert_eq!(res.status(), 401); - let body = res.body_mut().data().await.unwrap().unwrap(); + let body = res + .into_body() + .into_data_stream() + .collect::<Vec<Result<Bytes, axum::Error>>>() + .await + .into_iter() + .map(Result::unwrap) + .by_ref() + .fold(Vec::new(), |mut a, i| { a.extend(i); a}); let json: MicropubError = serde_json::from_slice(&body as &[u8]).unwrap(); assert_eq!(json.error, super::ErrorType::NotAuthorized); } diff --git a/src/webmentions/check.rs b/src/webmentions/check.rs index 6dc6a25..178c008 100644 --- a/src/webmentions/check.rs +++ b/src/webmentions/check.rs @@ -1,7 +1,11 @@ -use std::{cell::RefCell, rc::Rc}; -use microformats::{types::PropertyValue, html5ever::{self, tendril::TendrilSink}}; +use std::rc::Rc; +use microformats::types::PropertyValue; +use html5ever::{self, tendril::TendrilSink}; use kittybox_util::MentionType; +// TODO: replace. +mod rcdom; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error("microformats error: {0}")] @@ -19,19 +23,16 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url let document = microformats::from_html(document.as_ref(), base_url.clone())?; // Get an iterator of all items - let items_iter = document.items.iter() - .map(AsRef::as_ref) - .map(RefCell::borrow); + let items_iter = document.items.iter(); for item in items_iter { tracing::debug!("Processing item: {:?}", item); - let props = item.properties.borrow(); for (prop, interaction_type) in [ ("in-reply-to", MentionType::Reply), ("like-of", MentionType::Like), ("bookmark-of", MentionType::Bookmark), ("repost-of", MentionType::Repost) ] { - if let Some(propvals) = props.get(prop) { + if let Some(propvals) = item.properties.get(prop) { tracing::debug!("Has a u-{} property", prop); for val in propvals { if let PropertyValue::Url(url) = val { @@ -45,13 +46,13 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url } // Process `content` tracing::debug!("Processing e-content..."); - if let Some(PropertyValue::Fragment(content)) = props.get("content") + if let Some(PropertyValue::Fragment(content)) = item.properties.get("content") .map(Vec::as_slice) .unwrap_or_default() .first() { tracing::debug!("Parsing HTML data..."); - let root = html5ever::parse_document(html5ever::rcdom::RcDom::default(), Default::default()) + let root = html5ever::parse_document(rcdom::RcDom::default(), Default::default()) .from_utf8() .one(content.html.to_owned().as_bytes()) .document; @@ -64,7 +65,7 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url // iteration of the loop. // // Empty list means all nodes were processed. - let mut unprocessed_nodes: Vec<Rc<html5ever::rcdom::Node>> = root.children.borrow().iter().cloned().collect(); + let mut unprocessed_nodes: Vec<Rc<rcdom::Node>> = root.children.borrow().iter().cloned().collect(); while !unprocessed_nodes.is_empty() { // "Take" the list out of its memory slot, replace it with an empty list let nodes = std::mem::take(&mut unprocessed_nodes); @@ -73,7 +74,7 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url // Add children nodes to the list for the next iteration unprocessed_nodes.extend(node.children.borrow().iter().cloned()); - if let html5ever::rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data { + if let rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data { // If it's not `<a>`, skip it if name.local != *"a" { continue; } let mut is_mention: bool = false; diff --git a/src/webmentions/check/rcdom.rs b/src/webmentions/check/rcdom.rs new file mode 100644 index 0000000..549610f --- /dev/null +++ b/src/webmentions/check/rcdom.rs @@ -0,0 +1,515 @@ +// Copyright 2014-2017 The html5ever Project Developers. +// Copyright Michael Howell and others. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(missing_docs)] + +//! A simple reference-counted DOM. +//! +//! This is sufficient as a static parse tree, but don't build a +//! web browser using it. :) +//! +//! A DOM is a [tree structure] with ordered children that can be represented in an XML-like +//! format. For example, the following graph +//! +//! ```text +//! div +//! +- "text node" +//! +- span +//! ``` +//! in HTML would be serialized as +//! +//! ```html +//! <div>text node<span></span></div> +//! ``` +//! +//! See the [document object model article on wikipedia][dom wiki] for more information. +//! +//! This implementation stores the information associated with each node once, and then hands out +//! refs to children. The nodes themselves are reference-counted to avoid copying - you can create +//! a new ref and then a node will outlive the document. Nodes own their children, but only have +//! weak references to their parents. +//! +//! [tree structure]: https://en.wikipedia.org/wiki/Tree_(data_structure) +//! [dom wiki]: https://en.wikipedia.org/wiki/Document_Object_Model + +use std::borrow::Cow; +use std::cell::{Cell, RefCell}; +use std::collections::{HashSet, VecDeque}; +use std::default::Default; +use std::fmt; +use std::io; +use std::mem; +use std::rc::{Rc, Weak}; + +use html5ever::tendril::StrTendril; + +use html5ever::interface::tree_builder; +use html5ever::interface::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink}; +use html5ever::serialize::TraversalScope; +use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; +use html5ever::serialize::{Serialize, Serializer}; +use html5ever::Attribute; +use html5ever::ExpandedName; +use html5ever::QualName; + +/// The different kinds of nodes in the DOM. +#[derive(Debug)] +pub enum NodeData { + /// The `Document` itself - the root node of a HTML document. + Document, + + /// A `DOCTYPE` with name, public id, and system id. See + /// [document type declaration on wikipedia][dtd wiki]. + /// + /// [dtd wiki]: https://en.wikipedia.org/wiki/Document_type_declaration + Doctype { + name: StrTendril, + public_id: StrTendril, + system_id: StrTendril, + }, + + /// A text node. + Text { contents: RefCell<StrTendril> }, + + /// A comment. + Comment { contents: StrTendril }, + + /// An element with attributes. + Element { + name: QualName, + attrs: RefCell<Vec<Attribute>>, + + /// For HTML \<template\> elements, the [template contents]. + /// + /// [template contents]: https://html.spec.whatwg.org/multipage/#template-contents + template_contents: RefCell<Option<Handle>>, + + /// Whether the node is a [HTML integration point]. + /// + /// [HTML integration point]: https://html.spec.whatwg.org/multipage/#html-integration-point + mathml_annotation_xml_integration_point: bool, + }, + + /// A Processing instruction. + ProcessingInstruction { + target: StrTendril, + contents: StrTendril, + }, +} + +/// A DOM node. +pub struct Node { + /// Parent node. + pub parent: Cell<Option<WeakHandle>>, + /// Child nodes of this node. + pub children: RefCell<Vec<Handle>>, + /// Represents this node's data. + pub data: NodeData, +} + +impl Node { + /// Create a new node from its contents + pub fn new(data: NodeData) -> Rc<Self> { + Rc::new(Node { + data, + parent: Cell::new(None), + children: RefCell::new(Vec::new()), + }) + } +} + +impl Drop for Node { + fn drop(&mut self) { + let mut nodes = mem::take(&mut *self.children.borrow_mut()); + while let Some(node) = nodes.pop() { + let children = mem::take(&mut *node.children.borrow_mut()); + nodes.extend(children.into_iter()); + if let NodeData::Element { + ref template_contents, + .. + } = node.data + { + if let Some(template_contents) = template_contents.borrow_mut().take() { + nodes.push(template_contents); + } + } + } + } +} + +impl fmt::Debug for Node { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("Node") + .field("data", &self.data) + .field("children", &self.children) + .finish() + } +} + +/// Reference to a DOM node. +pub type Handle = Rc<Node>; + +/// Weak reference to a DOM node, used for parent pointers. +pub type WeakHandle = Weak<Node>; + +/// Append a parentless node to another nodes' children +fn append(new_parent: &Handle, child: Handle) { + let previous_parent = child.parent.replace(Some(Rc::downgrade(new_parent))); + // Invariant: child cannot have existing parent + assert!(previous_parent.is_none()); + new_parent.children.borrow_mut().push(child); +} + +/// If the node has a parent, get it and this node's position in its children +fn get_parent_and_index(target: &Handle) -> Option<(Handle, usize)> { + if let Some(weak) = target.parent.take() { + let parent = weak.upgrade().expect("dangling weak pointer"); + target.parent.set(Some(weak)); + let i = match parent + .children + .borrow() + .iter() + .enumerate() + .find(|&(_, child)| Rc::ptr_eq(child, target)) + { + Some((i, _)) => i, + None => panic!("have parent but couldn't find in parent's children!"), + }; + Some((parent, i)) + } else { + None + } +} + +fn append_to_existing_text(prev: &Handle, text: &str) -> bool { + match prev.data { + NodeData::Text { ref contents } => { + contents.borrow_mut().push_slice(text); + true + } + _ => false, + } +} + +fn remove_from_parent(target: &Handle) { + if let Some((parent, i)) = get_parent_and_index(target) { + parent.children.borrow_mut().remove(i); + target.parent.set(None); + } +} + +/// The DOM itself; the result of parsing. +pub struct RcDom { + /// The `Document` itself. + pub document: Handle, + + /// Errors that occurred during parsing. + pub errors: Vec<Cow<'static, str>>, + + /// The document's quirks mode. + pub quirks_mode: QuirksMode, +} + +impl TreeSink for RcDom { + type Output = Self; + fn finish(self) -> Self { + self + } + + type Handle = Handle; + + fn parse_error(&mut self, msg: Cow<'static, str>) { + self.errors.push(msg); + } + + fn get_document(&mut self) -> Handle { + self.document.clone() + } + + fn get_template_contents(&mut self, target: &Handle) -> Handle { + if let NodeData::Element { + ref template_contents, + .. + } = target.data + { + template_contents + .borrow() + .as_ref() + .expect("not a template element!") + .clone() + } else { + panic!("not a template element!") + } + } + + fn set_quirks_mode(&mut self, mode: QuirksMode) { + self.quirks_mode = mode; + } + + fn same_node(&self, x: &Handle, y: &Handle) -> bool { + Rc::ptr_eq(x, y) + } + + fn elem_name<'a>(&self, target: &'a Handle) -> ExpandedName<'a> { + return match target.data { + NodeData::Element { ref name, .. } => name.expanded(), + _ => panic!("not an element!"), + }; + } + + fn create_element( + &mut self, + name: QualName, + attrs: Vec<Attribute>, + flags: ElementFlags, + ) -> Handle { + Node::new(NodeData::Element { + name, + attrs: RefCell::new(attrs), + template_contents: RefCell::new(if flags.template { + Some(Node::new(NodeData::Document)) + } else { + None + }), + mathml_annotation_xml_integration_point: flags.mathml_annotation_xml_integration_point, + }) + } + + fn create_comment(&mut self, text: StrTendril) -> Handle { + Node::new(NodeData::Comment { contents: text }) + } + + fn create_pi(&mut self, target: StrTendril, data: StrTendril) -> Handle { + Node::new(NodeData::ProcessingInstruction { + target, + contents: data, + }) + } + + fn append(&mut self, parent: &Handle, child: NodeOrText<Handle>) { + // Append to an existing Text node if we have one. + if let NodeOrText::AppendText(ref text) = child { + if let Some(h) = parent.children.borrow().last() { + if append_to_existing_text(h, text) { + return; + } + } + } + + append( + parent, + match child { + NodeOrText::AppendText(text) => Node::new(NodeData::Text { + contents: RefCell::new(text), + }), + NodeOrText::AppendNode(node) => node, + }, + ); + } + + fn append_before_sibling(&mut self, sibling: &Handle, child: NodeOrText<Handle>) { + let (parent, i) = get_parent_and_index(sibling) + .expect("append_before_sibling called on node without parent"); + + let child = match (child, i) { + // No previous node. + (NodeOrText::AppendText(text), 0) => Node::new(NodeData::Text { + contents: RefCell::new(text), + }), + + // Look for a text node before the insertion point. + (NodeOrText::AppendText(text), i) => { + let children = parent.children.borrow(); + let prev = &children[i - 1]; + if append_to_existing_text(prev, &text) { + return; + } + Node::new(NodeData::Text { + contents: RefCell::new(text), + }) + } + + // The tree builder promises we won't have a text node after + // the insertion point. + + // Any other kind of node. + (NodeOrText::AppendNode(node), _) => node, + }; + + remove_from_parent(&child); + + child.parent.set(Some(Rc::downgrade(&parent))); + parent.children.borrow_mut().insert(i, child); + } + + fn append_based_on_parent_node( + &mut self, + element: &Self::Handle, + prev_element: &Self::Handle, + child: NodeOrText<Self::Handle>, + ) { + let parent = element.parent.take(); + let has_parent = parent.is_some(); + element.parent.set(parent); + + if has_parent { + self.append_before_sibling(element, child); + } else { + self.append(prev_element, child); + } + } + + fn append_doctype_to_document( + &mut self, + name: StrTendril, + public_id: StrTendril, + system_id: StrTendril, + ) { + append( + &self.document, + Node::new(NodeData::Doctype { + name, + public_id, + system_id, + }), + ); + } + + fn add_attrs_if_missing(&mut self, target: &Handle, attrs: Vec<Attribute>) { + let mut existing = if let NodeData::Element { ref attrs, .. } = target.data { + attrs.borrow_mut() + } else { + panic!("not an element") + }; + + let existing_names = existing + .iter() + .map(|e| e.name.clone()) + .collect::<HashSet<_>>(); + existing.extend( + attrs + .into_iter() + .filter(|attr| !existing_names.contains(&attr.name)), + ); + } + + fn remove_from_parent(&mut self, target: &Handle) { + remove_from_parent(target); + } + + fn reparent_children(&mut self, node: &Handle, new_parent: &Handle) { + let mut children = node.children.borrow_mut(); + let mut new_children = new_parent.children.borrow_mut(); + for child in children.iter() { + let previous_parent = child.parent.replace(Some(Rc::downgrade(new_parent))); + assert!(Rc::ptr_eq( + node, + &previous_parent.unwrap().upgrade().expect("dangling weak") + )) + } + new_children.extend(mem::take(&mut *children)); + } + + fn is_mathml_annotation_xml_integration_point(&self, target: &Handle) -> bool { + if let NodeData::Element { + mathml_annotation_xml_integration_point, + .. + } = target.data + { + mathml_annotation_xml_integration_point + } else { + panic!("not an element!") + } + } +} + +impl Default for RcDom { + fn default() -> RcDom { + RcDom { + document: Node::new(NodeData::Document), + errors: vec![], + quirks_mode: tree_builder::NoQuirks, + } + } +} + +enum SerializeOp { + Open(Handle), + Close(QualName), +} + +pub struct SerializableHandle(Handle); + +impl From<Handle> for SerializableHandle { + fn from(h: Handle) -> SerializableHandle { + SerializableHandle(h) + } +} + +impl Serialize for SerializableHandle { + fn serialize<S>(&self, serializer: &mut S, traversal_scope: TraversalScope) -> io::Result<()> + where + S: Serializer, + { + let mut ops = VecDeque::new(); + match traversal_scope { + IncludeNode => ops.push_back(SerializeOp::Open(self.0.clone())), + ChildrenOnly(_) => ops.extend( + self.0 + .children + .borrow() + .iter() + .map(|h| SerializeOp::Open(h.clone())), + ), + } + + while let Some(op) = ops.pop_front() { + match op { + SerializeOp::Open(handle) => match handle.data { + NodeData::Element { + ref name, + ref attrs, + .. + } => { + serializer.start_elem( + name.clone(), + attrs.borrow().iter().map(|at| (&at.name, &at.value[..])), + )?; + + ops.reserve(1 + handle.children.borrow().len()); + ops.push_front(SerializeOp::Close(name.clone())); + + for child in handle.children.borrow().iter().rev() { + ops.push_front(SerializeOp::Open(child.clone())); + } + } + + NodeData::Doctype { ref name, .. } => serializer.write_doctype(name)?, + + NodeData::Text { ref contents } => serializer.write_text(&contents.borrow())?, + + NodeData::Comment { ref contents } => serializer.write_comment(contents)?, + + NodeData::ProcessingInstruction { + ref target, + ref contents, + } => serializer.write_processing_instruction(target, contents)?, + + NodeData::Document => panic!("Can't serialize Document node itself"), + }, + + SerializeOp::Close(name) => { + serializer.end_elem(name)?; + } + } + } + + Ok(()) + } +} diff --git a/templates-neo/Cargo.toml b/templates-neo/Cargo.toml index 98e70a7..ed88873 100644 --- a/templates-neo/Cargo.toml +++ b/templates-neo/Cargo.toml @@ -15,16 +15,19 @@ rand = "^0.8.5" [dependencies] ellipse = "^0.2.0" -http = "^0.2.7" +http = "^1.0" html = "^0.6.0" serde_json = "^1.0.64" include_dir = "^0.7.2" -axum = "^0.6.18" +axum = "^0.7.5" thiserror = "1.0.43" [dependencies.url] # URL library for Rust, based on the WHATWG URL Standard version = "^2.2.1" features = ["serde"] +[dependencies.time] +version = "^0.3.34" +features = ["formatting"] [dependencies.chrono] version = "^0.4.19" features = ["serde"] @@ -35,4 +38,4 @@ path = "../util" version = "0.2.0" path = "../indieauth" [dependencies.microformats] -version="^0.3.0" \ No newline at end of file +version="^0.9.1" \ No newline at end of file diff --git a/templates-neo/src/mf2.rs b/templates-neo/src/mf2.rs index 8190720..3cf453f 100644 --- a/templates-neo/src/mf2.rs +++ b/templates-neo/src/mf2.rs @@ -64,7 +64,7 @@ impl TryFrom<Item> for Card { }); } - let mut props = card.properties.take(); + let mut props = card.properties; let uid = { let uids = props.remove("uid").ok_or(Error::NoUid)?; if let Some(PropertyValue::Url(uid)) = uids.into_iter().take(1).next() { @@ -106,12 +106,12 @@ impl TryFrom<Item> for Card { .unwrap_or_default() .into_iter() .next() - .and_then(|v| match v { - PropertyValue::Plain(plain) => Some(Ok(plain)), - other => Some(Err(Error::WrongValueType { + .map(|v| match v { + PropertyValue::Plain(plain) => Ok(plain), + other => Err(Error::WrongValueType { expected: "string", got: other, - })), + }), }) .transpose()?, photo: props @@ -122,10 +122,13 @@ impl TryFrom<Item> for Card { .ok_or(Error::MissingProperty("photo")) .and_then(|v| match v { PropertyValue::Url(url) => Ok(Image::Plain(url)), - PropertyValue::Image(image) => Ok(Image::Accessible { - src: image.src, - alt: image.alt, - }), + PropertyValue::Image(image) => match image.alt { + Some(alt) => Ok(Image::Accessible { + src: image.value, + alt, + }), + None => Ok(Image::Plain(image.value)) + }, other => Err(Error::WrongValueType { expected: "string", got: other, @@ -198,7 +201,7 @@ impl Card { for url in urls { let url = String::from(url); ul.list_item(move |li| { - li.push({ Anchor::builder().href(url.clone()).text(url).build() }) + li.push(Anchor::builder().href(url.clone()).text(url).build()) }); } @@ -215,7 +218,7 @@ impl TryFrom<PropertyValue> for Card { fn try_from(v: PropertyValue) -> Result<Self, Self::Error> { match v { - PropertyValue::Item(item) => item.take().try_into(), + PropertyValue::Item(item) => item.try_into(), other => Err(Error::WrongValueType { expected: "h-card", got: other, @@ -229,7 +232,7 @@ pub struct Cite { url: Vec<url::Url>, in_reply_to: Option<Vec<Citation>>, author: Card, - published: Option<chrono::DateTime<chrono::FixedOffset>>, + published: Option<time::OffsetDateTime>, content: Content, } @@ -258,7 +261,7 @@ impl TryFrom<PropertyValue> for Citation { fn try_from(v: PropertyValue) -> Result<Self, Self::Error> { match v { PropertyValue::Url(url) => Ok(Self::Brief(url)), - PropertyValue::Item(item) => Ok(Self::Full(item.take().try_into()?)), + PropertyValue::Item(item) => Ok(Self::Full(item.try_into()?)), other => Err(Error::WrongValueType { expected: "url or h-cite", got: other, @@ -287,7 +290,7 @@ pub struct Entry { author: Card, category: Vec<String>, syndication: Vec<url::Url>, - published: chrono::DateTime<chrono::FixedOffset>, + published: time::OffsetDateTime, content: Content, } @@ -301,7 +304,7 @@ impl TryFrom<Item> for Entry { }); } - let mut props = entry.properties.take(); + let mut props = entry.properties; let uid = { let uids = props.remove("uid").ok_or(Error::NoUid)?; if let Some(PropertyValue::Url(uid)) = uids.into_iter().take(1).next() { @@ -369,23 +372,26 @@ impl TryFrom<Item> for Entry { .into_iter() .next() .map( - |v| -> Result<chrono::DateTime<chrono::FixedOffset>, Error> { + |v| -> Result<time::OffsetDateTime, Error> { match v { - PropertyValue::Temporal(Temporal::Timestamp(dt)) => { + PropertyValue::Temporal(Temporal::Timestamp(ref dt)) => { // This is incredibly sketchy. let (date, time, offset) = ( - dt.date.clone().unwrap().data, - dt.as_time().unwrap().data.clone(), - dt.as_time().unwrap().offset.unwrap().data, + dt.date.to_owned().ok_or_else(|| Error::WrongValueType { + expected: "timestamp (date, time, offset)", + got: v.clone() + })?.data, + dt.time.to_owned().ok_or_else(|| Error::WrongValueType { + expected: "timestamp (date, time, offset)", + got: v.clone() + })?.data, + dt.offset.to_owned().ok_or_else(|| Error::WrongValueType { + expected: "timestamp (date, time, offset)", + got: v.clone() + })?.data, ); - date.and_time(time) - .and_local_timezone(offset) - .single() - .ok_or_else(|| Error::WrongValueType { - expected: "datetime with timezone", - got: PropertyValue::Temporal(Temporal::Timestamp(dt)), - }) + Ok(date.with_time(time).assume_offset(offset)) } other => Err(Error::WrongValueType { expected: "timestamp", @@ -428,13 +434,10 @@ impl Entry { html::inline_text::Time::builder() .text( self.published - .format("%Y-%m-%d %a %H:%M:%S %z") - .to_string(), + .format(&time::format_description::well_known::Rfc2822) + .unwrap() ) - .date_time(self.published.to_rfc3339_opts( - chrono::SecondsFormat::Secs, - false, - )) + .date_time(self.published.format(&time::format_description::well_known::Rfc3339).unwrap()) .build(), ) }) diff --git a/templates/Cargo.toml b/templates/Cargo.toml index 9be5f30..6209e76 100644 --- a/templates/Cargo.toml +++ b/templates/Cargo.toml @@ -12,16 +12,19 @@ walkdir = "^2.3.2" [dev-dependencies] faker_rand = "^0.1.1" rand = "^0.8.5" +[dev-dependencies.time] +version = "^0.3.34" +features = ["parsing", "formatting"] [dev-dependencies.microformats] -version="^0.3.0" +version="^0.9.1" [dependencies] ellipse = "^0.2.0" -http = "^0.2.7" -markup = "^0.13.1" +http = "^1.0" +markup = "^0.15.0" serde_json = "^1.0.64" include_dir = "^0.7.2" -axum = "^0.6.18" +axum = "^0.7.5" [dependencies.chrono] version = "^0.4.19" features = ["serde"] diff --git a/templates/src/lib.rs b/templates/src/lib.rs index dd263e9..b7b9a24 100644 --- a/templates/src/lib.rs +++ b/templates/src/lib.rs @@ -56,9 +56,8 @@ mod tests { use faker_rand::en_us::internet::Domain; use faker_rand::lorem::Word; use microformats::types::{Document, Item, PropertyValue, Url}; + use rand::distributions::Distribution; use serde_json::json; - use std::cell::RefCell; - use std::rc::Rc; enum PostType { Note, @@ -99,7 +98,17 @@ mod tests { rand::random::<Word>(), rand::random::<Word>() ); - let dt = chrono::offset::Local::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true); + let dt = time::OffsetDateTime::now_utc() + .to_offset( + time::UtcOffset::from_hms( + rand::distributions::Uniform::new(-11, 12) + .sample(&mut rand::thread_rng()), + if rand::random::<bool>() { 0 } else { 30 }, + 0 + ).unwrap() + ) + .format(&time::format_description::well_known::Rfc3339) + .unwrap(); match kind { PostType::Note => { @@ -189,46 +198,38 @@ mod tests { } } - fn check_dt_published(mf2: &serde_json::Value, item: &Rc<RefCell<Item>>) { + fn check_dt_published(mf2: &serde_json::Value, item: &Item) { use microformats::types::temporal::Value as TemporalValue; - let _item = item.borrow(); - let props = _item.properties.borrow(); - assert!(props.contains_key("published")); + assert!(item.properties.contains_key("published")); if let Some(PropertyValue::Temporal(TemporalValue::Timestamp(item))) = - props.get("published").and_then(|v| v.first()) + item.properties.get("published").and_then(|v| v.first()) { - use chrono::{DateTime, FixedOffset, NaiveDateTime}; - // Faithfully reconstruct the original datetime // I wonder why not just have an Enum that would // get you either date, time or a datetime, // potentially with an offset? let offset = item.as_offset().unwrap().data; - let ndt: NaiveDateTime = item.as_date().unwrap().data - .and_time(item.as_time().unwrap().data) - // subtract the offset here, since we will add it back - - offset; - let dt = DateTime::<FixedOffset>::from_utc(ndt, offset); + let date = item.as_date().unwrap().data; + let time = item.as_time().unwrap().data; - let expected: DateTime<FixedOffset> = chrono::DateTime::parse_from_rfc3339( + let dt = date.with_time(time).assume_offset(offset); + let expected = time::OffsetDateTime::parse( mf2["properties"]["published"][0].as_str().unwrap(), - ) - .unwrap(); - + &time::format_description::well_known::Rfc3339 + ).unwrap(); + assert_eq!(dt, expected); } else { unreachable!() } } - fn check_e_content(mf2: &serde_json::Value, item: &Rc<RefCell<Item>>) { - let _item = item.borrow(); - let props = _item.properties.borrow(); - assert!(props.contains_key("content")); + fn check_e_content(mf2: &serde_json::Value, item: &Item) { + assert!(item.properties.contains_key("content")); - if let Some(PropertyValue::Fragment(content)) = props.get("content").and_then(|v| v.first()) + if let Some(PropertyValue::Fragment(content)) = item.properties.get("content").and_then(|v| v.first()) { assert_eq!( content.html, @@ -240,7 +241,6 @@ mod tests { } #[test] - #[ignore = "see https://gitlab.com/maxburon/microformats-parser/-/issues/7"] fn test_note() { let mf2 = gen_random_post(&rand::random::<Domain>().to_string(), PostType::Note); @@ -253,9 +253,8 @@ mod tests { .unwrap(); let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); - if let Some(PropertyValue::Item(item)) = parsed.get_item_by_url(&url) { - let _item = item.borrow(); - let props = _item.properties.borrow(); + if let Some(item) = parsed.into_iter().find(|i| i.properties.get("url").unwrap().contains(&PropertyValue::Url(url.clone()))) { + let props = &item.properties; check_e_content(&mf2, &item); check_dt_published(&mf2, &item); @@ -284,21 +283,20 @@ mod tests { .unwrap(); let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); - if let Some(PropertyValue::Item(item)) = parsed.get_item_by_url(&url) { - let _item = item.borrow(); - let props = _item.properties.borrow(); + if let Some(item) = parsed.into_iter().find(|i| i.properties.get("url").unwrap().contains(&PropertyValue::Url(url.clone()))) { check_e_content(&mf2, &item); check_dt_published(&mf2, &item); - assert!(props.contains_key("uid")); - assert!(props.contains_key("url")); - assert!(props + assert!(item.properties.contains_key("uid")); + assert!(item.properties.contains_key("url")); + assert!(item + .properties .get("url") .unwrap() .iter() - .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); - assert!(props.contains_key("name")); - if let Some(PropertyValue::Plain(name)) = props.get("name").and_then(|v| v.first()) { + .any(|i| i == item.properties.get("uid").and_then(|v| v.first()).unwrap())); + assert!(item.properties.contains_key("name")); + if let Some(PropertyValue::Plain(name)) = item.properties.get("name").and_then(|v| v.first()) { assert_eq!( name, mf2.pointer("/properties/name/0") @@ -337,13 +335,10 @@ mod tests { let html = crate::mf2::Entry { post: &mf2 }.to_string(); let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); - if let Some(item) = parsed.items.get(0) { - let _item = item.borrow(); - let props = _item.properties.borrow(); - + if let Some(item) = parsed.items.first() { check_dt_published(&mf2, item); - assert!(props.contains_key("like-of")); - match props.get("like-of").and_then(|v| v.first()) { + assert!(item.properties.contains_key("like-of")); + match item.properties.get("like-of").and_then(|v| v.first()) { Some(PropertyValue::Url(url)) => { assert_eq!( url, diff --git a/util/Cargo.toml b/util/Cargo.toml index 0425849..3d8327c 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -11,8 +11,8 @@ fs = ["rand", "tokio", "tokio/fs"] [dependencies] serde = { version = "^1.0.170", features = ["derive"] } serde_json = "^1.0.64" -axum-core = "^0.3.4" -http = "^0.2.7" +axum-core = "^0.4.3" +http = "^1.0" async-trait = "^0.1.50" futures-util = "^0.3.14" uuid = "^1.3.3" @@ -24,6 +24,6 @@ version = "^1.16.1" features = ["tracing"] optional = true [dependencies.sqlx] -version = "0.7" +version = "0.8" features = ["json"] optional = true \ No newline at end of file |