From 7074316257bd736e0d3393368fc93dec9604b49e Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:22:45 -0400 Subject: [PATCH] fix(@angular/build): support HTTP HEAD requests for virtual output files When using the development server, HTTP HEAD requests will now correctly respond for the virtual output files generated from the Angular build system. Previously Vite only handled GET requests for the files. While HEAD requests are not common in development workflows, it can be needed in more complex cases with additional servers/proxies/etc. during development. (cherry picked from commit f6b7cd925dacf0ae34cb8e49b4deaf2e5c52ccd4) --- .../vite/middlewares/assets-middleware.ts | 6 +++++ .../e2e/tests/commands/serve/head-request.ts | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/legacy-cli/e2e/tests/commands/serve/head-request.ts diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index 9dd93e1df516..6cc74495af29 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -63,6 +63,12 @@ export function createAngularAssetsMiddleware( return; } + // Support HTTP HEAD requests for the virtual output files from the Angular build + if (req.method === 'HEAD' && outputFiles.get(pathname)?.servable) { + // While a GET will also generate content, the rest of the response is equivalent + req.method = 'GET'; + } + // Resource files are handled directly. // Global stylesheets (CSS files) are currently considered resources to workaround // dev server sourcemap issues with stylesheets. diff --git a/tests/legacy-cli/e2e/tests/commands/serve/head-request.ts b/tests/legacy-cli/e2e/tests/commands/serve/head-request.ts new file mode 100644 index 000000000000..82ba370a0743 --- /dev/null +++ b/tests/legacy-cli/e2e/tests/commands/serve/head-request.ts @@ -0,0 +1,25 @@ +import { ngServe } from '../../../utils/project'; + +export default async function () { + const port = await ngServe(); + // HTML + await checkHeadForUrl(`http://localhost:${port}/index.html`); + // Generated JS + await checkHeadForUrl(`http://localhost:${port}/main.js`); + // Generated CSS + await checkHeadForUrl(`http://localhost:${port}/styles.css`); + // Configured asset + await checkHeadForUrl(`http://localhost:${port}/favicon.ico`); +} + +async function checkHeadForUrl(url: string): Promise { + const result = await fetch(url, { method: 'HEAD' }); + const content = await result.blob(); + + if (content.size !== 0) { + throw new Error(`Expected "size" to be "0" but got "${content.size}".`); + } + if (result.status !== 200) { + throw new Error(`Expected "status" to be "200" but got "${result.status}".`); + } +}