diff --git a/src/error.rs b/src/error.rs index f3fceae..8a9092f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -112,6 +112,9 @@ pub enum ChorusError { // Pocket Types Error PocketType(pocket_types::Error), + // Rate limit exceeded + RateLimitExceeded, + // X-Real-Ip header is missing RealIpHeaderMissing, @@ -186,6 +189,7 @@ impl std::fmt::Display for ChorusError { ChorusError::PocketDb(e) => write!(f, "{e}"), ChorusError::PocketDbHeed(e) => write!(f, "{e}"), ChorusError::PocketType(e) => write!(f, "{e}"), + ChorusError::RateLimitExceeded => write!(f, "Rate limit exceeded"), ChorusError::ProtectedEvent => write!(f, "Protected event"), ChorusError::RealIpHeaderMissing => write!(f, "X-Real-Ip header is missing"), ChorusError::Restricted => write!(f, "Restricted"), @@ -270,6 +274,7 @@ impl ChorusError { ChorusError::PocketDb(_) => 0.0, ChorusError::PocketDbHeed(_) => 0.0, ChorusError::PocketType(_) => 0.25, + ChorusError::RateLimitExceeded => 1.0, ChorusError::ProtectedEvent => 0.35, ChorusError::RealIpHeaderMissing => 0.0, ChorusError::Restricted => 0.1, diff --git a/src/lib.rs b/src/lib.rs index eb62bdc..3cebe99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -247,6 +247,10 @@ async fn websocket_thread(peer: HashedPeer, websocket: HyperWebsocket, origin: S session_exit = SessionExit::TooManyErrors; msg = "Errored Out"; } + ChorusError::RateLimitExceeded => { + session_exit = SessionExit::TooManyErrors; // close enough for now. + msg = "Rate Limit Exceeded"; + } ChorusError::TimedOut => { session_exit = SessionExit::Timeout; msg = "Timed Out (with no subscriptions)"; @@ -437,10 +441,12 @@ impl WebSocketService { // Consume tokens, possibly closing the connection if there are not enough if message.len() > self.burst_tokens { + log::info!(target: "Client", "{}: Rate limited exceeded", self.peer); let reply = NostrReply::Notice("Rate limit exceeded.".into()); self.websocket.send(Message::text(reply.as_json())).await?; - self.error_punishment += 1.0; - return Err(ChorusError::ErrorClose.into()); + let error = ChorusError::RateLimitExceeded; + self.error_punishment += error.punishment(); + return Err(error.into()); } else { self.burst_tokens = self.burst_tokens - message.len(); }