Skip to content

Commit a8b39c2

Browse files
committed
fix: fix the 4180 issue, under the optionsMethod option.
1 parent 72cdfa4 commit a8b39c2

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

lib/Server.js

+26
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ const schema = require("./options.json");
200200
* @property {boolean} [setupExitSignals]
201201
* @property {boolean | ClientConfiguration} [client]
202202
* @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext<Request, Response>) => Headers)} [headers]
203+
* @property {boolean} [optionsMethod]
203204
* @property {(devServer: Server) => void} [onAfterSetupMiddleware]
204205
* @property {(devServer: Server) => void} [onBeforeSetupMiddleware]
205206
* @property {(devServer: Server) => void} [onListening]
@@ -2111,6 +2112,31 @@ class Server {
21112112
middleware: this.setHeaders.bind(this),
21122113
});
21132114
}
2115+
if (this.options.optionsMethod) {
2116+
/**
2117+
*
2118+
* @param {Request} req
2119+
* @param {Response} res
2120+
* @param {NextFunction} next
2121+
* @returns {void}
2122+
*
2123+
*/
2124+
const optionsRequestResponseMiddleware = (req, res, next) => {
2125+
if (req.method === "OPTIONS") {
2126+
res.statusCode = 204;
2127+
res.setHeader("Content-Length", "0");
2128+
res.end();
2129+
return;
2130+
}
2131+
next();
2132+
};
2133+
2134+
middlewares.push({
2135+
name: "options-request-response",
2136+
path: "*",
2137+
middleware: optionsRequestResponseMiddleware,
2138+
});
2139+
}
21142140

21152141
middlewares.push({
21162142
name: "webpack-dev-middleware",

lib/options.json

+10
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,13 @@
445445
"description": "Allows to set custom headers on response.",
446446
"link": "https://webpack.js.org/configuration/dev-server/#devserverheaders"
447447
},
448+
"OptionsMethod": {
449+
"type": "boolean",
450+
"description": "Response with 204 httpCode when receive an OPTIONS request",
451+
"cli": {
452+
"exclude": true
453+
}
454+
},
448455
"HistoryApiFallback": {
449456
"anyOf": [
450457
{
@@ -1146,6 +1153,9 @@
11461153
"headers": {
11471154
"$ref": "#/definitions/Headers"
11481155
},
1156+
"optionsMethod": {
1157+
"$ref": "#/definitions/OptionsMethod"
1158+
},
11491159
"historyApiFallback": {
11501160
"$ref": "#/definitions/HistoryApiFallback"
11511161
},
+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"use strict";
2+
3+
const webpack = require("webpack");
4+
const Express = require("express");
5+
const Server = require("../../lib/Server");
6+
const config = require("../fixtures/client-config/webpack.config");
7+
const runBrowser = require("../helpers/run-browser");
8+
const port = require("../ports-map")["options-request-response"];
9+
10+
const createWaiting = () => {
11+
let reslove;
12+
let reject;
13+
const waiting = new Promise((resolve$, reject$) => {
14+
reslove = resolve$;
15+
reject = reject$;
16+
});
17+
return {
18+
reslove,
19+
reject,
20+
waiting,
21+
};
22+
};
23+
24+
describe("handle options-request correctly", () => {
25+
it("should response with 200 http code", async () => {
26+
const compiler = webpack(config);
27+
const [portForServer, portForApp] = port;
28+
const closeApp = await (async () => {
29+
const { reslove, waiting } = createWaiting();
30+
const app = new Express();
31+
app.get("/", (req, res) => {
32+
res.sendStatus(200);
33+
});
34+
const server = app.listen(portForApp, () => {
35+
reslove();
36+
});
37+
await waiting;
38+
return async () => {
39+
const { reslove: reslove2, waiting: waiting2 } = createWaiting();
40+
server.close(() => {
41+
reslove2();
42+
});
43+
await waiting2;
44+
};
45+
})();
46+
const server = new Server(
47+
{
48+
port: portForServer,
49+
headers: {
50+
"Access-Control-Allow-Origin": "*",
51+
"Access-Control-Allow-Headers": "*",
52+
},
53+
optionsMethod: true,
54+
},
55+
compiler
56+
);
57+
await server.start();
58+
const { page, browser } = await runBrowser();
59+
const prefixUrl = "http://127.0.0.1";
60+
const htmlUrl = `${prefixUrl}:${portForServer}/test.html`;
61+
const appUrl = `${prefixUrl}:${portForApp}`;
62+
await page.goto(appUrl);
63+
const responseStatus = [];
64+
page.on("response", (res) => {
65+
responseStatus.push(res.status());
66+
});
67+
await page.evaluate(
68+
(url) =>
69+
window.fetch(url, {
70+
headers: {
71+
"another-header": "1",
72+
},
73+
}),
74+
htmlUrl
75+
);
76+
await browser.close();
77+
await server.stop();
78+
await closeApp();
79+
expect(responseStatus).toEqual([204, 200]);
80+
});
81+
});

test/ports-map.js

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const listOfTests = {
7979
"server-option": 1,
8080
"normalize-option": 1,
8181
"setup-middlewares-option": 1,
82+
"options-request-response": 2,
8283
};
8384

8485
let startPort = 8089;

0 commit comments

Comments
 (0)