<?php

namespace Gatekeeper;

use Cache;
use Gatekeeper\Alerts\BandwidthLimitApproached;
use Gatekeeper\Alerts\BandwidthLimitExceeded;
$Endpoint = $_EVENT['request']->getEndpoint();
// check endpoint bandwidth bucket (unlike requests, it can't be dripped until after the request)
if ($Endpoint->GlobalBandwidthPeriod && $Endpoint->GlobalBandwidthCount) {
    $flagKey = "alerts/endpoints/{$Endpoint->ID}/bandwidth-flagged";
    $bucket = HitBuckets::fetch("endpoints/{$Endpoint->ID}/bandwidth");
    if ($bucket && $bucket['hits'] < 0) {
        BandwidthLimitExceeded::open($Endpoint, ['request' => ['uri' => $_EVENT['request']->getUrl()], 'endpointId' => $Endpoint->ID, 'bucket' => $bucket]);
        Cache::store($flagKey, true);
        return ApiRequestHandler::throwRateError($bucket['seconds'], 'The global bandwidth limit for this endpoint has been exceeded');
    }
    if ($bucket && $Endpoint->AlertNearMaxRequests && $bucket['hits'] < (1 - $Endpoint->AlertNearMaxRequests) * $Endpoint->GlobalBandwidthCount) {
        BandwidthLimitApproached::open($Endpoint, ['request' => ['uri' => $_EVENT['request']->getUrl()], 'endpointId' => $Endpoint->ID, 'bucket' => $bucket]);
        Cache::store($flagKey, true);
    } elseif (Cache::fetch($flagKey)) {
        Cache::delete($flagKey);
        // automatically close any open alerts if there is a flag in the cache
        // TODO: maybe do this in a cron job instead?
        foreach ([BandwidthLimitExceeded::class, BandwidthLimitApproached::class] as $alertClass) {
            $OpenAlert = $alertClass::getByWhere(['Class' => $alertClass, 'EndpointID' => $Endpoint->ID, 'Status' => 'open']);
            if ($OpenAlert) {
                $OpenAlert->Status = 'closed';
                $OpenAlert->save();
            }
        }
Esempio n. 2
0
<?php

namespace Gatekeeper;

use Gatekeeper\Metrics\Metrics;
$Endpoint = $_EVENT['request']->getEndpoint();
// append metrics
$_EVENT['metrics']['endpointResponsesExecuted'] = Metrics::appendCounter("endpoints/{$Endpoint->ID}/responsesExecuted");
$_EVENT['metrics']['endpointBytesExecuted'] = Metrics::appendCounter("endpoints/{$Endpoint->ID}/bytesExecuted", $_EVENT['Transaction']->ResponseBytes);
$_EVENT['metrics']['endpointResponseTime'] = Metrics::appendAverage("endpoints/{$Endpoint->ID}/responseTime", $_EVENT['Transaction']->ResponseTime, $_EVENT['metrics']['endpointResponsesExecuted']);
// drip bandwidth bucket
if ($Endpoint->GlobalBandwidthPeriod && $Endpoint->GlobalBandwidthCount) {
    HitBuckets::drip("endpoints/{$Endpoint->ID}/bandwidth", function () use($Endpoint) {
        return ['seconds' => $Endpoint->GlobalBandwidthPeriod, 'count' => $Endpoint->GlobalBandwidthCount];
    }, $_EVENT['Transaction']->ResponseBytes);
}
<?php

namespace Gatekeeper;

use Cache;
use Gatekeeper\Alerts\RateLimitApproached;
use Gatekeeper\Alerts\RateLimitExceeded;
$Endpoint = $_EVENT['request']->getEndpoint();
// drip into endpoint requests bucket
if ($Endpoint->GlobalRatePeriod && $Endpoint->GlobalRateCount) {
    $flagKey = "alerts/endpoints/{$Endpoint->ID}/rate-flagged";
    $bucket = HitBuckets::drip("endpoints/{$Endpoint->ID}/requests", function () use($Endpoint) {
        return ['seconds' => $Endpoint->GlobalRatePeriod, 'count' => $Endpoint->GlobalRateCount];
    });
    if ($bucket['hits'] < 0) {
        RateLimitExceeded::open($Endpoint, ['request' => ['uri' => $_EVENT['request']->getUrl()], 'endpointId' => $Endpoint->ID, 'bucket' => $bucket]);
        Cache::store($flagKey, true);
        return ApiRequestHandler::throwRateError($bucket['seconds'], 'The global rate limit for this endpoint has been exceeded');
    }
    if ($Endpoint->AlertNearMaxRequests && $bucket['hits'] < (1 - $Endpoint->AlertNearMaxRequests) * $Endpoint->GlobalRateCount) {
        RateLimitApproached::open($Endpoint, ['request' => ['uri' => $_EVENT['request']->getUrl()], 'endpointId' => $Endpoint->ID, 'bucket' => $bucket]);
        Cache::store($flagKey, true);
    } elseif (Cache::fetch($flagKey)) {
        Cache::delete($flagKey);
        // automatically close any open alerts if there is a flag in the cache
        // TODO: maybe do this in a cron job instead?
        foreach ([RateLimitExceeded::class, RateLimitApproached::class] as $alertClass) {
            $OpenAlert = $alertClass::getByWhere(['Class' => $alertClass, 'EndpointID' => $Endpoint->ID, 'Status' => 'open']);
            if ($OpenAlert) {
                $OpenAlert->Status = 'closed';
                $OpenAlert->save();