%PDF- %PDF-
Direktori : /home/silvzytp/crm-dub-code/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ |
Current File : //home/silvzytp/crm-dub-code/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php |
<?php namespace Illuminate\Routing\Middleware; use Closure; use Illuminate\Cache\RateLimiter; use Illuminate\Cache\RateLimiting\Unlimited; use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Http\Exceptions\ThrottleRequestsException; use Illuminate\Support\Arr; use Illuminate\Support\InteractsWithTime; use RuntimeException; use Symfony\Component\HttpFoundation\Response; class ThrottleRequests { use InteractsWithTime; /** * The rate limiter instance. * * @var \Illuminate\Cache\RateLimiter */ protected $limiter; /** * Create a new request throttler. * * @param \Illuminate\Cache\RateLimiter $limiter * @return void */ public function __construct(RateLimiter $limiter) { $this->limiter = $limiter; } /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param int|string $maxAttempts * @param float|int $decayMinutes * @param string $prefix * @return \Symfony\Component\HttpFoundation\Response * * @throws \Illuminate\Http\Exceptions\ThrottleRequestsException */ public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $prefix = '') { if (is_string($maxAttempts) && func_num_args() === 3 && ! is_null($limiter = $this->limiter->limiter($maxAttempts))) { return $this->handleRequestUsingNamedLimiter($request, $next, $maxAttempts, $limiter); } return $this->handleRequest( $request, $next, [ (object) [ 'key' => $prefix.$this->resolveRequestSignature($request), 'maxAttempts' => $this->resolveMaxAttempts($request, $maxAttempts), 'decayMinutes' => $decayMinutes, 'responseCallback' => null, ], ] ); } /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string $limiterName * @param \Closure $limiter * @return \Symfony\Component\HttpFoundation\Response * * @throws \Illuminate\Http\Exceptions\ThrottleRequestsException */ protected function handleRequestUsingNamedLimiter($request, Closure $next, $limiterName, Closure $limiter) { $limiterResponse = $limiter($request); if ($limiterResponse instanceof Response) { return $limiterResponse; } elseif ($limiterResponse instanceof Unlimited) { return $next($request); } return $this->handleRequest( $request, $next, collect(Arr::wrap($limiterResponse))->map(function ($limit) use ($limiterName) { return (object) [ 'key' => md5($limiterName.$limit->key), 'maxAttempts' => $limit->maxAttempts, 'decayMinutes' => $limit->decayMinutes, 'responseCallback' => $limit->responseCallback, ]; })->all() ); } /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param array $limits * @return \Symfony\Component\HttpFoundation\Response * * @throws \Illuminate\Http\Exceptions\ThrottleRequestsException */ protected function handleRequest($request, Closure $next, array $limits) { foreach ($limits as $limit) { if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) { throw $this->buildException($request, $limit->key, $limit->maxAttempts, $limit->responseCallback); } $this->limiter->hit($limit->key, $limit->decayMinutes * 60); } $response = $next($request); foreach ($limits as $limit) { $response = $this->addHeaders( $response, $limit->maxAttempts, $this->calculateRemainingAttempts($limit->key, $limit->maxAttempts) ); } return $response; } /** * Resolve the number of attempts if the user is authenticated or not. * * @param \Illuminate\Http\Request $request * @param int|string $maxAttempts * @return int */ protected function resolveMaxAttempts($request, $maxAttempts) { if (str_contains($maxAttempts, '|')) { $maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0]; } if (! is_numeric($maxAttempts) && $request->user()) { $maxAttempts = $request->user()->{$maxAttempts}; } return (int) $maxAttempts; } /** * Resolve request signature. * * @param \Illuminate\Http\Request $request * @return string * * @throws \RuntimeException */ protected function resolveRequestSignature($request) { if ($user = $request->user()) { return sha1($user->getAuthIdentifier()); } elseif ($route = $request->route()) { return sha1($route->getDomain().'|'.$request->ip()); } throw new RuntimeException('Unable to generate the request signature. Route unavailable.'); } /** * Create a 'too many attempts' exception. * * @param \Illuminate\Http\Request $request * @param string $key * @param int $maxAttempts * @param callable|null $responseCallback * @return \Illuminate\Http\Exceptions\ThrottleRequestsException */ protected function buildException($request, $key, $maxAttempts, $responseCallback = null) { $retryAfter = $this->getTimeUntilNextRetry($key); $headers = $this->getHeaders( $maxAttempts, $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter), $retryAfter ); return is_callable($responseCallback) ? new HttpResponseException($responseCallback($request, $headers)) : new ThrottleRequestsException('Too Many Attempts.', null, $headers); } /** * Get the number of seconds until the next retry. * * @param string $key * @return int */ protected function getTimeUntilNextRetry($key) { return $this->limiter->availableIn($key); } /** * Add the limit header information to the given response. * * @param \Symfony\Component\HttpFoundation\Response $response * @param int $maxAttempts * @param int $remainingAttempts * @param int|null $retryAfter * @return \Symfony\Component\HttpFoundation\Response */ protected function addHeaders(Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null) { $response->headers->add( $this->getHeaders($maxAttempts, $remainingAttempts, $retryAfter, $response) ); return $response; } /** * Get the limit headers information. * * @param int $maxAttempts * @param int $remainingAttempts * @param int|null $retryAfter * @param \Symfony\Component\HttpFoundation\Response|null $response * @return array */ protected function getHeaders($maxAttempts, $remainingAttempts, $retryAfter = null, ?Response $response = null) { if ($response && ! is_null($response->headers->get('X-RateLimit-Remaining')) && (int) $response->headers->get('X-RateLimit-Remaining') <= (int) $remainingAttempts) { return []; } $headers = [ 'X-RateLimit-Limit' => $maxAttempts, 'X-RateLimit-Remaining' => $remainingAttempts, ]; if (! is_null($retryAfter)) { $headers['Retry-After'] = $retryAfter; $headers['X-RateLimit-Reset'] = $this->availableAt($retryAfter); } return $headers; } /** * Calculate the number of remaining attempts. * * @param string $key * @param int $maxAttempts * @param int|null $retryAfter * @return int */ protected function calculateRemainingAttempts($key, $maxAttempts, $retryAfter = null) { return is_null($retryAfter) ? $this->limiter->retriesLeft($key, $maxAttempts) : 0; } }