Open sidebar
<?php /** * NOTICE OF LICENSE * * UNIT3D is open-sourced software licensed under the GNU General Public License v3.0 * The details is bundled with this project in the file LICENSE.txt. * * @project UNIT3D * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 * @author HDVinnie */ namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Http\Response; use Symfony\Component\DomCrawler\Crawler; class Http2ServerPush { /** * The DomCrawler instance. * * @var \Symfony\Component\DomCrawler\Crawler */ protected $crawler; /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * * @return mixed */ public function handle(Request $request, Closure $next, $limit = null) { $response = $next($request); if ($response->isRedirection() || !$response instanceof Response || $request->isJson()) { return $response; } $this->generateAndAttachLinkHeaders($response, $limit); return $response; } /** * @param \Illuminate\Http\Response $response * * @return $this */ protected function generateAndAttachLinkHeaders(Response $response, $limit = null) { $headers = $this->fetchLinkableNodes($response) ->flatten(1) ->map(function ($url) { return $this->buildLinkHeaderString($url); }) ->filter() ->take($limit) ->implode(','); if (!empty(trim($headers))) { $this->addLinkHeader($response, $headers); } return $this; } /** * Get the DomCrawler instance. * * @param \Illuminate\Http\Response $response * * @return \Symfony\Component\DomCrawler\Crawler */ protected function getCrawler(Response $response) { if ($this->crawler) { return $this->crawler; } return $this->crawler = new Crawler($response->getContent()); } /** * Get all nodes we are interested in pushing. * * @param \Illuminate\Http\Response $response * * @return \Illuminate\Support\Collection */ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); return collect($crawler->filter('link, script[src]')->extract(['src', 'href'])); } /** * Build out header string based on asset extension. * * @param string $url * * @return string */ private function buildLinkHeaderString($url) { $linkTypeMap = [ '.CSS' => 'style', '.JS' => 'script', ]; $type = collect($linkTypeMap)->first(function ($type, $extension) use ($url) { return str_contains(strtoupper($url), $extension); }); return is_null($type) ? null : "<{$url}>; rel=preload; as={$type}"; } /** * Add Link Header * * @param \Illuminate\Http\Response $response * * @param $link */ private function addLinkHeader(Response $response, $link) { if ($response->headers->get('Link')) { $link = $response->headers->get('Link') . ',' . $link; } $response->header('Link', $link); } }
Close sidebar
Back
Please note that all pasted data is publicly available.
X (fomerly Twitter)
GitHub
Use setting
Back
Please note that all pasted data is publicly available.
X (fomerly Twitter)
GitHub
Use setting