[[package]]
name = "actix-http"
-version = "3.0.0-beta.8"
+version = "3.0.0-beta.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cd16d6b846983ffabfd081e1a67abd7698094fcbe7b3d9bcf1acbc6f546a516"
+checksum = "01260589f1aafad11224002741eb37bc603b4ce55b4e3556d2b2122f9aac7c51"
dependencies = [
"actix-codec",
"actix-rt",
"actix-service",
"actix-tls",
"actix-utils",
- "ahash 0.7.4",
+ "ahash",
"base64 0.13.0",
"bitflags",
"bytes",
"rand 0.8.4",
"regex",
"serde",
- "sha-1 0.9.6",
+ "sha-1 0.9.7",
"smallvec",
"time 0.2.27",
"tokio",
"actix-tls",
"actix-utils",
"actix-web-codegen",
- "ahash 0.7.4",
+ "ahash",
"bytes",
"cfg-if",
"cookie",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
-[[package]]
-name = "ahash"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
-
[[package]]
name = "ahash"
version = "0.7.4"
"winapi",
]
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
[[package]]
name = "autocfg"
version = "1.0.1"
[[package]]
name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitvec"
[[package]]
name = "bytemuck"
-version = "1.7.0"
+version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9966d2ab714d0f785dbac0a0396251a35280aeb42413281617d0209ab4898435"
+checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b"
[[package]]
name = "byteorder"
[[package]]
name = "cc"
-version = "1.0.68"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
+checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
[[package]]
name = "cfg-if"
"chrono",
]
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+dependencies = [
+ "bitflags",
+]
+
[[package]]
name = "color_quant"
version = "1.1.0"
[[package]]
name = "crossbeam-deque"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
[[package]]
name = "derive_more"
-version = "0.99.14"
+version = "0.99.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320"
+checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df"
dependencies = [
"convert_case",
"proc-macro2 1.0.28",
"quote 1.0.9",
+ "rustc_version 0.3.3",
"syn 1.0.74",
]
[[package]]
name = "fallible_collections"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ad9169582543d2cfe9961be1e9eaf4fc42f9aa3483f7c485717b8dde36466ea"
+checksum = "eaefd4190151d458f16f0793d3452d7f13aeb3701566a4cefc4c37598876cc00"
dependencies = [
- "hashbrown 0.9.1",
+ "hashbrown",
]
[[package]]
name = "fastrand"
-version = "1.4.1"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
+checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e"
dependencies = [
"instant",
]
"percent-encoding",
]
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+
[[package]]
name = "funty"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
+[[package]]
+name = "futf"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
+dependencies = [
+ "mac",
+ "new_debug_unreachable",
+]
+
[[package]]
name = "futures"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"proc-macro-hack",
"proc-macro2 1.0.28",
"quote 1.0.9",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"futures-channel",
"futures-core",
"futures-io",
"tracing",
]
-[[package]]
-name = "hashbrown"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
-dependencies = [
- "ahash 0.4.7",
-]
-
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+dependencies = [
+ "ahash",
+]
[[package]]
name = "heck"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
+[[package]]
+name = "html5ever"
+version = "0.22.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c213fa6a618dc1da552f54f85cba74b05d8e883c92ec4e89067736938084c26e"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "syn 0.15.44",
+]
+
[[package]]
name = "http"
version = "0.2.4"
[[package]]
name = "http-body"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9"
+checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5"
dependencies = [
"bytes",
"http",
[[package]]
name = "hyper"
-version = "0.14.9"
+version = "0.14.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83"
+checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11"
dependencies = [
"bytes",
"futures-channel",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
- "autocfg",
- "hashbrown 0.11.2",
+ "autocfg 1.0.1",
+ "hashbrown",
]
[[package]]
name = "instant"
-version = "0.1.9"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
dependencies = [
"cfg-if",
]
[[package]]
name = "js-sys"
-version = "0.3.51"
+version = "0.3.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
+checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752"
dependencies = [
"wasm-bindgen",
]
"thiserror",
"tokio",
"url",
+ "webpage",
]
[[package]]
[[package]]
name = "libc"
-version = "0.2.97"
+version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
+checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
[[package]]
name = "local-channel"
"cfg-if",
]
+[[package]]
+name = "mac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
+
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+[[package]]
+name = "markup5ever"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897636f9850c3eef4905a5540683ed53dc9393860f0846cab2c2ddf9939862ff"
+dependencies = [
+ "phf",
+ "phf_codegen",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "string_cache",
+ "string_cache_codegen",
+ "tendril",
+]
+
[[package]]
name = "match_cfg"
version = "0.1.0"
[[package]]
name = "matches"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
]
[[package]]
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
- "autocfg",
+ "autocfg 1.0.1",
]
[[package]]
[[package]]
name = "native-tls"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4"
+checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
dependencies = [
"lazy_static",
"libc",
"tempfile",
]
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
+
[[package]]
name = "nom"
version = "6.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"num-integer",
"num-traits",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"num-traits",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"num-integer",
"num-traits",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"num-integer",
"num-traits",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"cc",
"libc",
"pkg-config",
"sha-1 0.8.2",
]
+[[package]]
+name = "phf"
+version = "0.7.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
+dependencies = [
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.7.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.7.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
+dependencies = [
+ "phf_shared",
+ "rand 0.6.5",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.7.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
+dependencies = [
+ "siphasher",
+]
+
[[package]]
name = "pin-project"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
+checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
+checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
dependencies = [
"proc-macro2 1.0.28",
"quote 1.0.9",
"vcpkg",
]
+[[package]]
+name = "precomputed-hash"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
+[[package]]
+name = "rand"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+dependencies = [
+ "autocfg 0.1.7",
+ "libc",
+ "rand_chacha 0.1.1",
+ "rand_core 0.4.2",
+ "rand_hc 0.1.0",
+ "rand_isaac",
+ "rand_jitter",
+ "rand_os",
+ "rand_pcg",
+ "rand_xorshift",
+ "winapi",
+]
+
[[package]]
name = "rand"
version = "0.7.3"
"rand_hc 0.3.1",
]
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+dependencies = [
+ "autocfg 0.1.7",
+ "rand_core 0.3.1",
+]
+
[[package]]
name = "rand_chacha"
version = "0.2.2"
"rand_core 0.6.3",
]
+[[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"
"getrandom 0.2.3",
]
+[[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"
"rand_core 0.6.3",
]
+[[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.7",
+ "rand_core 0.4.2",
+]
+
+[[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 = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"crossbeam-deque",
"either",
"rayon-core",
"num_cpus",
]
+[[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 = "redox_syscall"
-version = "0.2.9"
+version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
+checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
- "semver",
+ "semver 0.9.0",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+dependencies = [
+ "semver 0.11.0",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
- "semver-parser",
+ "semver-parser 0.7.0",
+]
+
+[[package]]
+name = "semver"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser 0.10.2",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+[[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
[[package]]
name = "serde"
version = "1.0.127"
[[package]]
name = "sha-1"
-version = "0.9.6"
+version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
+checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"num-traits",
]
+[[package]]
+name = "siphasher"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
+
[[package]]
name = "slab"
-version = "0.4.3"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
+checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]]
name = "smallvec"
[[package]]
name = "socket2"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
+checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad"
dependencies = [
"libc",
"winapi",
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [
"discard",
- "rustc_version",
+ "rustc_version 0.2.3",
"stdweb-derive",
"stdweb-internal-macros",
"stdweb-internal-runtime",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+[[package]]
+name = "string_cache"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67"
+dependencies = [
+ "lazy_static",
+ "new_debug_unreachable",
+ "phf_shared",
+ "precomputed-hash",
+ "serde",
+ "string_cache_codegen",
+ "string_cache_shared",
+]
+
+[[package]]
+name = "string_cache_codegen"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2 1.0.28",
+ "quote 1.0.9",
+ "string_cache_shared",
+]
+
+[[package]]
+name = "string_cache_shared"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
+
[[package]]
name = "strsim"
version = "0.9.3"
"unicode-xid 0.1.0",
]
+[[package]]
+name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "unicode-xid 0.1.0",
+]
+
[[package]]
name = "syn"
version = "1.0.74"
"winapi",
]
+[[package]]
+name = "tendril"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33"
+dependencies = [
+ "futf",
+ "mac",
+ "utf-8",
+]
+
[[package]]
name = "termcolor"
version = "1.1.2"
[[package]]
name = "tinyvec"
-version = "1.2.0"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
+checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
dependencies = [
"tinyvec_macros",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b"
dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
"bytes",
"libc",
"memchr",
[[package]]
name = "tracing-core"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
+checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8"
dependencies = [
"lazy_static",
]
[[package]]
name = "unicode-bidi"
-version = "0.3.5"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
-dependencies = [
- "matches",
-]
+checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
[[package]]
name = "unicode-normalization"
"serde",
]
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
[[package]]
name = "uuid"
version = "0.8.2"
[[package]]
name = "wasm-bindgen"
-version = "0.2.74"
+version = "0.2.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
+checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586"
dependencies = [
"cfg-if",
"serde",
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.74"
+version = "0.2.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
+checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f"
dependencies = [
"bumpalo",
"lazy_static",
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.24"
+version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
+checksum = "16646b21c3add8e13fdb8f20172f8a28c3dbf62f45406bcff0233188226cfe0c"
dependencies = [
"cfg-if",
"js-sys",
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.74"
+version = "0.2.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
+checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c"
dependencies = [
"quote 1.0.9",
"wasm-bindgen-macro-support",
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.74"
+version = "0.2.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
+checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f"
dependencies = [
"proc-macro2 1.0.28",
"quote 1.0.9",
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.74"
+version = "0.2.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
+checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2"
[[package]]
name = "web-sys"
-version = "0.3.51"
+version = "0.3.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
+checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696"
dependencies = [
"js-sys",
"wasm-bindgen",
]
+[[package]]
+name = "webpage"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1adf8232428a373fe9dc80dc3b7ba15c35621746691869ae2aa4fe0bb6f01098"
+dependencies = [
+ "html5ever",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "webpki"
version = "0.21.4"
- Can transfer site and communities to others.
- Can fully erase your data, replacing all posts and comments.
- NSFW post / community support.
-- OEmbed support via Iframely.
- High performance.
- Server is written in rust.
- Front end is `~80kB` gzipped.
- src: 'templates/nginx.conf'
dest: '/etc/nginx/sites-enabled/lemmy.conf'
mode: '0644'
- - src: '../docker/iframely.config.local.js'
- dest: '{{lemmy_base_dir}}/iframely.config.local.js'
- mode: '0600'
vars:
lemmy_docker_image: "dessalines/lemmy:{{ lookup('file', 'VERSION') }}"
lemmy_docker_ui_image: "dessalines/lemmy-ui:{{ lookup('file', 'VERSION') }}"
lemmy_port: "8536"
lemmy_ui_port: "1235"
pictshare_port: "8537"
- iframely_port: "8538"
- name: add config file (only during initial setup)
template:
- src: 'templates/nginx.conf'
dest: '/etc/nginx/sites-enabled/lemmy.conf'
mode: '0644'
- - src: '../docker/iframely.config.local.js'
- dest: '{{lemmy_base_dir}}/iframely.config.local.js'
- mode: '0600'
vars:
lemmy_docker_image: "dessalines/lemmy:dev"
lemmy_docker_ui_image: "dessalines/lemmy-ui:{{ lookup('file', 'VERSION') }}"
lemmy_port: "8536"
lemmy_ui_port: "1235"
pictshare_port: "8537"
- iframely_port: "8538"
postgres_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/postgres chars=ascii_letters,digits') }}"
- name: add config file (only during initial setup)
depends_on:
- postgres
- pictrs
- - iframely
lemmy-ui:
image: {{ lemmy_docker_ui_image }}
restart: always
mem_limit: 200m
- iframely:
- image: dogbin/iframely:latest
- ports:
- - "127.0.0.1:8061:80"
- volumes:
- - ./iframely.config.local.js:/iframely/config.local.js:ro
- restart: always
- mem_limit: 200m
-
postfix:
image: mwader/postfix-relay
environment:
return 301 /pictrs/image/$1;
}
- location /iframely/ {
- proxy_pass http://0.0.0.0:8061/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
# Anonymize IP addresses
jwt_secret: "changeme"
# address where pictrs is available
pictrs_url: "http://pictrs:8080"
- # address where iframely is available
- iframely_url: "http://iframely"
# maximum length of local community and user names
actor_name_max_length: 20
# rate limits for various user actions, by user ip
UserOperation::ResolvePostReport => {
do_websocket_operation::<ResolvePostReport>(context, id, op, data).await
}
+ UserOperation::GetSiteMetadata => {
+ do_websocket_operation::<GetSiteMetadata>(context, id, op, data).await
+ }
// Comment ops
UserOperation::MarkCommentAsRead => {
use lemmy_db_queries::{source::post::Post_, Crud, Likeable, Saveable};
use lemmy_db_schema::source::{moderator::*, post::*};
use lemmy_db_views::post_view::PostView;
-use lemmy_utils::{ApiError, ConnectionId, LemmyError};
+use lemmy_utils::{request::fetch_site_metadata, ApiError, ConnectionId, LemmyError};
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation};
use std::convert::TryInto;
Ok(PostResponse { post_view })
}
}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for GetSiteMetadata {
+ type Response = GetSiteMetadataResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<GetSiteMetadataResponse, LemmyError> {
+ let data: &Self = self;
+
+ let metadata = fetch_site_metadata(context.client(), &data.url).await?;
+
+ Ok(GetSiteMetadataResponse { metadata })
+ }
+}
community_moderator_view::CommunityModeratorView,
community_view::CommunityView,
};
+use lemmy_utils::request::SiteMetadata;
use serde::{Deserialize, Serialize};
use url::Url;
pub struct ListPostReportsResponse {
pub posts: Vec<PostReportView>,
}
+
+#[derive(Deserialize, Debug)]
+pub struct GetSiteMetadata {
+ pub url: Url,
+}
+
+#[derive(Serialize, Clone, Debug)]
+pub struct GetSiteMetadataResponse {
+ pub metadata: SiteMetadata,
+}
use lemmy_db_queries::{source::post::Post_, Crud, Likeable};
use lemmy_db_schema::source::post::*;
use lemmy_utils::{
- request::fetch_iframely_and_pictrs_data,
+ request::fetch_site_data,
utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title},
ApiError,
ConnectionId,
check_community_ban(local_user_view.person.id, data.community_id, context.pool()).await?;
- // Fetch Iframely and pictrs cached image
+ // Fetch post links and pictrs cached image
let data_url = data.url.as_ref();
- let (iframely_response, pictrs_thumbnail) =
- fetch_iframely_and_pictrs_data(context.client(), data_url).await?;
- let (embed_title, embed_description, embed_html) = iframely_response
+ let (metadata_res, pictrs_thumbnail) = fetch_site_data(context.client(), data_url).await;
+ let (embed_title, embed_description, embed_html) = metadata_res
.map(|u| (u.title, u.description, u.html))
.unwrap_or((None, None, None));
use lemmy_db_queries::{source::post::Post_, Crud};
use lemmy_db_schema::{naive_now, source::post::*};
use lemmy_utils::{
- request::fetch_iframely_and_pictrs_data,
+ request::fetch_site_data,
utils::{check_slurs_opt, clean_url_params, is_valid_post_title},
ApiError,
ConnectionId,
return Err(ApiError::err("no_post_edit_allowed").into());
}
- // Fetch Iframely and Pictrs cached image
+ // Fetch post links and Pictrs cached image
let data_url = data.url.as_ref();
- let (iframely_response, pictrs_thumbnail) =
- fetch_iframely_and_pictrs_data(context.client(), data_url).await?;
- let (embed_title, embed_description, embed_html) = iframely_response
+ let (metadata_res, pictrs_thumbnail) = fetch_site_data(context.client(), data_url).await;
+ let (embed_title, embed_description, embed_html) = metadata_res
.map(|u| (u.title, u.description, u.html))
.unwrap_or((None, None, None));
},
};
use lemmy_utils::{
- request::fetch_iframely_and_pictrs_data,
+ request::fetch_site_data,
utils::{check_slurs, convert_datetime, markdown_to_html, remove_slurs},
LemmyError,
};
let community = extract_community(&page.to, context, request_counter).await?;
let thumbnail_url: Option<Url> = page.image.clone().map(|i| i.url);
- let (iframely_response, pictrs_thumbnail) = if let Some(url) = &page.url {
- fetch_iframely_and_pictrs_data(context.client(), Some(url)).await?
+ let (metadata_res, pictrs_thumbnail) = if let Some(url) = &page.url {
+ fetch_site_data(context.client(), Some(url)).await
} else {
(None, thumbnail_url)
};
- let (embed_title, embed_description, embed_html) = iframely_response
+ let (embed_title, embed_description, embed_html) = metadata_res
.map(|u| (u.title, u.description, u.html))
.unwrap_or((None, None, None));
jsonwebtoken = "7.2.0"
deser-hjson = "1.0.2"
smart-default = "0.6.0"
+webpage = { version = "1.1", default-features = false, features = ["serde"] }
use log::error;
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use reqwest::Client;
-use serde::Deserialize;
+use serde::{Deserialize, Serialize};
use std::future::Future;
use thiserror::Error;
use url::Url;
+use webpage::HTML;
#[derive(Clone, Debug, Error)]
#[error("Error sending request, {0}")]
response.expect("retry http request")
}
-#[derive(Deserialize, Debug)]
-pub struct IframelyResponse {
+#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
+pub struct SiteMetadata {
pub title: Option<String>,
pub description: Option<String>,
- thumbnail_url: Option<Url>,
+ image: Option<Url>,
pub html: Option<String>,
}
-pub(crate) async fn fetch_iframely(
- client: &Client,
- url: &Url,
-) -> Result<IframelyResponse, LemmyError> {
- if let Some(iframely_url) = Settings::get().iframely_url {
- let fetch_url = format!("{}/oembed?url={}", iframely_url, url);
+/// Fetches the post link html tags (like title, description, image, etc)
+pub async fn fetch_site_metadata(client: &Client, url: &Url) -> Result<SiteMetadata, LemmyError> {
+ let response = retry(|| client.get(url.as_str()).send()).await?;
- let response = retry(|| client.get(&fetch_url).send()).await?;
+ let html = response
+ .text()
+ .await
+ .map_err(|e| RecvError(e.to_string()))?;
- let res: IframelyResponse = response
- .json()
- .await
- .map_err(|e| RecvError(e.to_string()))?;
- Ok(res)
- } else {
- Err(anyhow!("Missing Iframely URL in config.").into())
- }
+ let tags = html_to_site_metadata(&html)?;
+
+ Ok(tags)
+}
+
+fn html_to_site_metadata(html: &str) -> Result<SiteMetadata, LemmyError> {
+ let page = HTML::from_string(html.to_string(), None)?;
+
+ let page_title = page.title;
+ let page_description = page.description;
+
+ let og_description = page
+ .opengraph
+ .properties
+ .get("description")
+ .map(|t| t.to_string());
+ let og_title = page
+ .opengraph
+ .properties
+ .get("title")
+ .map(|t| t.to_string());
+ let og_image = page
+ .opengraph
+ .images
+ .get(0)
+ .map(|ogo| Url::parse(&ogo.url).ok())
+ .flatten();
+
+ let title = og_title.or(page_title);
+ let description = og_description.or(page_description);
+ let image = og_image;
+
+ Ok(SiteMetadata {
+ title,
+ description,
+ image,
+ html: None,
+ })
}
#[derive(Deserialize, Debug, Clone)]
pub(crate) async fn fetch_pictrs(
client: &Client,
image_url: &Url,
-) -> Result<Option<PictrsResponse>, LemmyError> {
+) -> Result<PictrsResponse, LemmyError> {
if let Some(pictrs_url) = Settings::get().pictrs_url {
is_image_content_type(client, image_url).await?;
.map_err(|e| RecvError(e.to_string()))?;
if response.msg == "ok" {
- Ok(Some(response))
+ Ok(response)
} else {
Err(anyhow!("{}", &response.msg).into())
}
} else {
- Ok(None)
+ Err(anyhow!("pictrs_url not set up in config").into())
}
}
-pub async fn fetch_iframely_and_pictrs_data(
+/// Both are options, since the URL might be either an html page, or an image
+/// Returns the SiteMetadata, and a Pictrs URL, if there is a picture associated
+pub async fn fetch_site_data(
client: &Client,
url: Option<&Url>,
-) -> Result<(Option<IframelyResponse>, Option<Url>), LemmyError> {
+) -> (Option<SiteMetadata>, Option<Url>) {
match &url {
Some(url) => {
- // Fetch iframely data
- let iframely_res_option = fetch_iframely(client, url).await.ok();
+ // Fetch metadata
+ // Ignore errors, since it may be an image, or not have the data.
+ // Warning, this may ignore SSL errors
+ let metadata_option = fetch_site_metadata(client, url).await.ok();
// Fetch pictrs thumbnail
- let pictrs_hash = match &iframely_res_option {
- Some(iframely_res) => match &iframely_res.thumbnail_url {
- Some(iframely_thumbnail_url) => fetch_pictrs(client, iframely_thumbnail_url)
- .await?
+ let pictrs_hash = match &metadata_option {
+ Some(metadata_res) => match &metadata_res.image {
+ // Metadata, with image
+ // Try to generate a small thumbnail if there's a full sized one from post-links
+ Some(metadata_image) => fetch_pictrs(client, metadata_image)
+ .await
.map(|r| r.files[0].file.to_owned()),
- // Try to generate a small thumbnail if iframely is not supported
+ // Metadata, but no image
None => fetch_pictrs(client, url)
- .await?
+ .await
.map(|r| r.files[0].file.to_owned()),
},
+ // No metadata, try to fetch the URL as an image
None => fetch_pictrs(client, url)
- .await?
+ .await
.map(|r| r.files[0].file.to_owned()),
};
))
.ok()
})
+ .ok()
.flatten();
- Ok((iframely_res_option, pictrs_thumbnail))
+ (metadata_option, pictrs_thumbnail)
}
- None => Ok((None, None)),
+ None => (None, None),
}
}
#[cfg(test)]
mod tests {
+ use crate::request::fetch_site_metadata;
+ use url::Url;
+
+ use super::SiteMetadata;
+
// These helped with testing
- // #[test]
- // fn test_iframely() {
- // let res = fetch_iframely(client, "https://www.redspark.nu/?p=15341").await;
- // assert!(res.is_ok());
- // }
+ #[actix_rt::test]
+ async fn test_site_metadata() {
+ let client = reqwest::Client::default();
+ let sample_url = Url::parse("https://www.redspark.nu/en/peoples-war/district-leader-of-chand-led-cpn-arrested-in-bhojpur/").unwrap();
+ let sample_res = fetch_site_metadata(&client, &sample_url).await.unwrap();
+ assert_eq!(
+ SiteMetadata {
+ title: Some("District Leader Of Chand Led CPN Arrested In Bhojpur - Redspark".to_string()),
+ description: Some("BHOJPUR: A district leader of the outlawed Netra Bikram Chand alias Biplav-led outfit has been arrested. According to District Police".to_string()),
+ image: Some(Url::parse("https://www.redspark.nu/wp-content/uploads/2020/03/netra-bikram-chand-attends-program-1272019033653-1000x0-845x653-1.jpg").unwrap()),
+ html: None,
+ }, sample_res);
+
+ let youtube_url = Url::parse("https://www.youtube.com/watch?v=IquO_TcMZIQ").unwrap();
+ let youtube_res = fetch_site_metadata(&client, &youtube_url).await.unwrap();
+ assert_eq!(
+ SiteMetadata {
+ title: Some("A Hard Look at Rent and Rent Seeking with Michael Hudson & Pepe Escobar".to_string()),
+ description: Some("An interactive discussion on wealth inequality and the “Great Game” on the control of natural resources.In this webinar organized jointly by the Henry George...".to_string()),
+ image: Some(Url::parse("https://i.ytimg.com/vi/IquO_TcMZIQ/maxresdefault.jpg").unwrap()),
+ html: None,
+ }, youtube_res);
+ }
// #[test]
// fn test_pictshare() {
#[default(None)]
pub pictrs_url: Option<String>,
#[default(None)]
- pub iframely_url: Option<String>,
- #[default(None)]
pub additional_slurs: Option<String>,
#[default(20)]
pub actor_name_max_length: usize,
CommunityJoin,
ModJoin,
ChangePassword,
+ GetSiteMetadata,
}
#[derive(EnumString, ToString, Debug, Clone)]
depends_on:
- pictrs
- postgres
- - iframely
lemmy-ui:
image: dessalines/lemmy-ui:dev
volumes:
- ./volumes/pictrs:/mnt
restart: always
-
- iframely:
- image: dogbin/iframely:latest
- ports:
- - "8061:80"
- volumes:
- - ../iframely.config.local.js:/iframely/config.local.js:ro
- restart: always
- mem_limit: 200m
# Install libpq for postgres
RUN apt-get update -y
-RUN apt-get install -y libpq-dev
+RUN apt-get install -y libpq-dev ca-certificates
# Copy resources
COPY --from=rust /app/lemmy_server /app/lemmy
restart: on-failure
depends_on:
- pictrs
- - iframely
- lemmy-alpha-ui
- lemmy-beta-ui
- lemmy-gamma-ui
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_epsilon:/var/lib/postgresql/data
-
- iframely:
- image: dogbin/iframely:latest
- volumes:
- - ../iframely.config.local.js:/iframely/config.local.js:ro
- restart: always
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
}
- location /iframely/ {
- proxy_pass http://iframely:80/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
upstream lemmy-beta {
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
}
- location /iframely/ {
- proxy_pass http://iframely:80/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
upstream lemmy-gamma {
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
}
- location /iframely/ {
- proxy_pass http://iframely:80/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
upstream lemmy-delta {
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
}
- location /iframely/ {
- proxy_pass http://iframely:80/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
upstream lemmy-epsilon {
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
}
- location /iframely/ {
- proxy_pass http://iframely:80/;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
}
}
+++ /dev/null
-(function() {
- var config = {
-
- // Specify a path for custom plugins. Custom plugins will override core plugins.
- // CUSTOM_PLUGINS_PATH: __dirname + '/yourcustom-plugin-folder',
-
- DEBUG: false,
- RICH_LOG_ENABLED: false,
-
- // For embeds that require render, baseAppUrl will be used as the host.
- baseAppUrl: "http://yourdomain.com",
- relativeStaticUrl: "/r",
-
- // Or just skip built-in renders altogether
- SKIP_IFRAMELY_RENDERS: true,
-
- // For legacy reasons the response format of Iframely open-source is
- // different by default as it does not group the links array by rel.
- // In order to get the same grouped response as in Cloud API,
- // add `&group=true` to your request to change response per request
- // or set `GROUP_LINKS` in your config to `true` for a global change.
- GROUP_LINKS: true,
-
- // Number of maximum redirects to follow before aborting the page
- // request with `redirect loop` error.
- MAX_REDIRECTS: 4,
-
- SKIP_OEMBED_RE_LIST: [
- // /^https?:\/\/yourdomain\.com\//,
- ],
-
- /*
- // Used to pass parameters to the generate functions when creating HTML elements
- // disableSizeWrapper: Don't wrap element (iframe, video, etc) in a positioned div
- GENERATE_LINK_PARAMS: {
- disableSizeWrapper: true
- },
- */
-
- port: 80, //can be overridden by PORT env var
- host: '0.0.0.0', // Dockers beware. See https://github.com/itteco/iframely/issues/132#issuecomment-242991246
- //can be overridden by HOST env var
-
- // Optional SSL cert, if you serve under HTTPS.
- /*
- ssl: {
- key: require('fs').readFileSync(__dirname + '/key.pem'),
- cert: require('fs').readFileSync(__dirname + '/cert.pem'),
- port: 443
- },
- */
-
- /*
- Supported cache engines:
- - no-cache - no caching will be used.
- - node-cache - good for debug, node memory will be used (https://github.com/tcs-de/nodecache).
- - redis - https://github.com/mranney/node_redis.
- - memcached - https://github.com/3rd-Eden/node-memcached
- */
- CACHE_ENGINE: 'node-cache',
- CACHE_TTL: 0, // In seconds.
- // 0 = 'never expire' for memcached & node-cache to let cache engine decide itself when to evict the record
- // 0 = 'no cache' for redis. Use high enough (e.g. 365*24*60*60*1000) ttl for similar 'never expire' approach instead
-
- /*
- // Redis cache options.
- REDIS_OPTIONS: {
- host: '127.0.0.1',
- port: 6379
- },
- */
-
- /*
- // Memcached options. See https://github.com/3rd-Eden/node-memcached#server-locations
- MEMCACHED_OPTIONS: {
- locations: "127.0.0.1:11211"
- }
- */
-
- /*
- // Access-Control-Allow-Origin list.
- allowedOrigins: [
- "*",
- "http://another_domain.com"
- ],
- */
-
- /*
- // Uncomment to enable plugin testing framework.
- tests: {
- mongodb: 'mongodb://localhost:27017/iframely-tests',
- single_test_timeout: 10 * 1000,
- plugin_test_period: 2 * 60 * 60 * 1000,
- relaunch_script_period: 5 * 60 * 1000
- },
- */
-
- // If there's no response from remote server, the timeout will occur after
- RESPONSE_TIMEOUT: 5 * 1000, //ms
-
- /* From v1.4.0, Iframely supports HTTP/2 by default. Disable it, if you'd rather not.
- Alternatively, you can also disable per origin. See `proxy` option below.
- */
- // DISABLE_HTTP2: true,
-
- // Customize API calls to oembed endpoints.
- ADD_OEMBED_PARAMS: [{
- // Endpoint url regexp array.
- re: [/^http:\/\/api\.instagram\.com\/oembed/],
- // Custom get params object.
- params: {
- hidecaption: true
- }
- }, {
- re: [/^https:\/\/www\.facebook\.com\/plugins\/page\/oembed\.json/i],
- params: {
- show_posts: 0,
- show_facepile: 0,
- maxwidth: 600
- }
- }, {
- // match i=user or i=moment or i=timeline to configure these types invidually
- // see params spec at https://dev.twitter.com/web/embedded-timelines/oembed
- re: [/^https?:\/\/publish\.twitter\.com\/oembed\?i=user/i],
- params: {
- limit: 1,
- maxwidth: 600
- }
- /*
- }, {
- // Facebook https://developers.facebook.com/docs/plugins/oembed-endpoints
- re: [/^https:\/\/www\.facebook\.com\/plugins\/\w+\/oembed\.json/i],
- params: {
- // Skip script tag and fb-root div.
- omitscript: true
- }
- */
- }],
-
- /*
- // Configure use of HTTP proxies as needed.
- // You don't have to specify all options per regex - just what you need to override
- PROXY: [{
- re: [/^https?:\/\/www\.domain\.com/],
- proxy_server: 'http://1.2.3.4:8080',
- user_agent: 'CHANGE YOUR AGENT',
- headers: {
- // HTTP headers
- // Overrides previous params if overlapped.
- },
- request_options: {
- // Refer to: https://github.com/request/request
- // Overrides previous params if overlapped.
- },
- disable_http2: true
- }],
- */
-
- // Customize API calls to 3rd parties. At the very least - configure required keys.
- providerOptions: {
- locale: "en_US", // ISO 639-1 two-letter language code, e.g. en_CA or fr_CH.
- // Will be added as highest priotity in accept-language header with each request.
- // Plus is used in FB, YouTube and perhaps other plugins
- "twitter": {
- "max-width": 550,
- "min-width": 250,
- hide_media: false,
- hide_thread: false,
- omit_script: false,
- center: false,
- // dnt: true,
- cache_ttl: 100 * 365 * 24 * 3600 // 100 Years.
- },
- readability: {
- enabled: false
- // allowPTagDescription: true // to enable description fallback to first paragraph
- },
- images: {
- loadSize: false, // if true, will try an load first bytes of all images to get/confirm the sizes
- checkFavicon: false // if true, will verify all favicons
- },
- tumblr: {
- consumer_key: "INSERT YOUR VALUE"
- // media_only: true // disables status embeds for images and videos - will return plain media
- },
- google: {
- // https://developers.google.com/maps/documentation/embed/guide#api_key
- maps_key: "INSERT YOUR VALUE"
- },
-
- /*
- // Optional Camo Proxy to wrap all images: https://github.com/atmos/camo
- camoProxy: {
- camo_proxy_key: "INSERT YOUR VALUE",
- camo_proxy_host: "INSERT YOUR VALUE"
- // ssl_only: true // will only proxy non-ssl images
- },
- */
-
- // List of query parameters to add to YouTube and Vimeo frames
- // Start it with leading "?". Or omit alltogether for default values
- // API key is optional, youtube will work without it too.
- // It is probably the same API key you use for Google Maps.
- youtube: {
- // api_key: "INSERT YOUR VALUE",
- get_params: "?rel=0&showinfo=1" // https://developers.google.com/youtube/player_parameters
- },
- vimeo: {
- get_params: "?byline=0&badge=0" // https://developer.vimeo.com/player/embedding
- },
-
- /*
- soundcloud: {
- old_player: true // enables classic player
- },
- giphy: {
- media_only: true // disables branded player for gifs and returns just the image
- }
- */
- /*
- bandcamp: {
- get_params: '/size=large/bgcol=333333/linkcol=ffffff/artwork=small/transparent=true/',
- media: {
- album: {
- height: 472,
- 'max-width': 700
- },
- track: {
- height: 120,
- 'max-width': 700
- }
- }
- }
- */
- },
-
- // WHITELIST_WILDCARD, if present, will be added to whitelist as record for top level domain: "*"
- // with it, you can define what parsers do when they run accross unknown publisher.
- // If absent or empty, all generic media parsers will be disabled except for known domains
- // More about format: https://iframely.com/docs/qa-format
-
- /*
- WHITELIST_WILDCARD: {
- "twitter": {
- "player": "allow",
- "photo": "deny"
- },
- "oembed": {
- "video": "allow",
- "photo": "allow",
- "rich": "deny",
- "link": "deny"
- },
- "og": {
- "video": ["allow", "ssl", "responsive"]
- },
- "iframely": {
- "survey": "allow",
- "reader": "allow",
- "player": "allow",
- "image": "allow"
- },
- "html-meta": {
- "video": ["allow", "responsive"],
- "promo": "allow"
- }
- }
- */
-
- // Black-list any of the inappropriate domains. Iframely will return 417
- // At minimum, keep your localhosts blacklisted to avoid SSRF
- BLACKLIST_DOMAINS_RE: [
- /^https?:\/\/127\.0\.0\.1/i,
- /^https?:\/\/localhost/i,
-
- // And this is AWS metadata service
- // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
- /^https?:\/\/169\.254\.169\.254/
- ]
- };
-
- module.exports = config;
-})();
# json web token for authorization between server and client
jwt_secret: "changeme"
# settings related to the postgresql database
+ # address where pictrs is available
+ pictrs_url: "http://pictrs:8080"
database: {
# name of the postgres database for lemmy
database: "lemmy"
depends_on:
- postgres
- pictrs
- - iframely
lemmy-ui:
image: dessalines/lemmy-ui:0.11.3
- ./volumes/pictrs:/mnt
restart: always
- iframely:
- image: dogbin/iframely:latest
- ports:
- - "127.0.0.1:8061:80"
- volumes:
- - ./iframely.config.local.js:/iframely/config.local.js:ro
- restart: always
- mem_limit: 200m
"/report/resolve",
web::put().to(route_post::<ResolvePostReport>),
)
- .route("/report/list", web::get().to(route_get::<ListPostReports>)),
+ .route("/report/list", web::get().to(route_get::<ListPostReports>))
+ .route(
+ "/site_metadata",
+ web::get().to(route_get::<GetSiteMetadata>),
+ ),
)
// Comment
.service(
);
let activity_queue = create_activity_queue();
+
let chat_server = ChatServer::startup(
pool.clone(),
rate_limiter.clone(),