HandlePrecognitiveRequests.php
TLDR
This file is a middleware class that handles precognitive requests in the Illuminate\Foundation\Http\Middleware namespace.
Methods
handle
This method handles an incoming request. If the request is not attempting precognition, it appends a "Vary" header to the response. If the request is attempting precognition, it prepares for precognition by setting the "precognitive" attribute of the request and binding the appropriate dispatcher classes in the container. It then appends a "Precognition" header and the appropriate "Vary" header to the response.
prepareForPrecognition
This method prepares to handle a precognitive request by setting the "precognitive" attribute of the request and binding the appropriate dispatcher classes in the container.
appendVaryHeader
This method appends the appropriate "Vary" header to the given response. It retrieves the current "Vary" header from the response, adds "Precognition" to it, and sets the updated header in the response.
Classes
None
<?php
namespace Illuminate\Foundation\Http\Middleware;
use Illuminate\Container\Container;
use Illuminate\Foundation\Routing\PrecognitionCallableDispatcher;
use Illuminate\Foundation\Routing\PrecognitionControllerDispatcher;
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
*/
protected function appendVaryHeader($request, $response)
{
return tap($response, fn () => $response->headers->set('Vary', implode(', ', array_filter([
$response->headers->get('Vary'),
'Precognition',
]))));
}
}