diff --git a/Cargo.lock b/Cargo.lock index e7dd862..7008e9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,16 @@ dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "async-trait" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atty" version = "0.2.11" @@ -130,7 +140,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -406,7 +416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "flodgatt" -version = "0.8.5" +version = "0.9.0" dependencies = [ "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -414,7 +424,7 @@ dependencies = [ "hashbrown 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "postgres-openssl 0.2.0-rc.1 (git+https://github.com/sfackler/rust-postgres.git)", "pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -710,7 +720,7 @@ dependencies = [ "h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -756,11 +766,10 @@ dependencies = [ [[package]] name = "iovec" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -908,7 +917,7 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -923,7 +932,7 @@ name = "mio-uds" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1159,7 +1168,7 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1174,15 +1183,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "postgres" -version = "0.17.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-postgres 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-postgres 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1235,7 +1244,7 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1325,7 +1334,7 @@ name = "r2d2_postgres" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1870,16 +1879,18 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.4" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1966,9 +1977,10 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1977,11 +1989,11 @@ dependencies = [ "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "postgres-protocol 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "postgres-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postgres-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2018,7 +2030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2080,7 +2092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2092,15 +2104,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2332,6 +2344,7 @@ dependencies = [ "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" +"checksum async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" @@ -2412,7 +2425,7 @@ dependencies = [ "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum input_buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b822cc844905551931d6f81608ed5f50a79c1078a4e2b4d42dbc7c1eedfbf" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -2460,14 +2473,14 @@ dependencies = [ "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" "checksum phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" +"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" -"checksum postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96dd5c8eddec65a5497798ebde2e5c74a93ef8b66782c1b09eeab9bb8538aebc" +"checksum postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18741b59a558e4dfdb9c968e8126dccbefd6a16bf54e3bc5668d420b4c4ed71b" "checksum postgres-openssl 0.2.0-rc.1 (git+https://github.com/sfackler/rust-postgres.git)" = "" "checksum postgres-protocol 0.4.1 (git+https://github.com/sfackler/rust-postgres.git)" = "" "checksum postgres-protocol 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a30f0e172ae0fb0653dbf777ad10a74b8e58d6de95a892f2e1d3e94a9df9a844" -"checksum postgres-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1dd99401779ab03bc3872f196fb02c420e76f416c850be494a6f2d67287ad" +"checksum postgres-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e634590e8812c500088d88db721195979223dabb05149f43cb50931d0ff5865d" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" @@ -2543,7 +2556,7 @@ dependencies = [ "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" "checksum tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cec6c34409089be085de9403ba2010b80e36938c9ca992c4f67f407bb13db0b1" -"checksum tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bcced6bb623d4bff3739c176c415f13c418f426395c169c9c3cd9a492c715b16" +"checksum tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" @@ -2551,7 +2564,7 @@ dependencies = [ "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" "checksum tokio-openssl 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7" "checksum tokio-postgres 0.4.0-rc.3 (git+https://github.com/sfackler/rust-postgres.git)" = "" -"checksum tokio-postgres 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c03cb0c66092269a9b280e9e4956cb23ce00b8a6b1b393f7700f7732ac4bf133" +"checksum tokio-postgres 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "524da2f17264514c854ac770177bdb810f0db7e706ae69f143d6e6828e3c4fe3" "checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" "checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" @@ -2560,7 +2573,7 @@ dependencies = [ "checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum tungstenite 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "577caf571708961603baf59d2e148d12931e0da2e4bb6c5b471dd4a524fef3aa" "checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" diff --git a/Cargo.toml b/Cargo.toml index 6ee3fe1..495047f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "flodgatt" description = "A blazingly fast drop-in replacement for the Mastodon streaming api server" -version = "0.8.5" +version = "0.9.0" authors = ["Daniel Long Sockwell "] edition = "2018" diff --git a/src/config.rs b/src/config.rs index 79e3041..227e129 100644 --- a/src/config.rs +++ b/src/config.rs @@ -26,13 +26,25 @@ pub fn merge_dotenv() -> Result<()> { let res = dotenv::from_filename(env_file); if let Ok(log_level) = env::var("RUST_LOG") { - if res.is_err() && ["warn", "info", "trace", "debug"].contains(&log_level.as_str()) { - eprintln!( - " WARN: could not load environmental variables from {:?}\n\ - {:8}Are you in the right directory? Proceeding with variables from the environment.", - env::current_dir().unwrap_or_else(|_|"./".into()).join(env_file), "" + if ["warn", "info", "trace", "debug"].contains(&log_level.as_str()) { + let env_file = env::current_dir() + .unwrap_or_else(|_| "./".into()) + .join(env_file); - ); + match res { + Err(dotenv::Error::LineParse(msg, line)) => eprintln!( + " ERROR: could not parse environmental file at {:?}\n\ + {:8}could not parse line {}, `{}`", + env_file, "", line, msg + ), + Err(dotenv::Error::Io(_)) => eprintln!( + " WARN: could not load environmental variables from {:?}\n\ + {:8}Are you in the right directory? Proceeding with variables from the environment.", + env_file, "" + ), + Err(_) => eprintln!(" ERROR: could not load environmental file at {:?}", env_file), + Ok(_) => () + } } } Ok(()) diff --git a/src/config/redis_cfg_types.rs b/src/config/redis_cfg_types.rs index 6e07063..0780377 100644 --- a/src/config/redis_cfg_types.rs +++ b/src/config/redis_cfg_types.rs @@ -20,7 +20,7 @@ from_env_var!( from_env_var!( /// How frequently to poll Redis let name = RedisInterval; - let default: Duration = Duration::from_millis(100); + let default: Duration = Duration::from_millis(10); let (env_var, allowed_values) = ("REDIS_FREQ", "a number of milliseconds"); let from_str = |s| s.parse().map(Duration::from_millis).ok(); ); diff --git a/src/request.rs b/src/request.rs index fdae7db..84c8e0b 100644 --- a/src/request.rs +++ b/src/request.rs @@ -17,6 +17,7 @@ use crate::config::Postgres; use warp::filters::BoxedFilter; use warp::http::StatusCode; use warp::path; +use warp::reply; use warp::{Filter, Rejection}; #[cfg(test)] @@ -54,7 +55,7 @@ macro_rules! parse_sse_query { }; } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct Handler { pg_conn: PgPool, } @@ -118,14 +119,23 @@ impl Handler { } pub fn err(r: Rejection) -> std::result::Result { - let json_err = match r.cause() { - Some(text) if text.to_string() == "Missing request header 'authorization'" => { - warp::reply::json(&"Error: Missing access token".to_string()) - } - Some(text) => warp::reply::json(&text.to_string()), - None => warp::reply::json(&"Error: Nonexistant endpoint".to_string()), + use StatusCode as Code; + let (msg, code) = match &r.cause().map(|s| s.to_string()).as_deref() { + Some(PgPool::BAD_TOKEN) => (PgPool::BAD_TOKEN, Code::UNAUTHORIZED), + Some(PgPool::PG_NULL) => (PgPool::PG_NULL, Code::BAD_REQUEST), + Some(PgPool::MISSING_HASHTAG) => (PgPool::MISSING_HASHTAG, Code::BAD_REQUEST), + Some(PgPool::SERVER_ERR) | Some(_) => (PgPool::SERVER_ERR, Code::INTERNAL_SERVER_ERROR), + None if r.is_not_found() => return Err(r), + + None => (PgPool::SERVER_ERR, Code::INTERNAL_SERVER_ERROR), }; - Ok(warp::reply::with_status(json_err, StatusCode::UNAUTHORIZED)) + + if code == Code::INTERNAL_SERVER_ERROR { + log::error!("Internal error: {:?}", &r); + } else { + log::info!("Request rejected: {} - {:?}", code, &r); + }; + Ok(reply::with_status(reply::json(&msg), code)) } } diff --git a/src/request/err.rs b/src/request/err.rs index 9050af9..38fe4e0 100644 --- a/src/request/err.rs +++ b/src/request/err.rs @@ -1,4 +1,5 @@ use std::fmt; + #[derive(Debug)] pub enum Error { PgPool(r2d2::Error), @@ -28,7 +29,7 @@ impl From for Error { Self::Pg(e) } } -// TODO make Timeline & TimelineErr their own top-level module + #[derive(Debug)] pub enum Timeline { MissingHashtag, diff --git a/src/request/postgres.rs b/src/request/postgres.rs index b6c621b..b143b0c 100644 --- a/src/request/postgres.rs +++ b/src/request/postgres.rs @@ -4,12 +4,14 @@ use super::timeline::{Scope, UserData}; use crate::config; use crate::Id; -use ::postgres; +use ::postgres::{self, SimpleQueryMessage}; use hashbrown::HashSet; use r2d2_postgres::PostgresConnectionManager; use std::convert::TryFrom; +#[allow(deprecated)] // one fn is deprecated, not whole module +use warp::reject; -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct PgPool { conn: r2d2::Pool>, whitelist_mode: bool, @@ -19,6 +21,11 @@ type Result = std::result::Result; type Rejectable = std::result::Result; impl PgPool { + pub(crate) const BAD_TOKEN: &'static str = "Error: Missing access token"; + pub(crate) const SERVER_ERR: &'static str = "Error: Internal server error"; + pub(crate) const PG_NULL: &'static str = "Error: Unexpected null from Postgres"; + pub(crate) const MISSING_HASHTAG: &'static str = "Error: Hashtag does not exist"; + pub(crate) fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result { let mut cfg = postgres::Config::new(); cfg.user(&pg_cfg.user) @@ -32,70 +39,93 @@ impl PgPool { cfg.connect(postgres::NoTls)?; // Test connection, letting us immediately exit with an error // when Postgres isn't running instead of timing out below let manager = PostgresConnectionManager::new(cfg, postgres::NoTls); - let pool = r2d2::Pool::builder().max_size(10).build(manager)?; Ok(Self { - conn: pool, + conn: r2d2::Pool::builder().max_size(10).build(manager)?, whitelist_mode, }) } + fn is_safe(txt: &str) -> bool { + txt.chars() + .all(|c| c.is_alphanumeric() || c == '_' || c == '-') + } + pub(crate) fn select_user(self, token: &Option) -> Rejectable { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; + let mut conn = self.conn.get().map_err(reject::custom)?; if let Some(token) = token { - let query_rows = conn - .query(" + if !Self::is_safe(token) { + Err(reject::custom(Self::BAD_TOKEN))?; + }; + + let rows = conn + .simple_query(&format!(" SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id - WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL -LIMIT 1", - &[&token.to_owned()], - ).map_err(warp::reject::custom)?; + WHERE oauth_access_tokens.token='{}' AND oauth_access_tokens.revoked_at IS NULL +LIMIT 1", &token.to_owned()) + ).map_err(reject::custom)?; - if let Some(result_columns) = query_rows.get(0) { - let id = Id(result_columns.get(1)); - let allowed_langs = result_columns - .try_get::<_, Vec<_>>(2) - .unwrap_or_default() - .into_iter() - .collect(); + let row = match rows.get(0) { + Some(postgres::SimpleQueryMessage::Row(row)) => row, + _ => Err(reject::custom(Self::PG_NULL))?, // Wildcard required by #[non_exhaustive] + }; - let mut scopes: HashSet = result_columns - .get::<_, String>(3) - .split(' ') - .filter_map(|scope| Scope::try_from(scope).ok()) - .collect(); - // We don't need to separately track read auth - it's just all three others - if scopes.contains(&Scope::Read) { - scopes = vec![Scope::Statuses, Scope::Notifications, Scope::Lists] - .into_iter() + let id = Id(get_col_or_reject(row, 1)?.parse().map_err(reject::custom)?); + + let allowed_langs: HashSet<_> = row + .try_get(2) + .map_err(reject::custom)? // looks like `Some("{en,eo,es}")` + .map_or_else(HashSet::new, |str| { + str.trim_start_matches('{') + .trim_end_matches('}') + .split(',') + .map(String::from) .collect() - } + }); - Ok(UserData { - id, - allowed_langs, - scopes, - }) - } else { - Err(warp::reject::custom("Error: Invalid access token")) + let mut scopes: HashSet = get_col_or_reject(row, 3)? + .split(' ') + .filter_map(|scope| Scope::try_from(scope).ok()) + .collect(); + // We don't need to separately track read auth - it's just all three others + if scopes.contains(&Scope::Read) { + scopes = vec![Scope::Statuses, Scope::Notifications, Scope::Lists] + .into_iter() + .collect() } + + Ok(UserData { + id, + allowed_langs, + scopes, + }) } else if self.whitelist_mode { - Err(warp::reject::custom("Error: Invalid access token")) + Err(reject::custom(Self::BAD_TOKEN)) } else { Ok(UserData::public()) } } pub(crate) fn select_hashtag_id(self, tag_name: &str) -> Rejectable { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; - conn.query("SELECT id FROM tags WHERE name = $1 LIMIT 1", &[&tag_name]) - .map_err(warp::reject::custom)? - .get(0) - .map(|row| row.get(0)) - .ok_or_else(|| warp::reject::custom("Error: Hashtag does not exist.")) + if !Self::is_safe(tag_name) { + Err(reject::custom(Self::MISSING_HASHTAG))?; + }; + + let mut conn = self.conn.get().map_err(reject::custom)?; + let rows = conn + .simple_query(&format!( + "SELECT id FROM tags WHERE name='{}' LIMIT 1", + &tag_name + )) + .map_err(reject::custom)?; + match rows.get(0).ok_or_else(|| reject::custom(Self::PG_NULL))? { + SimpleQueryMessage::Row(row) => get_col_or_reject(row, 0), + _ => Err(reject::custom(Self::MISSING_HASHTAG))?, + } + .map(|s| s.parse().map_err(reject::custom))? } /// Query Postgres for everyone the user has blocked or muted @@ -103,16 +133,21 @@ LIMIT 1", /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. pub(crate) fn select_blocked_users(self, user_id: Id) -> Rejectable> { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; - conn.query( - "SELECT target_account_id FROM blocks WHERE account_id = $1 - UNION SELECT target_account_id FROM mutes WHERE account_id = $1", - &[&*user_id], - ) - .map_err(warp::reject::custom)? + let mut conn = self.conn.get().map_err(reject::custom)?; + conn.simple_query(&format!( + "SELECT target_account_id FROM blocks WHERE account_id = {0} + UNION SELECT target_account_id FROM mutes WHERE account_id = {0}", + &*user_id + )) + .map_err(reject::custom)? .iter() - .map(|row| Ok(Id(row.get(0)))) - .collect() + .try_fold(HashSet::new(), |mut set, row| match row { + SimpleQueryMessage::Row(row) => { + set.insert(get_col_or_reject(row, 0)?.parse().map_err(reject::custom)?); + Ok(set) + } + _ => Ok(set), + }) } /// Query Postgres for everyone who has blocked the user @@ -120,15 +155,20 @@ LIMIT 1", /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. pub(crate) fn select_blocking_users(self, user_id: Id) -> Rejectable> { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; - conn.query( - "SELECT account_id FROM blocks WHERE target_account_id = $1", - &[&*user_id], - ) - .map_err(warp::reject::custom)? + let mut conn = self.conn.get().map_err(reject::custom)?; + conn.simple_query(&format!( + "SELECT account_id FROM blocks WHERE target_account_id = {}", + &*user_id + )) + .map_err(reject::custom)? .iter() - .map(|row| Ok(Id(row.get(0)))) - .collect() + .try_fold(HashSet::new(), |mut set, row| match row { + SimpleQueryMessage::Row(row) => { + set.insert(get_col_or_reject(row, 0)?.parse().map_err(reject::custom)?); + Ok(set) + } + _ => Ok(set), + }) } /// Query Postgres for all current domain blocks @@ -136,27 +176,45 @@ LIMIT 1", /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. pub(crate) fn select_blocked_domains(self, user_id: Id) -> Rejectable> { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; - conn.query( - "SELECT domain FROM account_domain_blocks WHERE account_id = $1", - &[&*user_id], - ) - .map_err(warp::reject::custom)? + let mut conn = self.conn.get().map_err(reject::custom)?; + conn.simple_query(&format!( + "SELECT domain FROM account_domain_blocks WHERE account_id = {}", + &*user_id, + )) + .map_err(reject::custom)? .iter() - .map(|row| Ok(row.get(0))) - .collect() + .try_fold(HashSet::new(), |mut set, row| match row { + SimpleQueryMessage::Row(row) => { + set.insert(get_col_or_reject(row, 0)?.to_string()); + Ok(set) + } + _ => Ok(set), + }) } /// Test whether a user owns a list pub(crate) fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable { - let mut conn = self.conn.get().map_err(warp::reject::custom)?; // For the Postgres query, `id` = list number; `account_id` = user.id - let rows = &conn - .query( - "SELECT id, account_id FROM lists WHERE id = $1 LIMIT 1", - &[&list_id], - ) - .map_err(warp::reject::custom)?; - Ok(rows.get(0).map_or(false, |row| Id(row.get(1)) == user_id)) + let mut conn = self.conn.get().map_err(reject::custom)?; + let rows = conn + .simple_query(&format!( + "SELECT id, account_id FROM lists WHERE id={} LIMIT 1", + &list_id, + )) + .map_err(reject::custom)?; + + match rows.get(0).ok_or_else(|| reject::custom(Self::PG_NULL))? { + SimpleQueryMessage::Row(row) => { + Ok(Id(get_col_or_reject(row, 1)?.parse().map_err(reject::custom)?) == user_id) + } + _ => Err(reject::custom(Self::MISSING_HASHTAG))?, + } } } + +fn get_col_or_reject(row: &postgres::row::SimpleQueryRow, col: usize) -> Rejectable<&str> { + Ok(row + .try_get(col) + .map_err(reject::custom)? + .ok_or(reject::custom(PgPool::PG_NULL))?) +} diff --git a/src/request/postgres_pool.rs b/src/request/postgres_pool.rs new file mode 100644 index 0000000..bf08d14 --- /dev/null +++ b/src/request/postgres_pool.rs @@ -0,0 +1,169 @@ +//! Postgres queries +use super::err; +use super::timeline::{Scope, UserData}; +use crate::config; +use crate::event::Id; + +use ::postgres; +use hashbrown::HashSet; +use r2d2_postgres::PostgresConnectionManager; +use std::convert::TryFrom; + +#[derive(Clone, Debug)] +pub struct PgPool { + conn: r2d2::Pool>, + whitelist_mode: bool, +} + +type Result = std::result::Result; +type Rejectable = std::result::Result; + +impl PgPool { + pub(crate) fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result { + let mut cfg = postgres::Config::new(); + log::info!( + "Connecting to postgres.\nuser: {:?}, password: {:?}", + &pg_cfg.user, + &pg_cfg.password + ); + cfg.user(&pg_cfg.user) + .host(&*pg_cfg.host.to_string()) + .port(*pg_cfg.port) + .dbname(&pg_cfg.database); + if let Some(password) = &*pg_cfg.password { + cfg.password(password); + }; + + cfg.connect(postgres::NoTls)?; // Test connection, letting us immediately exit with an error + // when Postgres isn't running instead of timing out below + let manager = PostgresConnectionManager::new(cfg, postgres::NoTls); + let pool = r2d2::Pool::builder().max_size(10).build(manager)?; + + Ok(Self { + conn: pool, + whitelist_mode, + }) + } + + pub(crate) fn select_user(self, token: &Option) -> Rejectable { + log::info!("Running `select_user`"); + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + log::info!(" got conn"); + if let Some(token) = token { + let query_rows = conn + .query(" +SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes + FROM oauth_access_tokens +INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id + WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL +LIMIT 1", + &[&token.to_owned()], + ).map_err(warp::reject::custom)?; + log::info!(" got rows"); + if let Some(result_columns) = query_rows.get(0) { + let id = Id(result_columns.get(1)); + log::info!(" got id: {:?}", id); + let allowed_langs = result_columns + .try_get::<_, Vec<_>>(2) + .unwrap_or_default() + .into_iter() + .collect(); + + let mut scopes: HashSet = result_columns + .get::<_, String>(3) + .split(' ') + .filter_map(|scope| Scope::try_from(scope).ok()) + .collect(); + // We don't need to separately track read auth - it's just all three others + if scopes.contains(&Scope::Read) { + scopes = vec![Scope::Statuses, Scope::Notifications, Scope::Lists] + .into_iter() + .collect() + } + + Ok(UserData { + id, + allowed_langs, + scopes, + }) + } else { + Err(warp::reject::custom("Error: Invalid access token")) + } + } else if self.whitelist_mode { + Err(warp::reject::custom("Error: Invalid access token")) + } else { + Ok(UserData::public()) + } + } + + pub(crate) fn select_hashtag_id(self, tag_name: &str) -> Rejectable { + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + conn.query("SELECT id FROM tags WHERE name = $1 LIMIT 1", &[&tag_name]) + .map_err(warp::reject::custom)? + .get(0) + .map(|row| row.get(0)) + .ok_or_else(|| warp::reject::custom("Error: Hashtag does not exist.")) + } + + /// Query Postgres for everyone the user has blocked or muted + /// + /// **NOTE**: because we check this when the user connects, it will not include any blocks + /// the user adds until they refresh/reconnect. + pub(crate) fn select_blocked_users(self, user_id: Id) -> Rejectable> { + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + conn.query( + "SELECT target_account_id FROM blocks WHERE account_id = $1 + UNION SELECT target_account_id FROM mutes WHERE account_id = $1", + &[&*user_id], + ) + .map_err(warp::reject::custom)? + .iter() + .map(|row| Ok(Id(row.get(0)))) + .collect() + } + + /// Query Postgres for everyone who has blocked the user + /// + /// **NOTE**: because we check this when the user connects, it will not include any blocks + /// the user adds until they refresh/reconnect. + pub(crate) fn select_blocking_users(self, user_id: Id) -> Rejectable> { + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + conn.query( + "SELECT account_id FROM blocks WHERE target_account_id = $1", + &[&*user_id], + ) + .map_err(warp::reject::custom)? + .iter() + .map(|row| Ok(Id(row.get(0)))) + .collect() + } + + /// Query Postgres for all current domain blocks + /// + /// **NOTE**: because we check this when the user connects, it will not include any blocks + /// the user adds until they refresh/reconnect. + pub(crate) fn select_blocked_domains(self, user_id: Id) -> Rejectable> { + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + conn.query( + "SELECT domain FROM account_domain_blocks WHERE account_id = $1", + &[&*user_id], + ) + .map_err(warp::reject::custom)? + .iter() + .map(|row| Ok(row.get(0))) + .collect() + } + + /// Test whether a user owns a list + pub(crate) fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable { + let mut conn = self.conn.get().map_err(warp::reject::custom)?; + // For the Postgres query, `id` = list number; `account_id` = user.id + let rows = &conn + .query( + "SELECT id, account_id FROM lists WHERE id = $1 LIMIT 1", + &[&list_id], + ) + .map_err(warp::reject::custom)?; + Ok(rows.get(0).map_or(false, |row| Id(row.get(1)) == user_id)) + } +} diff --git a/src/request/timeline/inner.rs b/src/request/timeline/inner.rs index f77fa4b..4d2e320 100644 --- a/src/request/timeline/inner.rs +++ b/src/request/timeline/inner.rs @@ -53,6 +53,7 @@ impl TryFrom<&str> for Scope { } } +#[derive(Debug, Clone)] pub(crate) struct UserData { pub(crate) id: Id, pub(crate) allowed_langs: HashSet, diff --git a/src/response/redis.rs b/src/response/redis.rs index db24126..3f44f4d 100644 --- a/src/response/redis.rs +++ b/src/response/redis.rs @@ -29,9 +29,9 @@ impl RedisCmd { .concat(), [ b"*3\r\n$3\r\nSET\r\n$", - tl.len().to_string().as_bytes(), - b"\r\n", - tl.as_bytes(), + (tl.len() + "subscribed:".len()).to_string().as_bytes(), + b"\r\nsubscribed:", + tl.to_string().as_bytes(), b"\r\n$1\r\n1\r\n", ] .concat(), @@ -47,9 +47,9 @@ impl RedisCmd { .concat(), [ b"*3\r\n$3\r\nSET\r\n$", - tl.len().to_string().as_bytes(), - b"\r\n", - tl.as_bytes(), + (tl.len() + "subscribed:".len()).to_string().as_bytes(), + b"\r\nsubscribed:", + tl.to_string().as_bytes(), b"\r\n$1\r\n0\r\n", ] .concat(), diff --git a/src/response/redis/connection.rs b/src/response/redis/connection.rs index d24eff9..557d934 100644 --- a/src/response/redis/connection.rs +++ b/src/response/redis/connection.rs @@ -63,7 +63,7 @@ impl RedisConn { } } Err(e) if matches!(e.kind(), io::ErrorKind::WouldBlock) => { - return Ok(Async::NotReady); + break; } Err(e) => break log::error!("{}", e), }; @@ -96,19 +96,18 @@ impl RedisConn { } Some(_non_matching_namespace) => (Ok(Ready(None)), msg.leftover_input), }, + Ok(NonMsg(leftover)) => (Ok(Ready(None)), leftover), Err(RedisParseErr::Incomplete) => (Ok(NotReady), input), Err(other_parse_err) => (Err(ManagerErr::RedisParseErr(other_parse_err)), input), }; - self.cursor = [leftover.as_bytes(), invalid_bytes] - .concat() - .bytes() - .fold(0, |acc, cur| { - // TODO - make clearer and comment side-effect - self.redis_input[acc] = cur.expect("TODO"); - acc + 1 - }); + // Store leftover in same buffer and set cursor to start after leftover next time + self.cursor = 0; + for byte in [leftover.as_bytes(), invalid_bytes].concat().iter() { + self.redis_input[self.cursor] = *byte; + self.cursor += 1; + } res } @@ -123,6 +122,12 @@ impl RedisConn { let (primary_cmd, secondary_cmd) = cmd.into_sendable(&tl); self.primary.write_all(&primary_cmd)?; + + // We also need to set a key to tell the Puma server that we've subscribed + // or unsubscribed to the channel because it stops publishing updates when it + // thinks no one is subscribed. (Documented in [PR + // #3278](https://github.com/tootsuite/mastodon/pull/3278)) + // Question: why can't the Puma server just use NUMSUB for this? self.secondary.write_all(&secondary_cmd)?; Ok(()) } diff --git a/src/response/stream/ws.rs b/src/response/stream/ws.rs index ed51924..4485409 100644 --- a/src/response/stream/ws.rs +++ b/src/response/stream/ws.rs @@ -53,6 +53,7 @@ impl Ws { let incoming_events = self.ws_rx.clone().map_err(|_| ()); incoming_events.for_each(move |(tl, event)| { + //TODO log::info!("{:?}, {:?}", &tl, &event); if matches!(event, Event::Ping) { self.send_msg(&event)? } else if target_timeline == tl { @@ -67,20 +68,30 @@ impl Ws { } fn send_or_filter(&mut self, tl: Timeline, event: &Event, update: &impl Payload) -> Result<()> { - let blocks = &self.subscription.blocks; - let allowed_langs = &self.subscription.allowed_langs; + let (blocks, allowed_langs) = (&self.subscription.blocks, &self.subscription.allowed_langs); const SKIP: Result<()> = Ok(()); + match tl { tl if tl.is_public() && !update.language_unset() && !allowed_langs.is_empty() && !allowed_langs.contains(&update.language()) => { + log::info!("{:?} msg skipped - disallowed language", tl); + SKIP + } + tl if !blocks.blocked_users.is_disjoint(&update.involved_users()) => { + log::info!("{:?} msg skipped - involves blocked user", tl); + SKIP + } + tl if blocks.blocking_users.contains(update.author()) => { + log::info!("{:?} msg skipped - from blocking user", tl); + SKIP + } + tl if blocks.blocked_domains.contains(update.sent_from()) => { + log::info!("{:?} msg skipped - from blocked domain", tl); SKIP } - _ if !blocks.blocked_users.is_disjoint(&update.involved_users()) => SKIP, - _ if blocks.blocking_users.contains(update.author()) => SKIP, - _ if blocks.blocked_domains.contains(update.sent_from()) => SKIP, _ => Ok(self.send_msg(&event)?), } }