<?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(); } }
<?php namespace Gatekeeper; use Gatekeeper\Endpoints\Endpoint; // detect endpoint if it has not already been set if (!$_EVENT['request']->getEndpoint()) { if (!($Endpoint = Endpoint::getFromPath($_EVENT['request']->getPathStack()))) { return ApiRequestHandler::throwNotFoundError('No endpoint was found that can handle this path'); } // trim path stack $_EVENT['request']->setPathStack(array_slice($_EVENT['request']->getPathStack(), substr_count($Endpoint->Path, '/') + 1)); // save determined endpoint to request object $_EVENT['request']->setEndpoint($Endpoint); }