Skip to content

Commit 70a3517

Browse files
committed
fix(@angular-devkit/build-angular): correctly respond to preflight requests
With this commit, we add a middleware that handles preflight requests as currently responses for this type of requests returning 404. This is a temporary workaround until this issue is fixed upstream. See: webpack/webpack-dev-server#4180 Closes #23639
1 parent 5677bee commit 70a3517

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { serveWebpackBrowser } from '../../index';
10+
import { executeOnceAndFetch } from '../execute-fetch';
11+
import {
12+
BASE_OPTIONS,
13+
DEV_SERVER_BUILDER_INFO,
14+
describeBuilder,
15+
setupBrowserTarget,
16+
} from '../setup';
17+
18+
describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
19+
describe('Behavior: "Preflight (OPTIONS) request"', () => {
20+
beforeEach(async () => {
21+
setupBrowserTarget(harness);
22+
23+
// Application code is not needed for these tests
24+
await harness.writeFile('src/main.ts', '');
25+
});
26+
27+
it('responds with correct status and content-length', async () => {
28+
harness.useTarget('serve', {
29+
...BASE_OPTIONS,
30+
});
31+
32+
const { result, response } = await executeOnceAndFetch(harness, '/', {
33+
request: { method: 'OPTIONS' },
34+
});
35+
36+
expect(result?.success).toBeTrue();
37+
expect(response?.status).toBe(204);
38+
expect(response?.size).toBe(0);
39+
});
40+
});
41+
});

packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/disable-host-check_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
4242
it('does not allow an invalid host when option is false', async () => {
4343
harness.useTarget('serve', {
4444
...BASE_OPTIONS,
45-
disableHostCheck: false,
45+
disableHostCheck: true,
4646
});
4747

4848
const { result, response } = await executeOnceAndFetch(harness, '/', {

packages/angular_devkit/build_angular/src/webpack/configs/dev-server.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import { existsSync, promises as fsPromises } from 'fs';
1111
import { extname, posix, resolve } from 'path';
1212
import { URL, pathToFileURL } from 'url';
1313
import { Configuration, RuleSetRule } from 'webpack';
14-
import { Configuration as DevServerConfiguration } from 'webpack-dev-server';
14+
import type {
15+
Configuration as DevServerConfiguration,
16+
NextFunction,
17+
Request,
18+
Response,
19+
} from 'webpack-dev-server';
1520
import { WebpackConfigOptions, WebpackDevServerOptions } from '../../utils/build-options';
1621
import { assertIsError } from '../../utils/error';
1722
import { loadEsmModule } from '../../utils/load-esm';
@@ -87,6 +92,26 @@ export async function getDevServerConfig(
8792
publicPath: servePath,
8893
stats: false,
8994
},
95+
setupMiddlewares: (middlewares, _devServer) => {
96+
// Temporary workaround for https://github.com/webpack/webpack-dev-server/issues/4180
97+
middlewares.push({
98+
name: 'options-request-response',
99+
path: '*',
100+
middleware: (req: Request, res: Response, next: NextFunction) => {
101+
if (req.method === 'OPTIONS') {
102+
res.statusCode = 204;
103+
res.setHeader('Content-Length', 0);
104+
res.end();
105+
106+
return;
107+
}
108+
109+
next();
110+
},
111+
});
112+
113+
return middlewares;
114+
},
90115
liveReload,
91116
hot: hmr && !liveReload ? 'only' : hmr,
92117
proxy: await addProxyConfig(root, proxyConfig),

0 commit comments

Comments
 (0)