File size: 2.43Kb
<?php
namespace Illuminate\Foundation\Http\Middleware;
use Illuminate\Container\Container;
use Illuminate\Foundation\Routing\PrecognitionCallableDispatcher;
use Illuminate\Foundation\Routing\PrecognitionControllerDispatcher;
use Illuminate\Http\Response;
use Illuminate\Routing\Contracts\CallableDispatcher as CallableDispatcherContract;
use Illuminate\Routing\Contracts\ControllerDispatcher as ControllerDispatcherContract;
class HandlePrecognitiveRequests
{
/**
* The container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* Create a new middleware instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, $next)
{
if (! $request->isAttemptingPrecognition()) {
return $this->appendVaryHeader($request, $next($request));
}
$this->prepareForPrecognition($request);
return tap($next($request), function ($response) use ($request) {
$response->headers->set('Precognition', 'true');
$this->appendVaryHeader($request, $response);
});
}
/**
* Prepare to handle a precognitive request.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function prepareForPrecognition($request)
{
$request->attributes->set('precognitive', true);
$this->container->bind(CallableDispatcherContract::class, fn ($app) => new PrecognitionCallableDispatcher($app));
$this->container->bind(ControllerDispatcherContract::class, fn ($app) => new PrecognitionControllerDispatcher($app));
}
/**
* Append the appropriate "Vary" header to the given response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Response $response
* @return \Illuminate\Http\Response $response
*/
protected function appendVaryHeader($request, $response)
{
return tap($response, fn () => $response->headers->set('Vary', implode(', ', array_filter([
$response->headers->get('Vary'),
'Precognition',
]))));
}
}