PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.41
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.41
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Http / Middleware / RateLimiter.php

RateLimiter.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.41, at vendor/wpfluent/framework/src/WPFluent/Http/Middleware/RateLimiter.php

172 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Http\Middleware;
4
5 use FluentBoards\Framework\Foundation\App;
6
7 class RateLimiter
8 {
9 /**
10 * The maximum number of requests allowed within the interval.
11 *
12 * @var int
13 */
14 protected $limit;
15
16 /**
17 * The time interval for the rate limit in seconds.
18 *
19 * @var int
20 */
21 protected $interval;
22
23 /**
24 * Constructor to initialize the rate limiter.
25 *
26 * @param int $limit Maximum number of requests allowed.
27 * @param int $interval Time interval for the rate limit in seconds.
28 */
29 public function __construct($limit, $interval)
30 {
31 $this->limit = $limit;
32 $this->interval = $interval;
33 }
34
35 /**
36 * Handle an incoming request and apply rate limiting.
37 *
38 * @param \FluentBoards\Framework\Http\Request $request
39 * @param callable $next
40 *
41 * @return mixed
42 */
43 public function handle($request, $next)
44 {
45 if ($this->shouldAllow($request)) {
46 return $next($request);
47 }
48
49 $settings = $this->getSettings($request, $currentTime = time());
50
51 if ($this->isIntervalExpired($settings, $currentTime)) {
52 $settings = $this->resetRateLimit($currentTime);
53 } else {
54 $settings['count']++;
55 }
56
57 $this->updateSettings($request, $settings);
58
59 if ($this->isRateLimitExceeded($settings)) {
60 return $request->abort(429, 'Too many requests.');
61 }
62
63 return $next($request);
64 }
65
66 /**
67 * Determine if the request should bypass rate limiting.
68 *
69 * @param \FluentBoards\Framework\Http\Request $request
70 *
71 * @return bool
72 */
73 protected function shouldAllow($request)
74 {
75 return is_user_logged_in() || in_array(
76 $request->method(), ['HEAD', 'OPTIONS']
77 );
78 }
79
80 /**
81 * Get the current rate limit settings for the request.
82 *
83 * @param \FluentBoards\Framework\Http\Request $request
84 * @param int $currentTime
85 *
86 * @return array
87 */
88 protected function getSettings($request, $currentTime)
89 {
90 $settings = $this->getTransient($request);
91 return $settings ?: ['count' => 0, 'firstTime' => $currentTime];
92 }
93
94 /**
95 * Check if the rate limit interval has expired.
96 *
97 * @param array $settings
98 * @param int $currentTime
99 *
100 * @return bool
101 */
102 protected function isIntervalExpired($settings, $currentTime)
103 {
104 return ($currentTime - $settings['firstTime']) > $this->interval;
105 }
106
107 /**
108 * Reset the rate limit for a new interval.
109 *
110 * @param int $currentTime
111 *
112 * @return array
113 */
114 protected function resetRateLimit($currentTime)
115 {
116 return ['count' => 1, 'firstTime' => $currentTime];
117 }
118
119 /**
120 * Check if the rate limit has been exceeded.
121 *
122 * @param array $settings
123 *
124 * @return bool
125 */
126 protected function isRateLimitExceeded($settings)
127 {
128 return $settings['count'] > $this->limit;
129 }
130
131 /**
132 * Retrieve the transient data for the current request's rate limit.
133 *
134 * @param \FluentBoards\Framework\Http\Request $request
135 *
136 * @return array|null
137 */
138 protected function getTransient($request)
139 {
140 return get_transient($this->makeTransientKey($request));
141 }
142
143 /**
144 * Update the rate limit settings in the transient storage.
145 *
146 * @param \FluentBoards\Framework\Http\Request $request
147 * @param array $settings
148 *
149 * @return void
150 */
151 protected function updateSettings($request, $settings)
152 {
153 $key = $this->makeTransientKey($request);
154
155 set_transient($key, $settings, $this->interval);
156 }
157
158 /**
159 * Generate a unique transient key for the current request.
160 *
161 * @param \FluentBoards\Framework\Http\Request $request
162 *
163 * @return string
164 */
165 protected function makeTransientKey($request)
166 {
167 $slug = App::config()->get('app.slug');
168
169 return "{$slug}_rate_limit_" . md5($request->getIp());
170 }
171 }
172