Kurlyk
Loading...
Searching...
No Matches
WebSocketRateLimiter.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _KURLYK_WEBSOCKET_RATE_LIMITER_HPP_INCLUDED
3#define _KURLYK_WEBSOCKET_RATE_LIMITER_HPP_INCLUDED
4
7
8namespace kurlyk {
9
14 public:
15 using time_point_t = std::chrono::steady_clock::time_point;
16
19 void set_limit(const std::vector<WebSocketConfig::RateLimitData>& rate_limits) {
20 std::lock_guard<std::mutex> lock(m_mutex);
21 m_limit_data.resize(rate_limits.size());
22 for (size_t i = 0; i < rate_limits.size(); ++i) {
23 m_limit_data[i].requests_per_period = rate_limits[i].requests_per_period;
24 m_limit_data[i].period_ms = rate_limits[i].period_ms;
25 m_limit_data[i].start_time = std::chrono::steady_clock::now();
26 }
27 }
28
32 /*
33 bool allow_request(long rate_limit_id) {
34 if (rate_limit_id < 0) return true; // No rate limit if ID is negative
35 std::lock_guard<std::mutex> lock(m_mutex);
36 if (rate_limit_id >= static_cast<long>(m_limit_data.size())) return true; // Out of bounds, allow by default
37 // Apply both the general limit (id 0) and the specific limit if applicable
38 return allow_request_impl(0) && (rate_limit_id == 0 || allow_request_impl(rate_limit_id));
39 }
40 */
41 bool allow_request(long rate_limit_id) {
42 if (rate_limit_id < 0) return true; // No rate limit if ID is negative
43 std::lock_guard<std::mutex> lock(m_mutex);
44 if (rate_limit_id >= static_cast<long>(m_limit_data.size())) return true; // Out of bounds, allow by default
45
46 // First check all applicable limits without updating counts
47 bool general_limit_allowed = check_limit(0);
48 bool specific_limit_allowed = (rate_limit_id == 0) || check_limit(rate_limit_id);
49
50 if (general_limit_allowed && specific_limit_allowed) {
51 // All limits allow the request, now update counts
52 update_limit(0);
53 if (rate_limit_id != 0) {
54 update_limit(rate_limit_id);
55 }
56 return true;
57 }
58
59 // Request is not allowed under one or more limits
60 return false;
61 }
62
63 private:
64
66 struct LimitData {
68 long period_ms = 0;
69 long count = 0;
70 time_point_t start_time = std::chrono::steady_clock::now();
71
72 LimitData() = default;
73 };
74
75 std::mutex m_mutex;
76 std::vector<LimitData> m_limit_data;
77
81 bool check_limit(long rate_limit_id) {
82 LimitData& limit_data = m_limit_data[rate_limit_id];
83 auto now = std::chrono::steady_clock::now();
84 auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(now - limit_data.start_time);
85
86 // If period has elapsed, the count will reset upon update
87 if (elapsed_time.count() >= limit_data.period_ms) {
88 return true; // Period elapsed, limit can be reset
89 }
90
91 // Check if under limit or if no limit is set (0 requests per period means unlimited)
92 if (limit_data.count < limit_data.requests_per_period ||
93 limit_data.requests_per_period == 0) {
94 return true;
95 }
96 return false;
97 }
98
101 void update_limit(long rate_limit_id) {
102 LimitData& limit_data = m_limit_data[rate_limit_id];
103 auto now = std::chrono::steady_clock::now();
104 auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(now - limit_data.start_time);
105
106 // Reset count if period has elapsed
107 if (elapsed_time.count() >= limit_data.period_ms) {
108 limit_data.start_time = now;
109 limit_data.count = 0;
110 }
111
112 ++limit_data.count;
113 }
114 };
115
116} // namespace kurlyk
117
118#endif // _KURLYK_WEBSOCKET_RATE_LIMITER_HPP_INCLUDED
Manages rate limiting for WebSocket requests based on predefined limits.
void update_limit(long rate_limit_id)
Updates the request count for the specified rate limit ID.
bool check_limit(long rate_limit_id)
Checks if a request is allowed under the specified rate limit without updating the count.
std::chrono::steady_clock::time_point time_point_t
bool allow_request(long rate_limit_id)
Checks if a request is allowed under the specified rate limit.
std::vector< LimitData > m_limit_data
Vector storing rate limit configurations.
std::mutex m_mutex
Mutex to protect shared data.
void set_limit(const std::vector< WebSocketConfig::RateLimitData > &rate_limits)
Sets the rate limits to control WebSocket request frequency.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
long requests_per_period
Maximum requests allowed per period.
long count
Number of requests made in the current period.
time_point_t start_time
Start time of the current rate limit period.
long period_ms
Duration of the rate limit period in milliseconds.