Jake Vanderwerf
2026-01-01 de699440ff94e9c0d8e8b5201ee93179c085bf60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
namespace JVBase\rest;
 
use WP_REST_Request;
 
if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}
/**
 * Handles rate limiting for REST requests
 */
class RateLimiter
{
    protected string $cache_group = 'jvb_rate_limits';
    protected array $limits = [
        'GET' => ['count' => 1000, 'window' => 3600],
        'POST' => ['count' => 100, 'window' => 3600],
        'PUT' => ['count' => 100, 'window' => 3600],
        'DELETE' => ['count' => 50, 'window' => 3600]
    ];
 
    /**
     * @param WP_REST_Request $request
     *
     * @return bool
     */
    public function checkLimit(WP_REST_Request $request):bool
    {
        $key = $this->getCacheKey($request);
        $limit = $this->getLimit($request);
 
        $current = wp_cache_get($key, $this->cache_group) ?: 0;
 
        if ($current >= $limit['count']) {
            return false;
        }
 
        wp_cache_incr($key, 1, $this->cache_group);
        return true;
    }
 
    /**
     * @param WP_REST_Request $request
     *
     * @return string
     */
    protected function getCacheKey(WP_REST_Request $request):string
    {
        $ip = $request->get_header('X-Forwarded-For') ?: $_SERVER['REMOTE_ADDR'];
        $user_id = get_current_user_id();
        $method = $request->get_method();
 
        return "rate_limit:$ip:$user_id:$method";
    }
 
    protected function getLimit(WP_REST_Request $request):mixed
    {
        $method = $request->get_method();
        return $this->limits[$method] ?? $this->limits['GET'];
    }
}