From a4d6577329a6ecae3e50c86cfc8f33f33fc4db8e Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Tue, 24 May 2022 14:26:24 +0200 Subject: [PATCH 01/14] Laravel 9 support --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 75de367..0d45dc3 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,14 @@ } ], "require": { - "php" : "^7.0|^8.0", - "illuminate/support": "~6.0|~7.0|~8.0", - "illuminate/http": "~6.0|~7.0|~8.0", - "symfony/dom-crawler": "^2.7|^3.0|^4.0|^5.0", - "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0" + "php" : "^7.0|^8.0|^8.1", + "illuminate/support": "~6.0|~7.0|~8.0|~9.0", + "illuminate/http": "~6.0|~7.0|~8.0|~9.0", + "symfony/dom-crawler": "^2.7|^3.0|^4.0|^5.0|^6.0", + "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0|^6.0" }, "require-dev": { - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^9.5", "scrutinizer/ocular": "^1.1" }, "autoload": { From 36520f464f8a8c91ad5bace142fc57dbcf08ee4f Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Tue, 24 May 2022 15:40:00 +0200 Subject: [PATCH 02/14] Auto registering and config fix --- composer.json | 7 +++++++ src/ServiceProvider.php | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 0d45dc3..461d003 100644 --- a/composer.json +++ b/composer.json @@ -39,5 +39,12 @@ }, "scripts": { "test": "phpunit" + }, + "extra": { + "laravel": { + "providers": [ + "JacobBennett\\Http2ServerPush\\ServiceProvider" + ] + } } } diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 2f37cea..ee93eb6 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -1,4 +1,4 @@ -publishes([ - __DIR__ . '/config.php' => config_path('http2serverpush.php'), - ]); + $this->mergeConfigFrom(__DIR__.'/config.php', 'http2serverpush'); + + // Register paths to be published by 'vendor:publish' Artisan command + $this->publishes([ + __DIR__ . '/config.php' => config_path('http2serverpush.php'), + ], 'config'); } } From a511afcd3e6764eba380cc55053eb3da59a8d35e Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Tue, 24 May 2022 15:41:11 +0200 Subject: [PATCH 03/14] Default headers support --- src/Middleware/AddHttp2ServerPush.php | 3 ++- src/config.php | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 23db2ee..37c03f6 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -69,7 +69,8 @@ protected function generateAndAttachLinkHeaders(Response $response, $limit = nul } return !preg_match('%('.$exclude_keywords->implode('|').')%i', $value); }) - ->take($limit); + ->take($limit) + ->merge($this->getConfig('default_headers', [])); $sizeLimit = $sizeLimit ?? max(1, intval($this->getConfig('size_limit', 32*1024))); $headersText = trim($headers->implode(',')); diff --git a/src/config.php b/src/config.php index 28e0206..2998a36 100644 --- a/src/config.php +++ b/src/config.php @@ -4,5 +4,8 @@ return [ 'size_limit' => '6000', // in bytes 'base_path' => '/', - 'exclude_keywords' => [] + 'exclude_keywords' => [], + 'default_headers' => [ + // '; rel=preload; as=style', + ], ]; From 6b8b8dade416135710af7d12a0f49c20d1db22ac Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Tue, 24 May 2022 15:41:26 +0200 Subject: [PATCH 04/14] Do not include lazy loaded images --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 37c03f6..69e7127 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -113,7 +113,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]), script[src], img[src], object[data]')->extract(['src', 'href', 'data'])); + return collect($crawler->filter('link:not([rel*="icon"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); } /** From 11479dc64c645913146a64f3ed818ddfa3cdc8c3 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Tue, 24 May 2022 15:41:44 +0200 Subject: [PATCH 05/14] Mark woff as font --- src/Middleware/AddHttp2ServerPush.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 69e7127..3059760 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -126,15 +126,17 @@ protected function fetchLinkableNodes($response) private function buildLinkHeaderString($url) { $linkTypeMap = [ - '.CSS' => 'style', - '.JS' => 'script', - '.BMP' => 'image', - '.GIF' => 'image', - '.JPG' => 'image', - '.JPEG' => 'image', - '.PNG' => 'image', - '.SVG' => 'image', - '.TIFF' => 'image', + '.CSS' => 'style', + '.JS' => 'script', + '.BMP' => 'image', + '.GIF' => 'image', + '.JPG' => 'image', + '.JPEG' => 'image', + '.PNG' => 'image', + '.SVG' => 'image', + '.TIFF' => 'image', + '.WOFF' => 'font', + '.WOFF2' => 'font', ]; $type = collect($linkTypeMap)->first(function ($type, $extension) use ($url) { From 142d3497fd0fba67469763496019f660855587c0 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Fri, 19 Aug 2022 10:02:13 +0200 Subject: [PATCH 06/14] Exclude preconnect links --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 3059760..bebf4e3 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -113,7 +113,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); } /** From a08ab5e1315bd777fc06f3adf2d071e04e00b979 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Fri, 19 Aug 2022 10:44:38 +0200 Subject: [PATCH 07/14] Exclude canonical links --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index bebf4e3..9615cd8 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -113,7 +113,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); } /** From a6ce55ed419ef39ca211e079db3a8e2c2297ff4e Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Fri, 19 Aug 2022 10:49:55 +0200 Subject: [PATCH 08/14] Exclude manifest links --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 9615cd8..85ddec1 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -113,7 +113,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); } /** From 283e65c1ae00c5623c97fc8abee22440e71856d2 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Fri, 19 Aug 2022 10:51:50 +0200 Subject: [PATCH 09/14] Webp support --- src/Middleware/AddHttp2ServerPush.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 85ddec1..7539d65 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -135,6 +135,7 @@ private function buildLinkHeaderString($url) '.PNG' => 'image', '.SVG' => 'image', '.TIFF' => 'image', + '.WEBP' => 'image', '.WOFF' => 'font', '.WOFF2' => 'font', ]; From a41255a44149ce9653d43619078ba74f388c3b39 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Fri, 14 Oct 2022 10:44:46 +0200 Subject: [PATCH 10/14] Crossorigin for fonts --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 7539d65..702e0df 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -153,7 +153,7 @@ private function buildLinkHeaderString($url) $url = $basePath . ltrim($url, $basePath); } - return is_null($type) ? null : "<{$url}>; rel=preload; as={$type}"; + return is_null($type) ? null : "<{$url}>; rel=preload; as={$type}" . ($type == 'font' ? '; crossorigin' : ''); } /** From d3e497afd6577b2dcb68b87a4d7bd77950727c16 Mon Sep 17 00:00:00 2001 From: indykoning <15870933+indykoning@users.noreply.github.com> Date: Fri, 2 Dec 2022 14:54:45 +0100 Subject: [PATCH 11/14] Support modulepreload rel (#1) --- src/Middleware/AddHttp2ServerPush.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 702e0df..99991ab 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -54,9 +54,15 @@ protected function generateAndAttachLinkHeaders(Response $response, $limit = nul { $excludeKeywords = $excludeKeywords ?? $this->getConfig('exclude_keywords', []); $headers = $this->fetchLinkableNodes($response) - ->flatten(1) - ->map(function ($url) { - return $this->buildLinkHeaderString($url); + ->flatMap(function ($element) { + list($src, $href, $data, $rel, $type) = $element; + $rel = $type === 'module' ? 'modulepreload' : $rel; + + return [ + $this->buildLinkHeaderString($src ?? '', $rel ?? null), + $this->buildLinkHeaderString($href ?? '', $rel ?? null), + $this->buildLinkHeaderString($data ?? '', $rel ?? null), + ]; }) ->unique() ->filter(function($value, $key) use ($excludeKeywords){ @@ -113,7 +119,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type'])); } /** @@ -123,7 +129,7 @@ protected function fetchLinkableNodes($response) * * @return string */ - private function buildLinkHeaderString($url) + private function buildLinkHeaderString($url, $rel = 'preload') { $linkTypeMap = [ '.CSS' => 'style', @@ -152,8 +158,12 @@ private function buildLinkHeaderString($url) $basePath = $this->getConfig('base_path', '/'); $url = $basePath . ltrim($url, $basePath); } + + if(!in_array($rel, ['preload', 'modulepreload'])) { + $rel = 'preload'; + } - return is_null($type) ? null : "<{$url}>; rel=preload; as={$type}" . ($type == 'font' ? '; crossorigin' : ''); + return is_null($type) ? null : "<{$url}>; rel={$rel}; as={$type}" . ($type == 'font' ? '; crossorigin' : ''); } /** From 2cf8bc6d2e658aaf89012fd7daf944574b026725 Mon Sep 17 00:00:00 2001 From: indykoning <15870933+indykoning@users.noreply.github.com> Date: Mon, 6 Feb 2023 14:20:26 +0100 Subject: [PATCH 12/14] Skip images within picture (#2) --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 99991ab..7a38bc2 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -119,7 +119,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], *:not(picture)>img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type'])); } /** From e27e5f2ecbc12a5e37e0371347147dd0d4982d5d Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 15 Nov 2023 16:22:07 +0100 Subject: [PATCH 13/14] Laravel 10 support --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 461d003..7314d60 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ } ], "require": { - "php" : "^7.0|^8.0|^8.1", - "illuminate/support": "~6.0|~7.0|~8.0|~9.0", - "illuminate/http": "~6.0|~7.0|~8.0|~9.0", + "php" : "^7.0|^8.0|^8.1|^8.2", + "illuminate/support": "~6.0|~7.0|~8.0|~9.0|~10.0", + "illuminate/http": "~6.0|~7.0|~8.0|~9.0|~10.0", "symfony/dom-crawler": "^2.7|^3.0|^4.0|^5.0|^6.0", "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0|^6.0" }, From efbbad64df1677ba80383768c6b205ef5e2c3f58 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 15 Nov 2023 16:29:57 +0100 Subject: [PATCH 14/14] Skip rel alternate --- src/Middleware/AddHttp2ServerPush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AddHttp2ServerPush.php b/src/Middleware/AddHttp2ServerPush.php index 7a38bc2..06b31e2 100644 --- a/src/Middleware/AddHttp2ServerPush.php +++ b/src/Middleware/AddHttp2ServerPush.php @@ -119,7 +119,7 @@ protected function fetchLinkableNodes($response) { $crawler = $this->getCrawler($response); - return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]), script[src], *:not(picture)>img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type'])); + return collect($crawler->filter('link:not([rel*="icon"]):not([rel="preconnect"]):not([rel="canonical"]):not([rel="manifest"]):not([rel="alternate"]), script[src], *:not(picture)>img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type'])); } /**