<?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'];
|
}
|
}
|