|
1 | 1 | "use strict";
|
2 | 2 |
|
3 | 3 | const express = require("express");
|
| 4 | +const internalIp = require("internal-ip"); |
4 | 5 | const webpack = require("webpack");
|
5 | 6 | const { createProxyMiddleware } = require("http-proxy-middleware");
|
6 | 7 | const Server = require("../../lib/Server");
|
@@ -1069,4 +1070,284 @@ describe("allowed hosts", () => {
|
1069 | 1070 | await server.stop();
|
1070 | 1071 | });
|
1071 | 1072 | }
|
| 1073 | + |
| 1074 | + describe("check host headers", () => { |
| 1075 | + let compiler; |
| 1076 | + let server; |
| 1077 | + let page; |
| 1078 | + let browser; |
| 1079 | + let pageErrors; |
| 1080 | + let consoleMessages; |
| 1081 | + |
| 1082 | + beforeEach(() => { |
| 1083 | + compiler = webpack(config); |
| 1084 | + pageErrors = []; |
| 1085 | + consoleMessages = []; |
| 1086 | + }); |
| 1087 | + |
| 1088 | + afterEach(async () => { |
| 1089 | + await browser.close(); |
| 1090 | + await server.stop(); |
| 1091 | + }); |
| 1092 | + |
| 1093 | + it("should always allow `localhost` if options.allowedHosts is auto", async () => { |
| 1094 | + const options = { |
| 1095 | + allowedHosts: "auto", |
| 1096 | + port: port1, |
| 1097 | + }; |
| 1098 | + |
| 1099 | + const headers = { |
| 1100 | + host: "localhost", |
| 1101 | + }; |
| 1102 | + |
| 1103 | + server = new Server(options, compiler); |
| 1104 | + |
| 1105 | + await server.start(); |
| 1106 | + |
| 1107 | + ({ page, browser } = await runBrowser()); |
| 1108 | + |
| 1109 | + page |
| 1110 | + .on("console", (message) => { |
| 1111 | + consoleMessages.push(message); |
| 1112 | + }) |
| 1113 | + .on("pageerror", (error) => { |
| 1114 | + pageErrors.push(error); |
| 1115 | + }); |
| 1116 | + |
| 1117 | + const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, { |
| 1118 | + waitUntil: "networkidle0", |
| 1119 | + }); |
| 1120 | + |
| 1121 | + if (!server.checkHeader(headers, "host")) { |
| 1122 | + throw new Error("Validation didn't fail"); |
| 1123 | + } |
| 1124 | + |
| 1125 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1126 | + |
| 1127 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1128 | + "console messages" |
| 1129 | + ); |
| 1130 | + |
| 1131 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1132 | + }); |
| 1133 | + |
| 1134 | + it("should always allow value from the `host` options if options.allowedHosts is auto", async () => { |
| 1135 | + const networkIP = internalIp.v4.sync(); |
| 1136 | + const options = { |
| 1137 | + host: networkIP, |
| 1138 | + allowedHosts: "auto", |
| 1139 | + port: port1, |
| 1140 | + }; |
| 1141 | + |
| 1142 | + const headers = { |
| 1143 | + host: networkIP, |
| 1144 | + }; |
| 1145 | + |
| 1146 | + server = new Server(options, compiler); |
| 1147 | + |
| 1148 | + await server.start(); |
| 1149 | + |
| 1150 | + ({ page, browser } = await runBrowser()); |
| 1151 | + |
| 1152 | + page |
| 1153 | + .on("console", (message) => { |
| 1154 | + consoleMessages.push(message); |
| 1155 | + }) |
| 1156 | + .on("pageerror", (error) => { |
| 1157 | + pageErrors.push(error); |
| 1158 | + }); |
| 1159 | + |
| 1160 | + const response = await page.goto(`http://${networkIP}:${port1}/main.js`, { |
| 1161 | + waitUntil: "networkidle0", |
| 1162 | + }); |
| 1163 | + |
| 1164 | + if (!server.checkHeader(headers, "host")) { |
| 1165 | + throw new Error("Validation didn't fail"); |
| 1166 | + } |
| 1167 | + |
| 1168 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1169 | + |
| 1170 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1171 | + "console messages" |
| 1172 | + ); |
| 1173 | + |
| 1174 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1175 | + }); |
| 1176 | + |
| 1177 | + it.skip("should always allow value of the `host` option from the `client.webSocketURL` option if options.allowedHosts is auto", async () => { |
| 1178 | + const options = { |
| 1179 | + allowedHosts: "auto", |
| 1180 | + port: port1, |
| 1181 | + client: { |
| 1182 | + webSocketURL: "ws://test.host:80", |
| 1183 | + }, |
| 1184 | + }; |
| 1185 | + |
| 1186 | + const headers = { |
| 1187 | + host: "test.host", |
| 1188 | + }; |
| 1189 | + |
| 1190 | + server = new Server(options, compiler); |
| 1191 | + |
| 1192 | + await server.start(); |
| 1193 | + |
| 1194 | + ({ page, browser } = await runBrowser()); |
| 1195 | + |
| 1196 | + page |
| 1197 | + .on("console", (message) => { |
| 1198 | + consoleMessages.push(message); |
| 1199 | + }) |
| 1200 | + .on("pageerror", (error) => { |
| 1201 | + pageErrors.push(error); |
| 1202 | + }); |
| 1203 | + |
| 1204 | + const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, { |
| 1205 | + waitUntil: "networkidle0", |
| 1206 | + }); |
| 1207 | + |
| 1208 | + if (!server.checkHeader(headers, "host")) { |
| 1209 | + throw new Error("Validation didn't fail"); |
| 1210 | + } |
| 1211 | + |
| 1212 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1213 | + |
| 1214 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1215 | + "console messages" |
| 1216 | + ); |
| 1217 | + |
| 1218 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1219 | + }); |
| 1220 | + |
| 1221 | + it("should always allow any host if options.allowedHosts is all", async () => { |
| 1222 | + const options = { |
| 1223 | + allowedHosts: "all", |
| 1224 | + port: port1, |
| 1225 | + }; |
| 1226 | + const headers = { |
| 1227 | + host: "bad.host", |
| 1228 | + }; |
| 1229 | + |
| 1230 | + server = new Server(options, compiler); |
| 1231 | + |
| 1232 | + await server.start(); |
| 1233 | + |
| 1234 | + ({ page, browser } = await runBrowser()); |
| 1235 | + |
| 1236 | + page |
| 1237 | + .on("console", (message) => { |
| 1238 | + consoleMessages.push(message); |
| 1239 | + }) |
| 1240 | + .on("pageerror", (error) => { |
| 1241 | + pageErrors.push(error); |
| 1242 | + }); |
| 1243 | + |
| 1244 | + const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, { |
| 1245 | + waitUntil: "networkidle0", |
| 1246 | + }); |
| 1247 | + |
| 1248 | + if (!server.checkHeader(headers, "host")) { |
| 1249 | + throw new Error("Validation didn't fail"); |
| 1250 | + } |
| 1251 | + |
| 1252 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1253 | + |
| 1254 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1255 | + "console messages" |
| 1256 | + ); |
| 1257 | + |
| 1258 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1259 | + }); |
| 1260 | + |
| 1261 | + it("should allow hosts in allowedHosts", async () => { |
| 1262 | + const tests = ["test.host", "test2.host", "test3.host"]; |
| 1263 | + const options = { |
| 1264 | + allowedHosts: tests, |
| 1265 | + port: port1, |
| 1266 | + }; |
| 1267 | + |
| 1268 | + server = new Server(options, compiler); |
| 1269 | + |
| 1270 | + await server.start(); |
| 1271 | + |
| 1272 | + ({ page, browser } = await runBrowser()); |
| 1273 | + |
| 1274 | + page |
| 1275 | + .on("console", (message) => { |
| 1276 | + consoleMessages.push(message); |
| 1277 | + }) |
| 1278 | + .on("pageerror", (error) => { |
| 1279 | + pageErrors.push(error); |
| 1280 | + }); |
| 1281 | + |
| 1282 | + const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, { |
| 1283 | + waitUntil: "networkidle0", |
| 1284 | + }); |
| 1285 | + |
| 1286 | + tests.forEach((test) => { |
| 1287 | + const headers = { host: test }; |
| 1288 | + |
| 1289 | + if (!server.checkHeader(headers, "host")) { |
| 1290 | + throw new Error("Validation didn't fail"); |
| 1291 | + } |
| 1292 | + }); |
| 1293 | + |
| 1294 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1295 | + |
| 1296 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1297 | + "console messages" |
| 1298 | + ); |
| 1299 | + |
| 1300 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1301 | + }); |
| 1302 | + |
| 1303 | + it("should allow hosts that pass a wildcard in allowedHosts", async () => { |
| 1304 | + const options = { |
| 1305 | + allowedHosts: [".example.com"], |
| 1306 | + port: port1, |
| 1307 | + }; |
| 1308 | + |
| 1309 | + server = new Server(options, compiler); |
| 1310 | + |
| 1311 | + await server.start(); |
| 1312 | + |
| 1313 | + ({ page, browser } = await runBrowser()); |
| 1314 | + |
| 1315 | + page |
| 1316 | + .on("console", (message) => { |
| 1317 | + consoleMessages.push(message); |
| 1318 | + }) |
| 1319 | + .on("pageerror", (error) => { |
| 1320 | + pageErrors.push(error); |
| 1321 | + }); |
| 1322 | + |
| 1323 | + const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, { |
| 1324 | + waitUntil: "networkidle0", |
| 1325 | + }); |
| 1326 | + |
| 1327 | + const tests = [ |
| 1328 | + "www.example.com", |
| 1329 | + "subdomain.example.com", |
| 1330 | + "example.com", |
| 1331 | + "subsubcomain.subdomain.example.com", |
| 1332 | + "example.com:80", |
| 1333 | + "subdomain.example.com:80", |
| 1334 | + ]; |
| 1335 | + |
| 1336 | + tests.forEach((test) => { |
| 1337 | + const headers = { host: test }; |
| 1338 | + |
| 1339 | + if (!server.checkHeader(headers, "host")) { |
| 1340 | + throw new Error("Validation didn't fail"); |
| 1341 | + } |
| 1342 | + }); |
| 1343 | + |
| 1344 | + expect(response.status()).toMatchSnapshot("response status"); |
| 1345 | + |
| 1346 | + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( |
| 1347 | + "console messages" |
| 1348 | + ); |
| 1349 | + |
| 1350 | + expect(pageErrors).toMatchSnapshot("page errors"); |
| 1351 | + }); |
| 1352 | + }); |
1072 | 1353 | });
|
0 commit comments