rate limiting
This commit is contained in:
parent
215c806b9a
commit
ef24cfedbf
8 changed files with 322 additions and 44 deletions
265
Cargo.lock
generated
265
Cargo.lock
generated
|
@ -112,6 +112,12 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.3.0"
|
||||
|
@ -150,6 +156,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -160,6 +175,19 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
|
@ -208,25 +236,58 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.25"
|
||||
name = "futures"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -235,25 +296,35 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
|
@ -277,7 +348,25 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "governor"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c390a940a5d157878dd057c78680a33ce3415bcd05b4799509ea44210914b4d5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dashmap",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"no-std-compat",
|
||||
"nonzero_ext",
|
||||
"parking_lot",
|
||||
"quanta",
|
||||
"rand",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -401,6 +490,15 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -443,6 +541,15 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.0"
|
||||
|
@ -479,16 +586,28 @@ checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-compat"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||
|
||||
[[package]]
|
||||
name = "nonempty"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
|
||||
|
||||
[[package]]
|
||||
name = "nonzero_ext"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -603,6 +722,22 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quanta"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"libc",
|
||||
"mach",
|
||||
"once_cell",
|
||||
"raw-cpuid",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
|
@ -642,6 +777,15 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "10.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -976,6 +1120,26 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tower_governor"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6be418f6d18863291f0a7fa1da1de71495a19a54b5fb44969136f731a47e86"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"forwarded-header-value",
|
||||
"futures",
|
||||
"futures-core",
|
||||
"governor",
|
||||
"http",
|
||||
"pin-project",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
|
@ -1090,12 +1254,82 @@ dependencies = [
|
|||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -1192,6 +1426,7 @@ dependencies = [
|
|||
"tower",
|
||||
"tower-cookies",
|
||||
"tower-http",
|
||||
"tower_governor",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
|
|
@ -6,16 +6,17 @@ edition = "2021"
|
|||
[dependencies]
|
||||
tokio = { version = "1.23.0", features = ["full"] }
|
||||
axum = { version = "0.6.4", features = ["headers"] }
|
||||
axum-client-ip = "0.3.1"
|
||||
tower-http = { version = "0.3.5", features = ["fs"] }
|
||||
tower_governor = "0.0.4"
|
||||
tower-cookies = "0.8.0"
|
||||
tower = "0.4.13"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = "0.3.16"
|
||||
bytes = "1.3.0"
|
||||
axum-client-ip = "0.3.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0", features = ["std"] }
|
||||
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
||||
rand = "0.8.5"
|
||||
time = "0.3.17"
|
||||
lazy_static = "1.4.0"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = "0.3.16"
|
||||
lazy_static = "1.4.0"
|
|
@ -15,7 +15,7 @@ function header(home, people, user_id) {
|
|||
</a>
|
||||
</div>
|
||||
<a class="pfp" id="profile" hreF="profile">
|
||||
${pfp(user_id)}
|
||||
${user_id === undefined ? '' : pfp(user_id)}
|
||||
</a>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
|
|
|
@ -243,7 +243,12 @@ async function load() {
|
|||
}
|
||||
|
||||
async function init() {
|
||||
data.user = (await loadself()).json
|
||||
let request = (await loadself());
|
||||
if (request.status === 429) {
|
||||
header(true, false)
|
||||
throw new Error("Rate limited");
|
||||
}
|
||||
data.user = request.json
|
||||
header(true, false, data.user.user_id)
|
||||
data.users[data.user.user_id] = data.user
|
||||
const posts = await load()
|
||||
|
|
|
@ -48,7 +48,12 @@ async function loadMore() {
|
|||
}
|
||||
|
||||
async function load() {
|
||||
const self = (await loadself()).json
|
||||
let request = await loadself()
|
||||
if (request.status === 429) {
|
||||
header(false, true)
|
||||
throw new Error("Rate limited");
|
||||
}
|
||||
const self = request.json
|
||||
header(false, true, self.user_id)
|
||||
const users = (await loaduserspage(page)).json
|
||||
if (users.length === 0) {
|
||||
|
|
|
@ -89,7 +89,14 @@ async function load() {
|
|||
params[key] = value
|
||||
}
|
||||
|
||||
data.self = (await loadself()).json;
|
||||
let request = await loadself()
|
||||
|
||||
if (request.status === 429) {
|
||||
header(false, false)
|
||||
throw new Error("Rate limited");
|
||||
}
|
||||
|
||||
data.self = request.json;
|
||||
data.users[data.self.user_id] = data.self
|
||||
let id;
|
||||
|
||||
|
|
|
@ -1,5 +1,48 @@
|
|||
use crate::types::extract::RouterURI;
|
||||
use axum::{Extension, Router, BoxError, error_handling::HandleErrorLayer};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer, errors::display_error, key_extractor::SmartIpKeyExtractor};
|
||||
|
||||
pub mod admin;
|
||||
pub mod auth;
|
||||
pub mod pages;
|
||||
pub mod posts;
|
||||
pub mod users;
|
||||
|
||||
pub fn router() -> Router {
|
||||
let governor_conf = Box::new(
|
||||
GovernorConfigBuilder::default()
|
||||
.burst_size(10)
|
||||
.per_second(1)
|
||||
.key_extractor(SmartIpKeyExtractor)
|
||||
.finish()
|
||||
.expect("Failed to create rate limiter"),
|
||||
);
|
||||
|
||||
Router::new()
|
||||
.nest(
|
||||
"/admin",
|
||||
admin::router().layer(Extension(RouterURI("/api/admin"))),
|
||||
)
|
||||
.nest(
|
||||
"/auth",
|
||||
auth::router().layer(Extension(RouterURI("/api/auth"))),
|
||||
)
|
||||
.nest(
|
||||
"/users",
|
||||
users::router().layer(Extension(RouterURI("/api/users"))),
|
||||
)
|
||||
.nest(
|
||||
"/posts",
|
||||
posts::router().layer(Extension(RouterURI("/api/posts"))),
|
||||
)
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(HandleErrorLayer::new(|e: BoxError| async move {
|
||||
display_error(e)
|
||||
}))
|
||||
.layer(GovernorLayer {
|
||||
config: Box::leak(governor_conf),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -3,7 +3,7 @@ use axum::{
|
|||
http::{Request, StatusCode},
|
||||
middleware::{self, Next},
|
||||
response::Response,
|
||||
Extension, RequestExt, Router,
|
||||
RequestExt, Router,
|
||||
};
|
||||
use axum_client_ip::ClientIp;
|
||||
use std::{net::SocketAddr, process::exit};
|
||||
|
@ -14,10 +14,7 @@ use tracing_subscriber::{
|
|||
};
|
||||
use types::http::ResponseCode;
|
||||
|
||||
use crate::{
|
||||
api::{auth, pages, posts, users},
|
||||
types::extract::RouterURI,
|
||||
};
|
||||
use crate::api::pages;
|
||||
|
||||
mod admin;
|
||||
mod api;
|
||||
|
@ -77,22 +74,7 @@ async fn main() {
|
|||
.layer(middleware::from_fn(log))
|
||||
.layer(middleware::from_fn(serve))
|
||||
.nest("/", pages::router())
|
||||
.nest(
|
||||
"/api/admin",
|
||||
api::admin::router().layer(Extension(RouterURI("/api/admin"))),
|
||||
)
|
||||
.nest(
|
||||
"/api/auth",
|
||||
auth::router().layer(Extension(RouterURI("/api/auth"))),
|
||||
)
|
||||
.nest(
|
||||
"/api/users",
|
||||
users::router().layer(Extension(RouterURI("/api/users"))),
|
||||
)
|
||||
.nest(
|
||||
"/api/posts",
|
||||
posts::router().layer(Extension(RouterURI("/api/posts"))),
|
||||
)
|
||||
.nest("/api", api::router())
|
||||
.layer(CookieManagerLayer::new());
|
||||
|
||||
let Ok(addr) = "[::]:8080".parse::<std::net::SocketAddr>() else {
|
||||
|
|
Loading…
Reference in a new issue