MaketRandevu/application/helpers/rate_limit_helper.php

80 lines
2.6 KiB
PHP
Raw Permalink Normal View History

<?php defined('BASEPATH') or exit('No direct script access allowed');
/* ----------------------------------------------------------------------------
* Easy!Appointments - Open Source Web Scheduler
*
* @package EasyAppointments
* @author A.Tselegidis <alextselegidis@gmail.com>
* @copyright Copyright (c) 2013 - 2020, Alex Tselegidis
* @license http://opensource.org/licenses/GPL-3.0 - GPLv3
* @link http://easyappointments.org
* @since v1.1.0
* ---------------------------------------------------------------------------- */
if (!function_exists('rate_limit')) {
/**
* Rate-limit the application requests.
*
* Example:
*
* rate_limit($CI->input->ip_address(), 100, 300);
*
* @link https://github.com/alexandrugaidei-atomate/ratelimit-codeigniter-filebased
*
* @param string $ip Client IP address.
2022-04-19 10:03:57 +03:00
* @param int $max_requests Number of allowed requests, defaults to 100.
* @param int $duration In seconds, defaults to 2 minutes.
*/
2023-03-13 11:06:18 +03:00
function rate_limit(string $ip, int $max_requests = 100, int $duration = 120): void
{
2023-03-13 11:06:18 +03:00
/** @var EA_Controller $CI */
$CI = &get_instance();
$rate_limiting = $CI->config->item('rate_limiting');
if (!$rate_limiting || is_cli()) {
return;
}
$CI->load->driver('cache', ['adapter' => 'file']);
$cache_key = str_replace(':', '', 'rate_limit_key_' . $ip);
$cache_remain_time_key = str_replace(':', '', 'rate_limit_tmp_' . $ip);
$current_time = date('Y-m-d H:i:s');
if ($CI->cache->get($cache_key) === false) {
// First request
$current_time_plus = date('Y-m-d H:i:s', strtotime('+' . $duration . ' seconds'));
$CI->cache->save($cache_key, 1, $duration);
$CI->cache->save($cache_remain_time_key, $current_time_plus, $duration * 2);
}
// Consequent request
else {
$requests = $CI->cache->get($cache_key);
$time_lost = $CI->cache->get($cache_remain_time_key);
if ($current_time > $time_lost) {
$current_time_plus = date('Y-m-d H:i:s', strtotime('+' . $duration . ' seconds'));
$CI->cache->save($cache_key, 1, $duration);
$CI->cache->save($cache_remain_time_key, $current_time_plus, $duration * 2);
} else {
$CI->cache->save($cache_key, $requests + 1, $duration);
}
$requests = $CI->cache->get($cache_key);
if ($requests > $max_requests) {
header('HTTP/1.0 429 Too Many Requests');
exit();
}
}
}
}