mirror of
https://git.asonix.dog/asonix/relay.git
synced 2024-11-26 07:22:15 +00:00
Switch from awc to reqwest, enable HTTP Proxies
This commit is contained in:
parent
73b429ab51
commit
75df271b58
321
Cargo.lock
generated
321
Cargo.lock
generated
|
@ -100,7 +100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -140,7 +140,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"socket2",
|
||||
"socket2 0.4.9",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -167,7 +167,6 @@ dependencies = [
|
|||
"actix-service",
|
||||
"actix-utils",
|
||||
"futures-core",
|
||||
"http",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio-rustls 0.23.4",
|
||||
|
@ -219,20 +218,19 @@ dependencies = [
|
|||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"smallvec",
|
||||
"socket2",
|
||||
"socket2 0.4.9",
|
||||
"time",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-webfinger"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e64f0f9b28305d38058daaff76a608684a43cbf67e9a9289bdd124a2a45b5e"
|
||||
checksum = "74a22b44deff50693521b489885151fd65a2a596f7aef6d8c0753485b8915082"
|
||||
dependencies = [
|
||||
"actix-rt",
|
||||
"actix-web",
|
||||
"awc",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"thiserror",
|
||||
|
@ -287,9 +285,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.2"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
||||
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -375,9 +373,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
|
||||
checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
|
@ -385,9 +383,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.72"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "ap-relay"
|
||||
|
@ -400,7 +398,6 @@ dependencies = [
|
|||
"actix-webfinger",
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
"awc",
|
||||
"background-jobs",
|
||||
"base64 0.21.2",
|
||||
"bcrypt",
|
||||
|
@ -412,6 +409,7 @@ dependencies = [
|
|||
"flume",
|
||||
"futures-util",
|
||||
"http-signature-normalization-actix",
|
||||
"http-signature-normalization-reqwest",
|
||||
"lru",
|
||||
"metrics",
|
||||
"metrics-exporter-prometheus",
|
||||
|
@ -423,6 +421,9 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
"quanta",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"reqwest-tracing",
|
||||
"ring",
|
||||
"rsa",
|
||||
"rsa-magic-public-key",
|
||||
|
@ -439,7 +440,6 @@ dependencies = [
|
|||
"toml 0.7.6",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
"tracing-awc",
|
||||
"tracing-error",
|
||||
"tracing-futures",
|
||||
"tracing-log",
|
||||
|
@ -469,13 +469,13 @@ checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.72"
|
||||
version = "0.1.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
|
||||
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -484,40 +484,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "awc"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ef547a81796eb2dfe9b345aba34c2e08391a0502493711395b36dd64052b69"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-http",
|
||||
"actix-rt",
|
||||
"actix-service",
|
||||
"actix-tls",
|
||||
"actix-utils",
|
||||
"ahash 0.7.6",
|
||||
"base64 0.21.2",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"derive_more",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"itoa",
|
||||
"log",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"rustls 0.20.8",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
|
@ -667,9 +633,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.3.3"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
|
||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
@ -746,9 +712,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.81"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0"
|
||||
checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -781,9 +747,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.3.19"
|
||||
version = "4.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
|
||||
checksum = "b417ae4361bca3f5de378294fc7472d3c4ed86a5ef9f49e93ae722f432aae8d2"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -792,9 +758,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.3.19"
|
||||
version = "4.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
|
||||
checksum = "9c90dc0f0e42c64bff177ca9d7be6fcc9ddb0f26a6e062174a61c84dd6c644d4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -811,7 +777,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -883,9 +849,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
|
@ -1014,9 +980,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946"
|
||||
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
|
@ -1149,9 +1115,9 @@ checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
|
||||
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
|
@ -1261,7 +1227,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1458,7 +1424,6 @@ dependencies = [
|
|||
"actix-http",
|
||||
"actix-rt",
|
||||
"actix-web",
|
||||
"awc",
|
||||
"base64 0.13.1",
|
||||
"futures-util",
|
||||
"http-signature-normalization",
|
||||
|
@ -1470,6 +1435,22 @@ dependencies = [
|
|||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-signature-normalization-reqwest"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10cfb84663420ec12c4422820bfdf5e8e5e57467892587f43ac432e73ebce880"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.1",
|
||||
"http-signature-normalization",
|
||||
"httpdate",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"ring",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
|
@ -1478,9 +1459,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
|||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
|
@ -1505,7 +1486,7 @@ dependencies = [
|
|||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"socket2 0.4.9",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -1741,9 +1722,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.19"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
|
@ -1861,7 +1842,7 @@ checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1870,7 +1851,7 @@ version = "0.15.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e"
|
||||
dependencies = [
|
||||
"aho-corasick 1.0.2",
|
||||
"aho-corasick 1.0.4",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"hashbrown 0.13.1",
|
||||
|
@ -2327,7 +2308,7 @@ dependencies = [
|
|||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2381,29 +2362,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
|
||||
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
|
||||
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.10"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
|
||||
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
@ -2533,9 +2514,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -2618,13 +2599,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.1"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
|
||||
dependencies = [
|
||||
"aho-corasick 1.0.2",
|
||||
"aho-corasick 1.0.4",
|
||||
"memchr",
|
||||
"regex-automata 0.3.4",
|
||||
"regex-automata 0.3.6",
|
||||
"regex-syntax 0.7.4",
|
||||
]
|
||||
|
||||
|
@ -2639,11 +2620,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.4"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294"
|
||||
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
|
||||
dependencies = [
|
||||
"aho-corasick 1.0.2",
|
||||
"aho-corasick 1.0.4",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.4",
|
||||
]
|
||||
|
@ -2702,6 +2683,37 @@ dependencies = [
|
|||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest-middleware"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff44108c7925d082f2861e683a88618b68235ad9cdc60d64d9d1188efc951cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"http",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"task-local-extensions",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest-tracing"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b97ad83c2fc18113346b7158d79732242002427c30f620fa817c1f32901e0a8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"getrandom",
|
||||
"matchit",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"task-local-extensions",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
|
@ -2827,11 +2839,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.6"
|
||||
version = "0.38.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f"
|
||||
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||
dependencies = [
|
||||
"bitflags 2.3.3",
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
@ -2873,9 +2885,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.2"
|
||||
version = "0.101.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59"
|
||||
checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
|
@ -2917,29 +2929,29 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.181"
|
||||
version = "1.0.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d3e73c93c3240c0bda063c239298e633114c69a888c3e37ca8bb33f343e9890"
|
||||
checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.181"
|
||||
version = "1.0.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be02f6cb0cd3a5ec20bbcfbcbd749f57daddb1a0882dc2e46a6c236c90b977ed"
|
||||
checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.104"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -3082,6 +3094,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
@ -3158,9 +3180,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
version = "2.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
|
||||
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3185,6 +3207,15 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e"
|
||||
|
||||
[[package]]
|
||||
name = "task-local-extensions"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba323866e5d033818e3240feeb9f7db2c4296674e4d9e16b97b7bf8f490434e8"
|
||||
dependencies = [
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "teloxide"
|
||||
version = "0.12.2"
|
||||
|
@ -3267,22 +3298,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.44"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||
checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.44"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||
checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3340,11 +3371,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.29.1"
|
||||
version = "1.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
|
||||
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
|
@ -3352,7 +3382,7 @@ dependencies = [
|
|||
"parking_lot 0.12.1",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"socket2 0.5.3",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys",
|
||||
|
@ -3376,7 +3406,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3561,22 +3591,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-awc"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afd0c52e66eec56d4fbddbfa1d15261ee48a78360d7d3ee3d3900c4c3489d8ad"
|
||||
dependencies = [
|
||||
"actix-http",
|
||||
"actix-service",
|
||||
"awc",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tracing",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3794,7 +3809,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -3828,7 +3843,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"syn 2.0.29",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -3914,9 +3929,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.1"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
||||
checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
|
@ -3929,51 +3944,51 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
version = "0.48.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.3"
|
||||
version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807"
|
||||
checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -28,11 +28,10 @@ actix-web = { version = "4.0.1", default-features = false, features = [
|
|||
"compress-brotli",
|
||||
"compress-gzip",
|
||||
] }
|
||||
actix-webfinger = "0.4.0"
|
||||
actix-webfinger = { version = "0.5.0", default-features = false }
|
||||
activitystreams = "0.7.0-alpha.25"
|
||||
activitystreams-ext = "0.1.0-alpha.3"
|
||||
ammonia = "3.1.0"
|
||||
awc = { version = "3.0.0", default-features = false, features = ["rustls"] }
|
||||
bcrypt = "0.15"
|
||||
base64 = "0.21"
|
||||
clap = { version = "4.0.0", features = ["derive"] }
|
||||
|
@ -55,6 +54,9 @@ opentelemetry-otlp = "0.13"
|
|||
pin-project-lite = "0.2.9"
|
||||
quanta = "0.11.0"
|
||||
rand = "0.8"
|
||||
reqwest = { version = "0.11", default-features = false, features = ["rustls-tls", "stream"]}
|
||||
reqwest-middleware = "0.2"
|
||||
reqwest-tracing = "0.4.5"
|
||||
ring = "0.16.20"
|
||||
rsa = { version = "0.9" }
|
||||
rsa-magic-public-key = "0.8.0"
|
||||
|
@ -71,7 +73,6 @@ teloxide = { version = "0.12.0", default-features = false, features = [
|
|||
thiserror = "1.0"
|
||||
time = { version = "0.3.17", features = ["serde"] }
|
||||
tracing = "0.1"
|
||||
tracing-awc = "0.1.8"
|
||||
tracing-error = "0.2"
|
||||
tracing-futures = "0.2"
|
||||
tracing-log = "0.1"
|
||||
|
@ -92,7 +93,12 @@ features = ["background-jobs-actix", "error-logging"]
|
|||
[dependencies.http-signature-normalization-actix]
|
||||
version = "0.10.1"
|
||||
default-features = false
|
||||
features = ["client", "server", "ring"]
|
||||
features = ["server", "ring"]
|
||||
|
||||
[dependencies.http-signature-normalization-reqwest]
|
||||
version = "0.10.0"
|
||||
default-features = false
|
||||
features = ["middleware", "ring"]
|
||||
|
||||
[dependencies.tracing-actix-web]
|
||||
version = "0.7.6"
|
||||
|
|
12
README.md
12
README.md
|
@ -106,7 +106,6 @@ LOCAL_BLURB="<p>Welcome to my cool relay where I have cool relay things happenin
|
|||
PROMETHEUS_ADDR=0.0.0.0
|
||||
PROMETHEUS_PORT=9000
|
||||
CLIENT_TIMEOUT=10
|
||||
CLIENT_POOL_SIZE=20
|
||||
DELIVER_CONCURRENCY=8
|
||||
SIGNATURE_THREADS=2
|
||||
```
|
||||
|
@ -161,11 +160,6 @@ Optional - Port to bind to for serving the prometheus scrape endpoint
|
|||
##### `CLIENT_TIMEOUT`
|
||||
Optional - How long the relay will hold open a connection (in seconds) to a remote server during
|
||||
fetches and deliveries. This defaults to 10
|
||||
##### `CLIENT_POOL_SIZE`
|
||||
Optional - How many connections the relay should maintain per thread. This value will be multiplied
|
||||
by the number of cores available to the relay. This defaults to 20, so a 4-core machine will have a
|
||||
maximum of 160 simultaneous outbound connections. If you run into problems related to "Too many open
|
||||
files", you can either decrease this number or increase the ulimit for your system.
|
||||
##### `DELIVER_CONCURRENCY`
|
||||
Optional - How many deliver requests the relay should allow to be in-flight per thread. the default
|
||||
is 8
|
||||
|
@ -173,6 +167,12 @@ is 8
|
|||
Optional - Override number of threads used for signing and verifying requests. Default is
|
||||
`std::thread::available_parallelism()` (It tries to detect how many cores you have). If it cannot
|
||||
detect the correct number of cores, it falls back to 1.
|
||||
##### 'PROXY_URL'
|
||||
Optional - URL of an HTTP proxy to forward outbound requests through
|
||||
##### 'PROXY_USERNAME'
|
||||
Optional - username to provide to the HTTP proxy set with `PROXY_URL` through HTTP Basic Auth
|
||||
##### 'PROXY_PASSWORD'
|
||||
Optional - password to provide to the HTTP proxy set with `PROXY_URL` through HTTP Basic Auth
|
||||
|
||||
### Subscribing
|
||||
Mastodon admins can subscribe to this relay by adding the `/inbox` route to their relay settings.
|
||||
|
|
|
@ -3,12 +3,14 @@ use crate::{
|
|||
collector::Snapshot,
|
||||
config::{AdminUrlKind, Config},
|
||||
error::{Error, ErrorKind},
|
||||
extractors::XApiToken,
|
||||
};
|
||||
use awc::Client;
|
||||
use actix_web::http::header::Header;
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub(crate) async fn allow(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
domains: Vec<String>,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -16,7 +18,7 @@ pub(crate) async fn allow(
|
|||
}
|
||||
|
||||
pub(crate) async fn disallow(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
domains: Vec<String>,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -24,7 +26,7 @@ pub(crate) async fn disallow(
|
|||
}
|
||||
|
||||
pub(crate) async fn block(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
domains: Vec<String>,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -32,35 +34,50 @@ pub(crate) async fn block(
|
|||
}
|
||||
|
||||
pub(crate) async fn unblock(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
domains: Vec<String>,
|
||||
) -> Result<(), Error> {
|
||||
post_domains(client, config, domains, AdminUrlKind::Unblock).await
|
||||
}
|
||||
|
||||
pub(crate) async fn allowed(client: &Client, config: &Config) -> Result<AllowedDomains, Error> {
|
||||
pub(crate) async fn allowed(
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
) -> Result<AllowedDomains, Error> {
|
||||
get_results(client, config, AdminUrlKind::Allowed).await
|
||||
}
|
||||
|
||||
pub(crate) async fn blocked(client: &Client, config: &Config) -> Result<BlockedDomains, Error> {
|
||||
pub(crate) async fn blocked(
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
) -> Result<BlockedDomains, Error> {
|
||||
get_results(client, config, AdminUrlKind::Blocked).await
|
||||
}
|
||||
|
||||
pub(crate) async fn connected(client: &Client, config: &Config) -> Result<ConnectedActors, Error> {
|
||||
pub(crate) async fn connected(
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
) -> Result<ConnectedActors, Error> {
|
||||
get_results(client, config, AdminUrlKind::Connected).await
|
||||
}
|
||||
|
||||
pub(crate) async fn stats(client: &Client, config: &Config) -> Result<Snapshot, Error> {
|
||||
pub(crate) async fn stats(
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
) -> Result<Snapshot, Error> {
|
||||
get_results(client, config, AdminUrlKind::Stats).await
|
||||
}
|
||||
|
||||
pub(crate) async fn last_seen(client: &Client, config: &Config) -> Result<LastSeen, Error> {
|
||||
pub(crate) async fn last_seen(
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
) -> Result<LastSeen, Error> {
|
||||
get_results(client, config, AdminUrlKind::LastSeen).await
|
||||
}
|
||||
|
||||
async fn get_results<T: DeserializeOwned>(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
url_kind: AdminUrlKind,
|
||||
) -> Result<T, Error> {
|
||||
|
@ -68,9 +85,9 @@ async fn get_results<T: DeserializeOwned>(
|
|||
|
||||
let iri = config.generate_admin_url(url_kind);
|
||||
|
||||
let mut res = client
|
||||
let res = client
|
||||
.get(iri.as_str())
|
||||
.insert_header(x_api_token)
|
||||
.header(XApiToken::name(), x_api_token.to_string())
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| ErrorKind::SendRequest(iri.to_string(), e.to_string()))?;
|
||||
|
@ -88,7 +105,7 @@ async fn get_results<T: DeserializeOwned>(
|
|||
}
|
||||
|
||||
async fn post_domains(
|
||||
client: &Client,
|
||||
client: &ClientWithMiddleware,
|
||||
config: &Config,
|
||||
domains: Vec<String>,
|
||||
url_kind: AdminUrlKind,
|
||||
|
@ -99,8 +116,9 @@ async fn post_domains(
|
|||
|
||||
let res = client
|
||||
.post(iri.as_str())
|
||||
.insert_header(x_api_token)
|
||||
.send_json(&Domains { domains })
|
||||
.header(XApiToken::name(), x_api_token.to_string())
|
||||
.json(&Domains { domains })
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| ErrorKind::SendRequest(iri.to_string(), e.to_string()))?;
|
||||
|
||||
|
|
|
@ -46,7 +46,9 @@ pub(crate) struct ParsedConfig {
|
|||
prometheus_port: Option<u16>,
|
||||
deliver_concurrency: u64,
|
||||
client_timeout: u64,
|
||||
client_pool_size: usize,
|
||||
proxy_url: Option<IriString>,
|
||||
proxy_username: Option<String>,
|
||||
proxy_password: Option<String>,
|
||||
signature_threads: Option<usize>,
|
||||
}
|
||||
|
||||
|
@ -73,7 +75,7 @@ pub struct Config {
|
|||
prometheus_config: Option<PrometheusConfig>,
|
||||
deliver_concurrency: u64,
|
||||
client_timeout: u64,
|
||||
client_pool_size: usize,
|
||||
proxy_config: Option<ProxyConfig>,
|
||||
signature_threads: Option<usize>,
|
||||
}
|
||||
|
||||
|
@ -89,6 +91,12 @@ struct PrometheusConfig {
|
|||
port: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ProxyConfig {
|
||||
url: IriString,
|
||||
auth: Option<(String, String)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UrlKind {
|
||||
Activity,
|
||||
|
@ -144,7 +152,7 @@ impl std::fmt::Debug for Config {
|
|||
.field("prometheus_config", &self.prometheus_config)
|
||||
.field("deliver_concurrency", &self.deliver_concurrency)
|
||||
.field("client_timeout", &self.client_timeout)
|
||||
.field("client_pool_size", &self.client_pool_size)
|
||||
.field("proxy_config", &self.proxy_config)
|
||||
.field("signature_threads", &self.signature_threads)
|
||||
.finish()
|
||||
}
|
||||
|
@ -177,7 +185,9 @@ impl Config {
|
|||
.set_default("prometheus_port", None as Option<u16>)?
|
||||
.set_default("deliver_concurrency", 8u64)?
|
||||
.set_default("client_timeout", 10u64)?
|
||||
.set_default("client_pool_size", 20u64)?
|
||||
.set_default("proxy_url", None as Option<&str>)?
|
||||
.set_default("proxy_username", None as Option<&str>)?
|
||||
.set_default("proxy_password", None as Option<&str>)?
|
||||
.set_default("signature_threads", None as Option<u64>)?
|
||||
.add_source(Environment::default())
|
||||
.build()?;
|
||||
|
@ -220,6 +230,26 @@ impl Config {
|
|||
(None, None) => None,
|
||||
};
|
||||
|
||||
let proxy_config = match (config.proxy_username, config.proxy_password) {
|
||||
(Some(username), Some(password)) => config.proxy_url.map(|url| ProxyConfig {
|
||||
url,
|
||||
auth: Some((username, password)),
|
||||
}),
|
||||
(Some(_), None) => {
|
||||
tracing::warn!(
|
||||
"PROXY_USERNAME is set but PROXY_PASSWORD is not set, not setting Proxy Auth"
|
||||
);
|
||||
config.proxy_url.map(|url| ProxyConfig { url, auth: None })
|
||||
}
|
||||
(None, Some(_)) => {
|
||||
tracing::warn!(
|
||||
"PROXY_PASSWORD is set but PROXY_USERNAME is not set, not setting Proxy Auth"
|
||||
);
|
||||
config.proxy_url.map(|url| ProxyConfig { url, auth: None })
|
||||
}
|
||||
(None, None) => config.proxy_url.map(|url| ProxyConfig { url, auth: None }),
|
||||
};
|
||||
|
||||
let source_url = match Self::git_hash() {
|
||||
Some(hash) => format!(
|
||||
"{}{}{hash}",
|
||||
|
@ -252,7 +282,7 @@ impl Config {
|
|||
prometheus_config,
|
||||
deliver_concurrency: config.deliver_concurrency,
|
||||
client_timeout: config.client_timeout,
|
||||
client_pool_size: config.client_pool_size,
|
||||
proxy_config,
|
||||
signature_threads: config.signature_threads,
|
||||
})
|
||||
}
|
||||
|
@ -468,8 +498,10 @@ impl Config {
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn client_pool_size(&self) -> usize {
|
||||
self.client_pool_size
|
||||
pub(crate) fn proxy_config(&self) -> Option<(&IriString, Option<(&str, &str)>)> {
|
||||
self.proxy_config.as_ref().map(|ProxyConfig { url, auth }| {
|
||||
(url, auth.as_ref().map(|(u, p)| (u.as_str(), p.as_str())))
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn source_code(&self) -> &IriString {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::{
|
||||
config::{Config, UrlKind},
|
||||
data::NodeCache,
|
||||
db::Db,
|
||||
error::Error,
|
||||
|
@ -10,6 +9,7 @@ use activitystreams::iri_string::types::IriString;
|
|||
use actix_web::web;
|
||||
use lru::LruCache;
|
||||
use rand::thread_rng;
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use rsa::{RsaPrivateKey, RsaPublicKey};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
|
@ -17,10 +17,10 @@ use super::LastOnline;
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct State {
|
||||
pub(crate) requests: Requests,
|
||||
pub(crate) public_key: RsaPublicKey,
|
||||
private_key: RsaPrivateKey,
|
||||
object_cache: Arc<RwLock<LruCache<IriString, IriString>>>,
|
||||
node_cache: NodeCache,
|
||||
pub(crate) node_cache: NodeCache,
|
||||
breakers: Breakers,
|
||||
pub(crate) last_online: Arc<LastOnline>,
|
||||
pub(crate) db: Db,
|
||||
|
@ -37,23 +37,6 @@ impl std::fmt::Debug for State {
|
|||
}
|
||||
|
||||
impl State {
|
||||
pub(crate) fn node_cache(&self) -> NodeCache {
|
||||
self.node_cache.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn requests(&self, config: &Config, spawner: Spawner) -> Requests {
|
||||
Requests::new(
|
||||
config.generate_url(UrlKind::MainKey).to_string(),
|
||||
self.private_key.clone(),
|
||||
config.user_agent(),
|
||||
self.breakers.clone(),
|
||||
self.last_online.clone(),
|
||||
config.client_pool_size(),
|
||||
config.client_timeout(),
|
||||
spawner,
|
||||
)
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
level = "debug",
|
||||
name = "Get inboxes for other domains",
|
||||
|
@ -98,7 +81,12 @@ impl State {
|
|||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", name = "Building state", skip_all)]
|
||||
pub(crate) async fn build(db: Db) -> Result<Self, Error> {
|
||||
pub(crate) async fn build(
|
||||
db: Db,
|
||||
key_id: String,
|
||||
spawner: Spawner,
|
||||
client: ClientWithMiddleware,
|
||||
) -> Result<Self, Error> {
|
||||
let private_key = if let Ok(Some(key)) = db.private_key().await {
|
||||
tracing::debug!("Using existing key");
|
||||
key
|
||||
|
@ -117,16 +105,28 @@ impl State {
|
|||
|
||||
let public_key = private_key.to_public_key();
|
||||
|
||||
let state = State {
|
||||
public_key,
|
||||
let breakers = Breakers::default();
|
||||
let last_online = Arc::new(LastOnline::empty());
|
||||
|
||||
let requests = Requests::new(
|
||||
key_id,
|
||||
private_key,
|
||||
breakers.clone(),
|
||||
last_online.clone(),
|
||||
spawner,
|
||||
client,
|
||||
);
|
||||
|
||||
let state = State {
|
||||
requests,
|
||||
public_key,
|
||||
object_cache: Arc::new(RwLock::new(LruCache::new(
|
||||
(1024 * 8).try_into().expect("nonzero"),
|
||||
))),
|
||||
node_cache: NodeCache::new(db.clone()),
|
||||
breakers: Breakers::default(),
|
||||
breakers,
|
||||
db,
|
||||
last_online: Arc::new(LastOnline::empty()),
|
||||
last_online,
|
||||
};
|
||||
|
||||
Ok(state)
|
||||
|
|
18
src/error.rs
18
src/error.rs
|
@ -5,7 +5,7 @@ use actix_web::{
|
|||
http::StatusCode,
|
||||
HttpResponse,
|
||||
};
|
||||
use http_signature_normalization_actix::PrepareSignError;
|
||||
use http_signature_normalization_reqwest::SignError;
|
||||
use std::{convert::Infallible, fmt::Debug, io};
|
||||
use tracing_error::SpanTrace;
|
||||
|
||||
|
@ -84,6 +84,12 @@ pub(crate) enum ErrorKind {
|
|||
#[error("Couldn't sign request")]
|
||||
SignRequest,
|
||||
|
||||
#[error("Couldn't make request")]
|
||||
Reqwest(#[from] reqwest::Error),
|
||||
|
||||
#[error("Couldn't build client")]
|
||||
ReqwestMiddleware(#[from] reqwest_middleware::Error),
|
||||
|
||||
#[error("Couldn't parse IRI, {0}")]
|
||||
ParseIri(#[from] activitystreams::iri_string::validate::Error),
|
||||
|
||||
|
@ -102,8 +108,8 @@ pub(crate) enum ErrorKind {
|
|||
#[error("Couldn't do the json thing, {0}")]
|
||||
Json(#[from] serde_json::Error),
|
||||
|
||||
#[error("Couldn't build signing string, {0}")]
|
||||
PrepareSign(#[from] PrepareSignError),
|
||||
#[error("Couldn't sign request, {0}")]
|
||||
Sign(#[from] SignError),
|
||||
|
||||
#[error("Couldn't sign digest")]
|
||||
Signature(#[from] rsa::signature::Error),
|
||||
|
@ -251,3 +257,9 @@ impl From<http_signature_normalization_actix::Canceled> for ErrorKind {
|
|||
Self::Canceled
|
||||
}
|
||||
}
|
||||
|
||||
impl From<http_signature_normalization_reqwest::Canceled> for ErrorKind {
|
||||
fn from(_: http_signature_normalization_reqwest::Canceled) -> Self {
|
||||
Self::Canceled
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,3 +243,9 @@ impl FromStr for XApiToken {
|
|||
Ok(XApiToken(s.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for XApiToken {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
13
src/jobs.rs
13
src/jobs.rs
|
@ -14,11 +14,9 @@ pub(crate) use self::{
|
|||
|
||||
use crate::{
|
||||
config::Config,
|
||||
data::{ActorCache, MediaCache, NodeCache, State},
|
||||
data::{ActorCache, MediaCache, State},
|
||||
error::{Error, ErrorKind},
|
||||
jobs::{process_listeners::Listeners, record_last_online::RecordLastOnline},
|
||||
requests::Requests,
|
||||
spawner::Spawner,
|
||||
};
|
||||
use background_jobs::{
|
||||
memory_storage::{ActixTimer, Storage},
|
||||
|
@ -45,7 +43,6 @@ pub(crate) fn create_workers(
|
|||
actors: ActorCache,
|
||||
media: MediaCache,
|
||||
config: Config,
|
||||
spawner: Spawner,
|
||||
) -> JobServer {
|
||||
let deliver_concurrency = config.deliver_concurrency();
|
||||
|
||||
|
@ -56,7 +53,6 @@ pub(crate) fn create_workers(
|
|||
JobServer::new(queue_handle),
|
||||
media.clone(),
|
||||
config.clone(),
|
||||
spawner.clone(),
|
||||
)
|
||||
})
|
||||
.register::<Deliver>()
|
||||
|
@ -84,12 +80,10 @@ pub(crate) fn create_workers(
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct JobState {
|
||||
requests: Requests,
|
||||
state: State,
|
||||
actors: ActorCache,
|
||||
config: Config,
|
||||
media: MediaCache,
|
||||
node_cache: NodeCache,
|
||||
job_server: JobServer,
|
||||
}
|
||||
|
||||
|
@ -113,15 +107,12 @@ impl JobState {
|
|||
job_server: JobServer,
|
||||
media: MediaCache,
|
||||
config: Config,
|
||||
spawner: Spawner,
|
||||
) -> Self {
|
||||
JobState {
|
||||
requests: state.requests(&config, spawner),
|
||||
node_cache: state.node_cache(),
|
||||
state,
|
||||
actors,
|
||||
config,
|
||||
media,
|
||||
state,
|
||||
job_server,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ impl QueryContact {
|
|||
|
||||
async fn perform(self, state: JobState) -> Result<(), Error> {
|
||||
let contact_outdated = state
|
||||
.state
|
||||
.node_cache
|
||||
.is_contact_outdated(self.actor_id.clone())
|
||||
.await;
|
||||
|
@ -41,6 +42,7 @@ impl QueryContact {
|
|||
}
|
||||
|
||||
let contact = match state
|
||||
.state
|
||||
.requests
|
||||
.fetch::<AcceptedActors>(&self.contact_id)
|
||||
.await
|
||||
|
@ -57,6 +59,7 @@ impl QueryContact {
|
|||
to_contact(contact).ok_or(ErrorKind::Extract("contact"))?;
|
||||
|
||||
state
|
||||
.state
|
||||
.node_cache
|
||||
.set_contact(self.actor_id, username, display_name, url, avatar)
|
||||
.await?;
|
||||
|
|
|
@ -35,7 +35,7 @@ impl Deliver {
|
|||
|
||||
#[tracing::instrument(name = "Deliver", skip(state))]
|
||||
async fn permform(self, state: JobState) -> Result<(), Error> {
|
||||
if let Err(e) = state.requests.deliver(&self.to, &self.data).await {
|
||||
if let Err(e) = state.state.requests.deliver(&self.to, &self.data).await {
|
||||
if e.is_breaker() {
|
||||
tracing::debug!("Not trying due to failed breaker");
|
||||
return Ok(());
|
||||
|
|
|
@ -40,6 +40,7 @@ impl QueryInstance {
|
|||
InstanceApiType::Mastodon => {
|
||||
let mastodon_instance_uri = iri!(format!("{scheme}://{authority}/api/v1/instance"));
|
||||
state
|
||||
.state
|
||||
.requests
|
||||
.fetch_json::<Instance>(&mastodon_instance_uri)
|
||||
.await
|
||||
|
@ -47,6 +48,7 @@ impl QueryInstance {
|
|||
InstanceApiType::Misskey => {
|
||||
let msky_meta_uri = iri!(format!("{scheme}://{authority}/api/meta"));
|
||||
state
|
||||
.state
|
||||
.requests
|
||||
.fetch_json_msky::<MisskeyMeta>(&msky_meta_uri)
|
||||
.await
|
||||
|
@ -58,10 +60,12 @@ impl QueryInstance {
|
|||
#[tracing::instrument(name = "Query instance", skip(state))]
|
||||
async fn perform(self, state: JobState) -> Result<(), Error> {
|
||||
let contact_outdated = state
|
||||
.state
|
||||
.node_cache
|
||||
.is_contact_outdated(self.actor_id.clone())
|
||||
.await;
|
||||
let instance_outdated = state
|
||||
.state
|
||||
.node_cache
|
||||
.is_instance_outdated(self.actor_id.clone())
|
||||
.await;
|
||||
|
@ -123,6 +127,7 @@ impl QueryInstance {
|
|||
let avatar = state.config.generate_url(UrlKind::Media(uuid));
|
||||
|
||||
state
|
||||
.state
|
||||
.node_cache
|
||||
.set_contact(
|
||||
self.actor_id.clone(),
|
||||
|
@ -137,6 +142,7 @@ impl QueryInstance {
|
|||
let description = ammonia::clean(&description);
|
||||
|
||||
state
|
||||
.state
|
||||
.node_cache
|
||||
.set_instance(
|
||||
self.actor_id,
|
||||
|
|
|
@ -27,6 +27,7 @@ impl QueryNodeinfo {
|
|||
#[tracing::instrument(name = "Query node info", skip(state))]
|
||||
async fn perform(self, state: JobState) -> Result<(), Error> {
|
||||
if !state
|
||||
.state
|
||||
.node_cache
|
||||
.is_nodeinfo_outdated(self.actor_id.clone())
|
||||
.await
|
||||
|
@ -42,6 +43,7 @@ impl QueryNodeinfo {
|
|||
let well_known_uri = iri!(format!("{scheme}://{authority}/.well-known/nodeinfo"));
|
||||
|
||||
let well_known = match state
|
||||
.state
|
||||
.requests
|
||||
.fetch_json::<WellKnown>(&well_known_uri)
|
||||
.await
|
||||
|
@ -60,7 +62,7 @@ impl QueryNodeinfo {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let nodeinfo = match state.requests.fetch_json::<Nodeinfo>(&href).await {
|
||||
let nodeinfo = match state.state.requests.fetch_json::<Nodeinfo>(&href).await {
|
||||
Ok(nodeinfo) => nodeinfo,
|
||||
Err(e) if e.is_breaker() => {
|
||||
tracing::debug!("Not retrying due to failed breaker");
|
||||
|
@ -70,6 +72,7 @@ impl QueryNodeinfo {
|
|||
};
|
||||
|
||||
state
|
||||
.state
|
||||
.node_cache
|
||||
.set_info(
|
||||
self.actor_id.clone(),
|
||||
|
|
85
src/main.rs
85
src/main.rs
|
@ -1,17 +1,21 @@
|
|||
// need this for ructe
|
||||
#![allow(clippy::needless_borrow)]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use activitystreams::iri_string::types::IriString;
|
||||
use actix_rt::task::JoinHandle;
|
||||
use actix_web::{middleware::Compress, web, App, HttpServer};
|
||||
use collector::MemoryCollector;
|
||||
#[cfg(feature = "console")]
|
||||
use console_subscriber::ConsoleLayer;
|
||||
use error::Error;
|
||||
use http_signature_normalization_actix::middleware::VerifySignature;
|
||||
use metrics_exporter_prometheus::PrometheusBuilder;
|
||||
use metrics_util::layers::FanoutBuilder;
|
||||
use opentelemetry::{sdk::Resource, KeyValue};
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use rustls::ServerConfig;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
use tracing_error::ErrorLayer;
|
||||
|
@ -34,6 +38,8 @@ mod routes;
|
|||
mod spawner;
|
||||
mod telegram;
|
||||
|
||||
use crate::config::UrlKind;
|
||||
|
||||
use self::{
|
||||
args::Args,
|
||||
config::Config,
|
||||
|
@ -100,6 +106,38 @@ fn init_subscriber(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn build_client(
|
||||
user_agent: &str,
|
||||
timeout_seconds: u64,
|
||||
proxy: Option<(&IriString, Option<(&str, &str)>)>,
|
||||
) -> Result<ClientWithMiddleware, Error> {
|
||||
let builder = reqwest::Client::builder().user_agent(user_agent.to_string());
|
||||
|
||||
let builder = if let Some((url, auth)) = proxy {
|
||||
let proxy = reqwest::Proxy::all(url.as_str())?;
|
||||
|
||||
let proxy = if let Some((username, password)) = auth {
|
||||
proxy.basic_auth(username, password)
|
||||
} else {
|
||||
proxy
|
||||
};
|
||||
|
||||
builder.proxy(proxy)
|
||||
} else {
|
||||
builder
|
||||
};
|
||||
|
||||
let client = builder
|
||||
.timeout(Duration::from_secs(timeout_seconds))
|
||||
.build()?;
|
||||
|
||||
let client_with_middleware = reqwest_middleware::ClientBuilder::new(client)
|
||||
.with(reqwest_tracing::TracingMiddleware::default())
|
||||
.build();
|
||||
|
||||
Ok(client_with_middleware)
|
||||
}
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), anyhow::Error> {
|
||||
dotenv::dotenv().ok();
|
||||
|
@ -150,11 +188,11 @@ fn client_main(config: Config, args: Args) -> JoinHandle<Result<(), anyhow::Erro
|
|||
}
|
||||
|
||||
async fn do_client_main(config: Config, args: Args) -> Result<(), anyhow::Error> {
|
||||
let client = requests::build_client(
|
||||
let client = build_client(
|
||||
&config.user_agent(),
|
||||
config.client_pool_size(),
|
||||
config.client_timeout(),
|
||||
);
|
||||
config.proxy_config(),
|
||||
)?;
|
||||
|
||||
if !args.blocks().is_empty() || !args.allowed().is_empty() {
|
||||
if args.undo() {
|
||||
|
@ -251,15 +289,13 @@ async fn do_server_main(
|
|||
collector: MemoryCollector,
|
||||
config: Config,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let client = build_client(
|
||||
&config.user_agent(),
|
||||
config.client_timeout(),
|
||||
config.proxy_config(),
|
||||
)?;
|
||||
|
||||
tracing::warn!("Creating state");
|
||||
let state = State::build(db.clone()).await?;
|
||||
|
||||
if let Some((token, admin_handle)) = config.telegram_info() {
|
||||
tracing::warn!("Creating telegram handler");
|
||||
telegram::start(admin_handle.to_owned(), db.clone(), token);
|
||||
}
|
||||
|
||||
let keys = config.open_keys()?;
|
||||
|
||||
let (signature_threads, verify_threads) = match config.signature_threads() {
|
||||
0 | 1 => (1, 1),
|
||||
|
@ -272,26 +308,29 @@ async fn do_server_main(
|
|||
}
|
||||
};
|
||||
|
||||
let spawner = Spawner::build("sign-cpu", signature_threads)?;
|
||||
let verify_spawner = Spawner::build("verify-cpu", verify_threads)?;
|
||||
let sign_spawner = Spawner::build("sign-cpu", signature_threads)?;
|
||||
|
||||
let key_id = config.generate_url(UrlKind::MainKey).to_string();
|
||||
let state = State::build(db.clone(), key_id, sign_spawner, client).await?;
|
||||
|
||||
if let Some((token, admin_handle)) = config.telegram_info() {
|
||||
tracing::warn!("Creating telegram handler");
|
||||
telegram::start(admin_handle.to_owned(), db.clone(), token);
|
||||
}
|
||||
|
||||
let keys = config.open_keys()?;
|
||||
|
||||
let bind_address = config.bind_address();
|
||||
let server = HttpServer::new(move || {
|
||||
let requests = state.requests(&config, spawner.clone());
|
||||
|
||||
let job_server = create_workers(
|
||||
state.clone(),
|
||||
actors.clone(),
|
||||
media.clone(),
|
||||
config.clone(),
|
||||
spawner.clone(),
|
||||
);
|
||||
let job_server =
|
||||
create_workers(state.clone(), actors.clone(), media.clone(), config.clone());
|
||||
|
||||
let app = App::new()
|
||||
.app_data(web::Data::new(db.clone()))
|
||||
.app_data(web::Data::new(state.clone()))
|
||||
.app_data(web::Data::new(
|
||||
requests.clone().spawner(verify_spawner.clone()),
|
||||
state.requests.clone().spawner(verify_spawner.clone()),
|
||||
))
|
||||
.app_data(web::Data::new(actors.clone()))
|
||||
.app_data(web::Data::new(config.clone()))
|
||||
|
@ -317,7 +356,7 @@ async fn do_server_main(
|
|||
.wrap(config.digest_middleware().spawner(verify_spawner.clone()))
|
||||
.wrap(VerifySignature::new(
|
||||
MyVerify(
|
||||
requests.spawner(verify_spawner.clone()),
|
||||
state.requests.clone().spawner(verify_spawner.clone()),
|
||||
actors.clone(),
|
||||
state.clone(),
|
||||
verify_spawner.clone(),
|
||||
|
|
121
src/requests.rs
121
src/requests.rs
|
@ -5,10 +5,10 @@ use crate::{
|
|||
};
|
||||
use activitystreams::iri_string::types::IriString;
|
||||
use actix_web::http::header::Date;
|
||||
use awc::{error::SendRequestError, Client, ClientResponse, Connector};
|
||||
use base64::{engine::general_purpose::STANDARD, Engine};
|
||||
use dashmap::DashMap;
|
||||
use http_signature_normalization_actix::{digest::ring::Sha256, prelude::*};
|
||||
use http_signature_normalization_reqwest::{digest::ring::Sha256, prelude::*};
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use ring::{
|
||||
rand::SystemRandom,
|
||||
signature::{RsaKeyPair, RSA_PKCS1_SHA256},
|
||||
|
@ -18,7 +18,6 @@ use std::{
|
|||
sync::Arc,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use tracing_awc::Tracing;
|
||||
|
||||
const ONE_SECOND: u64 = 1;
|
||||
const ONE_MINUTE: u64 = 60 * ONE_SECOND;
|
||||
|
@ -139,10 +138,8 @@ impl Default for Breaker {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Requests {
|
||||
pool_size: usize,
|
||||
client: Client,
|
||||
client: ClientWithMiddleware,
|
||||
key_id: String,
|
||||
user_agent: String,
|
||||
private_key: Arc<RsaKeyPair>,
|
||||
rng: SystemRandom,
|
||||
config: Config<Spawner>,
|
||||
|
@ -153,66 +150,39 @@ pub(crate) struct Requests {
|
|||
impl std::fmt::Debug for Requests {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Requests")
|
||||
.field("pool_size", &self.pool_size)
|
||||
.field("key_id", &self.key_id)
|
||||
.field("user_agent", &self.user_agent)
|
||||
.field("config", &self.config)
|
||||
.field("breakers", &self.breakers)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CLIENT: std::cell::OnceCell<Client> = std::cell::OnceCell::new();
|
||||
}
|
||||
|
||||
pub(crate) fn build_client(user_agent: &str, pool_size: usize, timeout_seconds: u64) -> Client {
|
||||
CLIENT.with(|client| {
|
||||
client
|
||||
.get_or_init(|| {
|
||||
let connector = Connector::new().limit(pool_size);
|
||||
|
||||
Client::builder()
|
||||
.connector(connector)
|
||||
.wrap(Tracing)
|
||||
.add_default_header(("User-Agent", user_agent.to_string()))
|
||||
.timeout(Duration::from_secs(timeout_seconds))
|
||||
.finish()
|
||||
})
|
||||
.clone()
|
||||
})
|
||||
}
|
||||
|
||||
impl Requests {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
key_id: String,
|
||||
private_key: RsaPrivateKey,
|
||||
user_agent: String,
|
||||
breakers: Breakers,
|
||||
last_online: Arc<LastOnline>,
|
||||
pool_size: usize,
|
||||
timeout_seconds: u64,
|
||||
spawner: Spawner,
|
||||
client: ClientWithMiddleware,
|
||||
) -> Self {
|
||||
let private_key_der = private_key.to_pkcs1_der().expect("Can encode der");
|
||||
let private_key = ring::signature::RsaKeyPair::from_der(private_key_der.as_bytes())
|
||||
.expect("Key is valid");
|
||||
Requests {
|
||||
pool_size,
|
||||
client: build_client(&user_agent, pool_size, timeout_seconds),
|
||||
client,
|
||||
key_id,
|
||||
user_agent,
|
||||
private_key: Arc::new(private_key),
|
||||
rng: SystemRandom::new(),
|
||||
config: Config::new().mastodon_compat().spawner(spawner),
|
||||
config: Config::new_with_spawner(spawner).mastodon_compat(),
|
||||
breakers,
|
||||
last_online,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn spawner(mut self, spawner: Spawner) -> Self {
|
||||
self.config = self.config.spawner(spawner);
|
||||
self.config = self.config.set_spawner(spawner);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -223,27 +193,26 @@ impl Requests {
|
|||
async fn check_response(
|
||||
&self,
|
||||
parsed_url: &IriString,
|
||||
res: Result<ClientResponse, SendRequestError>,
|
||||
) -> Result<ClientResponse, Error> {
|
||||
res: Result<reqwest::Response, reqwest_middleware::Error>,
|
||||
) -> Result<reqwest::Response, Error> {
|
||||
if res.is_err() {
|
||||
self.breakers.fail(&parsed_url);
|
||||
}
|
||||
|
||||
let mut res =
|
||||
res.map_err(|e| ErrorKind::SendRequest(parsed_url.to_string(), e.to_string()))?;
|
||||
let res = res?;
|
||||
|
||||
if res.status().is_server_error() {
|
||||
let status = res.status();
|
||||
|
||||
if status.is_server_error() {
|
||||
self.breakers.fail(&parsed_url);
|
||||
|
||||
if let Ok(bytes) = res.body().await {
|
||||
if let Ok(s) = String::from_utf8(bytes.as_ref().to_vec()) {
|
||||
if let Ok(s) = res.text().await {
|
||||
if !s.is_empty() {
|
||||
tracing::debug!("Response from {parsed_url}, {s}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Err(ErrorKind::Status(parsed_url.to_string(), res.status()).into());
|
||||
return Err(ErrorKind::Status(parsed_url.to_string(), status).into());
|
||||
}
|
||||
|
||||
self.last_online.mark_seen(&parsed_url);
|
||||
|
@ -265,21 +234,18 @@ impl Requests {
|
|||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
{
|
||||
let mut res = self
|
||||
let body = self
|
||||
.do_deliver(
|
||||
url,
|
||||
&serde_json::json!({}),
|
||||
"application/json",
|
||||
"application/json",
|
||||
)
|
||||
.await?
|
||||
.bytes()
|
||||
.await?;
|
||||
|
||||
let body = res
|
||||
.body()
|
||||
.await
|
||||
.map_err(|e| ErrorKind::ReceiveResponse(url.to_string(), e.to_string()))?;
|
||||
|
||||
Ok(serde_json::from_slice(body.as_ref())?)
|
||||
Ok(serde_json::from_slice(&body)?)
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "Fetch Activity+Json", skip(self), fields(signing_string))]
|
||||
|
@ -294,18 +260,13 @@ impl Requests {
|
|||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
{
|
||||
let mut res = self.do_fetch_response(url, accept).await?;
|
||||
let body = self.do_fetch_response(url, accept).await?.bytes().await?;
|
||||
|
||||
let body = res
|
||||
.body()
|
||||
.await
|
||||
.map_err(|e| ErrorKind::ReceiveResponse(url.to_string(), e.to_string()))?;
|
||||
|
||||
Ok(serde_json::from_slice(body.as_ref())?)
|
||||
Ok(serde_json::from_slice(&body)?)
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "Fetch response", skip(self), fields(signing_string))]
|
||||
pub(crate) async fn fetch_response(&self, url: &IriString) -> Result<ClientResponse, Error> {
|
||||
pub(crate) async fn fetch_response(&self, url: &IriString) -> Result<reqwest::Response, Error> {
|
||||
self.do_fetch_response(url, "*/*").await
|
||||
}
|
||||
|
||||
|
@ -313,7 +274,7 @@ impl Requests {
|
|||
&self,
|
||||
url: &IriString,
|
||||
accept: &str,
|
||||
) -> Result<ClientResponse, Error> {
|
||||
) -> Result<reqwest::Response, Error> {
|
||||
if !self.breakers.should_try(url) {
|
||||
return Err(ErrorKind::Breaker.into());
|
||||
}
|
||||
|
@ -321,23 +282,18 @@ impl Requests {
|
|||
let signer = self.signer();
|
||||
let span = tracing::Span::current();
|
||||
|
||||
let res = self
|
||||
let request = self
|
||||
.client
|
||||
.get(url.as_str())
|
||||
.insert_header(("Accept", accept))
|
||||
.insert_header(Date(SystemTime::now().into()))
|
||||
.no_decompress()
|
||||
.signature(
|
||||
self.config.clone(),
|
||||
self.key_id.clone(),
|
||||
move |signing_string| {
|
||||
.header("Accept", accept)
|
||||
.header("Date", Date(SystemTime::now().into()).to_string())
|
||||
.signature(&self.config, self.key_id.clone(), move |signing_string| {
|
||||
span.record("signing_string", signing_string);
|
||||
span.in_scope(|| signer.sign(signing_string))
|
||||
},
|
||||
)
|
||||
.await?
|
||||
.send()
|
||||
.await;
|
||||
})
|
||||
.await?;
|
||||
|
||||
let res = self.client.execute(request).await;
|
||||
|
||||
let res = self.check_response(url, res).await?;
|
||||
|
||||
|
@ -369,7 +325,7 @@ impl Requests {
|
|||
item: &T,
|
||||
content_type: &str,
|
||||
accept: &str,
|
||||
) -> Result<ClientResponse, Error>
|
||||
) -> Result<reqwest::Response, Error>
|
||||
where
|
||||
T: serde::ser::Serialize + std::fmt::Debug,
|
||||
{
|
||||
|
@ -381,12 +337,12 @@ impl Requests {
|
|||
let span = tracing::Span::current();
|
||||
let item_string = serde_json::to_string(item)?;
|
||||
|
||||
let (req, body) = self
|
||||
let request = self
|
||||
.client
|
||||
.post(inbox.as_str())
|
||||
.insert_header(("Accept", accept))
|
||||
.insert_header(("Content-Type", content_type))
|
||||
.insert_header(Date(SystemTime::now().into()))
|
||||
.header("Accept", accept)
|
||||
.header("Content-Type", content_type)
|
||||
.header("Date", Date(SystemTime::now().into()).to_string())
|
||||
.signature_with_digest(
|
||||
self.config.clone(),
|
||||
self.key_id.clone(),
|
||||
|
@ -397,10 +353,9 @@ impl Requests {
|
|||
span.in_scope(|| signer.sign(signing_string))
|
||||
},
|
||||
)
|
||||
.await?
|
||||
.split();
|
||||
.await?;
|
||||
|
||||
let res = req.send_body(body).await;
|
||||
let res = self.client.execute(request).await;
|
||||
|
||||
let res = self.check_response(inbox, res).await?;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ pub(crate) async fn route(
|
|||
state: web::Data<State>,
|
||||
config: web::Data<Config>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let all_nodes = state.node_cache().nodes().await?;
|
||||
let all_nodes = state.node_cache.nodes().await?;
|
||||
|
||||
let mut nodes = Vec::new();
|
||||
let mut local = Vec::new();
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) async fn route(
|
|||
response.insert_header((name.clone(), value.clone()));
|
||||
}
|
||||
|
||||
return Ok(response.body(BodyStream::new(res)));
|
||||
return Ok(response.body(BodyStream::new(res.bytes_stream())));
|
||||
}
|
||||
|
||||
Ok(HttpResponse::NotFound().finish())
|
||||
|
|
|
@ -162,3 +162,32 @@ impl Spawn for Spawner {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl http_signature_normalization_reqwest::Spawn for Spawner {
|
||||
type Future<T> = std::pin::Pin<Box<dyn std::future::Future<Output = Result<T, http_signature_normalization_reqwest::Canceled>> + Send>> where T: Send;
|
||||
|
||||
fn spawn_blocking<Func, Out>(&self, func: Func) -> Self::Future<Out>
|
||||
where
|
||||
Func: FnOnce() -> Out + Send + 'static,
|
||||
Out: Send + 'static,
|
||||
{
|
||||
let sender = self.sender.as_ref().expect("Sender exists").clone();
|
||||
|
||||
Box::pin(async move {
|
||||
let (tx, rx) = flume::bounded(1);
|
||||
|
||||
let _ = sender
|
||||
.send_async(Box::new(move || {
|
||||
if tx.try_send((func)()).is_err() {
|
||||
tracing::warn!("Requestor hung up");
|
||||
metrics::increment_counter!("relay.spawner.disconnected");
|
||||
}
|
||||
}))
|
||||
.await;
|
||||
|
||||
timer(rx.recv_async())
|
||||
.await
|
||||
.map_err(|_| http_signature_normalization_reqwest::Canceled)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user