From 148dcc287b59043a643a11c43c2556d1a2cb04d4 Mon Sep 17 00:00:00 2001 From: Kharec Date: Sat, 30 May 2026 15:38:34 +0200 Subject: [PATCH] fix: correct rate limit refresh --- src/storage.gleam | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/storage.gleam b/src/storage.gleam index d278686..10a0b96 100644 --- a/src/storage.gleam +++ b/src/storage.gleam @@ -1,12 +1,19 @@ import gleam/dict.{type Dict} +import gleam/erlang import gleam/erlang/process import gleam/option.{type Option} import gleam/otp/actor +import gleam/result const max_requests_per_minute = 10 +const rate_limit_window_seconds = 60 + pub type StorageState { - StorageState(pastes: Dict(String, String), rate_limits: Dict(String, Int)) + StorageState( + pastes: Dict(String, String), + rate_limits: Dict(String, #(Int, Int)), + ) } pub type StorageMsg { @@ -39,16 +46,20 @@ pub fn handle_message(state: StorageState, msg: StorageMsg) { actor.continue(StorageState(new_pastes, state.rate_limits)) } CheckRateLimit(ip, reply) -> { - let count = + let now = erlang.system_time(erlang.Second) + let #(count, window_start) = state.rate_limits |> dict.get(ip) - |> option.from_result - |> option.unwrap(0) + |> result.unwrap(#(0, now)) + let #(count, window_start) = case now - window_start >= rate_limit_window_seconds { + True -> #(0, now) + False -> #(count, window_start) + } let allowed = count < max_requests_per_minute let new_limits = case allowed { True -> state.rate_limits - |> dict.insert(ip, count + 1) + |> dict.insert(ip, #(count + 1, window_start)) False -> state.rate_limits } process.send(reply, allowed)