From a70a7ef025f07ec6be69cee0b3b5204c7e3a0c5b Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Wed, 27 Oct 2021 09:58:42 -0700 Subject: [PATCH] feat: add the `server` option (#3940) --- README.md | 65 +- bin/cli-flags.js | 280 ++- lib/Server.js | 99 +- lib/options.json | 228 ++- .../validate-options.test.js.snap.webpack4 | 98 +- .../validate-options.test.js.snap.webpack5 | 98 +- .../__snapshots__/basic.test.js.snap.webpack4 | 44 +- .../__snapshots__/basic.test.js.snap.webpack5 | 44 +- .../https-option.test.js.snap.webpack4 | 2 +- .../https-option.test.js.snap.webpack5 | 2 +- .../server-option.test.js.snap.webpack4 | 90 + .../server-option.test.js.snap.webpack5 | 90 + test/cli/server-option.test.js | 246 +++ .../__snapshots__/https.test.js.snap.webpack4 | 11 + .../__snapshots__/https.test.js.snap.webpack5 | 11 + .../server.test.js.snap.webpack4 | 658 +++++++ .../server.test.js.snap.webpack5 | 658 +++++++ test/e2e/server.test.js | 1587 +++++++++++++++++ test/ports-map.js | 2 + .../Server.test.js.snap.webpack4 | 196 ++ .../Server.test.js.snap.webpack5 | 196 ++ test/validate-options.test.js | 69 + 22 files changed, 4639 insertions(+), 135 deletions(-) create mode 100644 test/cli/__snapshots__/server-option.test.js.snap.webpack4 create mode 100644 test/cli/__snapshots__/server-option.test.js.snap.webpack5 create mode 100644 test/cli/server-option.test.js create mode 100644 test/e2e/__snapshots__/server.test.js.snap.webpack4 create mode 100644 test/e2e/__snapshots__/server.test.js.snap.webpack5 create mode 100644 test/e2e/server.test.js diff --git a/README.md b/README.md index c185d84de4..bac6ca3bc0 100644 --- a/README.md +++ b/README.md @@ -122,21 +122,35 @@ Options: --no-http2 Does not serve over HTTP/2 using SPDY. --https Allows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). --no-https Disallows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). - --https-passphrase Passphrase for a pfx file. - --https-request-cert Request for an SSL certificate. - --no-https-request-cert Does not request for an SSL certificate. - --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. - --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-key Path to an SSL key or content of an SSL key. - --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. - --https-pfx Path to an SSL pfx file or content of an SSL pfx file. + --https-passphrase Passphrase for a pfx file. Deprecated, it will be removed in favor of the `server.options.passphrase` option. + --https-request-cert Request for an SSL certificate. Deprecated, it will be removed in favor of the `server.options.requestCert` + option. + --no-https-request-cert Negative 'https-request-cert' option. + --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the + `server.options.ca` option. + --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA + certificate. Deprecated, it will be removed in favor of the `server.options.ca` option. + --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the + `server.options.cacert` option. + --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA + certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option. + --https-cert Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the + `server.options.cert` option. + --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL + certificate. Deprecated, it will be removed in favor of the `server.options.cert` option. + --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate + Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option. + --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) + or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the + `server.options.crl` option. + --https-key Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` + option. + --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. Deprecated, + it will be removed in favor of the `server.options.key` option. + --https-pfx Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the + `server.options.pfx` option. --https-pfx-reset Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. - --https-cert Path to an SSL certificate or content of an SSL certificate. - --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. - --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). - --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + Deprecated, it will be removed in favor of the `server.options.pfx` option. --ipc [value] Listen to a unix socket. --live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default). --no-live-reload Disables reload/refresh the page(s) when file changes are detected (enabled by default) @@ -151,6 +165,29 @@ Options: --open-target-reset Clear all items provided in 'open.target' configuration. Opens specified page in browser. --open-app-name-reset Clear all items provided in 'open.app.name' configuration. Open specified browser. --port Allows to specify a port to use. + --server-type Allows to set server and options (by default 'http'). + --server-options-passphrase Passphrase for a pfx file. + --server-options-request-cert Request for an SSL certificate. + --no-server-options-request-cert Negative 'server-options-request-cert' option. + --server-options-ca Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-ca-reset Clear all items provided in 'server.options.ca' configuration. Path to an SSL CA certificate or content + of an SSL CA certificate. + --server-options-cacert Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cacert-reset Clear all items provided in 'server.options.cacert' configuration. Path to an SSL CA certificate or + content of an SSL CA certificate. + --server-options-cert Path to an SSL certificate or content of an SSL certificate. + --server-options-cert-reset Clear all items provided in 'server.options.cert' configuration. Path to an SSL certificate or content + of an SSL certificate. + --server-options-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate + Revocation Lists). + --server-options-crl-reset Clear all items provided in 'server.options.crl' configuration. Path to PEM formatted CRLs (Certificate + Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --server-options-key Path to an SSL key or content of an SSL key. + --server-options-key-reset Clear all items provided in 'server.options.key' configuration. Path to an SSL key or content of an SSL + key. + --server-options-pfx Path to an SSL pfx file or content of an SSL pfx file. + --server-options-pfx-reset Clear all items provided in 'server.options.pfx' configuration. Path to an SSL pfx file or content of + an SSL pfx file. --static [value...] Allows to configure options for serving static files from directory (by default 'public' directory). --no-static Negative 'static' option. --static-directory Directory for static contents. diff --git a/bin/cli-flags.js b/bin/cli-flags.js index bbef95350b..da2c2bf227 100644 --- a/bin/cli-flags.js +++ b/bin/cli-flags.js @@ -455,11 +455,13 @@ module.exports = { { type: "string", multiple: false, - description: "Passphrase for a pfx file.", + description: + "Passphrase for a pfx file. Deprecated, it will be removed in favor of the `server.options.passphrase` option.", path: "https.passphrase", }, ], - description: "Passphrase for a pfx file.", + description: + "Passphrase for a pfx file. Deprecated, it will be removed in favor of the `server.options.passphrase` option.", simpleType: "string", multiple: false, }, @@ -468,11 +470,13 @@ module.exports = { { type: "boolean", multiple: false, - description: "Request for an SSL certificate.", + description: + "Request for an SSL certificate. Deprecated, it will be removed in favor of the `server.options.requestCert` option.", path: "https.requestCert", }, ], - description: "Request for an SSL certificate.", + description: + "Request for an SSL certificate. Deprecated, it will be removed in favor of the `server.options.requestCert` option.", negatedDescription: "Does not request for an SSL certificate.", simpleType: "boolean", multiple: false, @@ -483,12 +487,12 @@ module.exports = { type: "string", multiple: true, description: - "Path to an SSL CA certificate or content of an SSL CA certificate.", + "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.ca` option.", path: "https.ca[]", }, ], description: - "Path to an SSL CA certificate or content of an SSL CA certificate.", + "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.ca` option.", simpleType: "string", multiple: true, }, @@ -496,14 +500,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + "Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.ca` option.", multiple: false, path: "https.ca", type: "reset", }, ], description: - "Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + "Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.ca` option.", multiple: false, simpleType: "boolean", }, @@ -513,12 +517,12 @@ module.exports = { type: "string", multiple: true, description: - "Path to an SSL CA certificate or content of an SSL CA certificate.", + "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option.", path: "https.cacert[]", }, ], description: - "Path to an SSL CA certificate or content of an SSL CA certificate.", + "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option.", simpleType: "string", multiple: true, }, @@ -526,14 +530,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + "Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option.", multiple: false, path: "https.cacert", type: "reset", }, ], description: - "Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + "Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option.", multiple: false, simpleType: "boolean", }, @@ -542,11 +546,13 @@ module.exports = { { type: "string", multiple: true, - description: "Path to an SSL key or content of an SSL key.", + description: + "Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` option.", path: "https.key[]", }, ], - description: "Path to an SSL key or content of an SSL key.", + description: + "Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` option.", simpleType: "string", multiple: true, }, @@ -554,14 +560,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key.", + "Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` option.", multiple: false, path: "https.key", type: "reset", }, ], description: - "Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key.", + "Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` option.", multiple: false, simpleType: "boolean", }, @@ -570,11 +576,13 @@ module.exports = { { type: "string", multiple: true, - description: "Path to an SSL pfx file or content of an SSL pfx file.", + description: + "Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the `server.options.pfx` option.", path: "https.pfx[]", }, ], - description: "Path to an SSL pfx file or content of an SSL pfx file.", + description: + "Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the `server.options.pfx` option.", simpleType: "string", multiple: true, }, @@ -582,14 +590,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file.", + "Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the `server.options.pfx` option.", multiple: false, path: "https.pfx", type: "reset", }, ], description: - "Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file.", + "Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the `server.options.pfx` option.", multiple: false, simpleType: "boolean", }, @@ -599,11 +607,12 @@ module.exports = { type: "string", multiple: true, description: - "Path to an SSL certificate or content of an SSL certificate.", + "Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the `server.options.cert` option.", path: "https.cert[]", }, ], - description: "Path to an SSL certificate or content of an SSL certificate.", + description: + "Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the `server.options.cert` option.", simpleType: "string", multiple: true, }, @@ -611,14 +620,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate.", + "Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the `server.options.cert` option.", multiple: false, path: "https.cert", type: "reset", }, ], description: - "Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate.", + "Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the `server.options.cert` option.", multiple: false, simpleType: "boolean", }, @@ -626,14 +635,14 @@ module.exports = { configs: [ { description: - "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option.", multiple: true, path: "https.crl[]", type: "string", }, ], description: - "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option.", multiple: true, simpleType: "string", }, @@ -641,14 +650,14 @@ module.exports = { configs: [ { description: - "Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + "Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option.", multiple: false, path: "https.crl", type: "reset", }, ], description: - "Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + "Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option.", multiple: false, simpleType: "boolean", }, @@ -852,6 +861,221 @@ module.exports = { simpleType: "string", multiple: false, }, + "server-options-ca": { + configs: [ + { + description: + "Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: true, + path: "server.options.ca[]", + type: "string", + }, + ], + description: + "Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: true, + simpleType: "string", + }, + "server-options-ca-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: false, + path: "server.options.ca", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: false, + simpleType: "boolean", + }, + "server-options-cacert": { + configs: [ + { + description: + "Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: true, + path: "server.options.cacert[]", + type: "string", + }, + ], + description: + "Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: true, + simpleType: "string", + }, + "server-options-cacert-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: false, + path: "server.options.cacert", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate.", + multiple: false, + simpleType: "boolean", + }, + "server-options-cert": { + configs: [ + { + description: + "Path to an SSL certificate or content of an SSL certificate.", + multiple: true, + path: "server.options.cert[]", + type: "string", + }, + ], + description: "Path to an SSL certificate or content of an SSL certificate.", + multiple: true, + simpleType: "string", + }, + "server-options-cert-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.cert' configuration. Path to an SSL certificate or content of an SSL certificate.", + multiple: false, + path: "server.options.cert", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.cert' configuration. Path to an SSL certificate or content of an SSL certificate.", + multiple: false, + simpleType: "boolean", + }, + "server-options-crl": { + configs: [ + { + description: + "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + multiple: true, + path: "server.options.crl[]", + type: "string", + }, + ], + description: + "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + multiple: true, + simpleType: "string", + }, + "server-options-crl-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + multiple: false, + path: "server.options.crl", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists).", + multiple: false, + simpleType: "boolean", + }, + "server-options-key": { + configs: [ + { + description: "Path to an SSL key or content of an SSL key.", + multiple: true, + path: "server.options.key[]", + type: "string", + }, + ], + description: "Path to an SSL key or content of an SSL key.", + multiple: true, + simpleType: "string", + }, + "server-options-key-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.key' configuration. Path to an SSL key or content of an SSL key.", + multiple: false, + path: "server.options.key", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.key' configuration. Path to an SSL key or content of an SSL key.", + multiple: false, + simpleType: "boolean", + }, + "server-options-passphrase": { + configs: [ + { + description: "Passphrase for a pfx file.", + multiple: false, + path: "server.options.passphrase", + type: "string", + }, + ], + description: "Passphrase for a pfx file.", + multiple: false, + simpleType: "string", + }, + "server-options-pfx": { + configs: [ + { + description: "Path to an SSL pfx file or content of an SSL pfx file.", + multiple: true, + path: "server.options.pfx[]", + type: "string", + }, + ], + description: "Path to an SSL pfx file or content of an SSL pfx file.", + multiple: true, + simpleType: "string", + }, + "server-options-pfx-reset": { + configs: [ + { + description: + "Clear all items provided in 'server.options.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file.", + multiple: false, + path: "server.options.pfx", + type: "reset", + }, + ], + description: + "Clear all items provided in 'server.options.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file.", + multiple: false, + simpleType: "boolean", + }, + "server-options-request-cert": { + configs: [ + { + description: "Request for an SSL certificate.", + multiple: false, + path: "server.options.requestCert", + type: "boolean", + }, + ], + description: "Request for an SSL certificate.", + multiple: false, + simpleType: "boolean", + }, + "server-type": { + configs: [ + { + description: "Allows to set server and options (by default 'http').", + multiple: false, + path: "server.type", + type: "enum", + values: ["http", "https", "spdy"], + }, + ], + description: "Allows to set server and options (by default 'http').", + multiple: false, + simpleType: "string", + }, static: { configs: [ { diff --git a/lib/Server.js b/lib/Server.js index 82932b897f..b74614ea15 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -155,7 +155,7 @@ class Server { if (typeof this.options.client.webSocketURL.protocol !== "undefined") { protocol = this.options.client.webSocketURL.protocol; } else { - protocol = this.options.https ? "wss:" : "ws:"; + protocol = this.options.server.type === "http" ? "ws:" : "wss:"; } searchParams.set("protocol", protocol); @@ -520,23 +520,51 @@ class Server { ? options.hot : true; - // if the user enables http2, we can safely enable https - if ((options.http2 && !options.https) || options.https === true) { - options.https = { - requestCert: false, + const isHTTPs = Boolean(options.https); + const isSPDY = Boolean(options.http2); + + options.server = { + type: + // eslint-disable-next-line no-nested-ternary + typeof options.server === "string" + ? options.server + : // eslint-disable-next-line no-nested-ternary + typeof (options.server || {}).type === "string" + ? options.server.type + : // eslint-disable-next-line no-nested-ternary + isSPDY + ? "spdy" + : isHTTPs + ? "https" + : "http", + options: { + ...options.https, + ...(options.server || {}).options, + }, + }; + + if ( + options.server.type === "spdy" && + typeof options.server.options.spdy === "undefined" + ) { + options.server.options.spdy = { + protocols: ["h2", "http/1.1"], }; } - // https option - if (options.https) { + if (options.server.type === "https" || options.server.type === "spdy") { + if (typeof options.server.options.requestCert === "undefined") { + options.server.options.requestCert = false; + } + // TODO remove the `cacert` option in favor `ca` in the next major release for (const property of ["cacert", "ca", "cert", "crl", "key", "pfx"]) { - if (typeof options.https[property] === "undefined") { + if (typeof options.server.options[property] === "undefined") { // eslint-disable-next-line no-continue continue; } - const value = options.https[property]; + const value = options.server.options[property]; const readFile = (item) => { if ( Buffer.isBuffer(item) || @@ -559,14 +587,14 @@ class Server { } }; - options.https[property] = Array.isArray(value) + options.server.options[property] = Array.isArray(value) ? value.map((item) => readFile(item)) : readFile(value); } let fakeCert; - if (!options.https.key || !options.https.cert) { + if (!options.server.options.key || !options.server.options.cert) { const certificateDir = Server.findCacheDir(); const certificatePath = path.join(certificateDir, "server.pem"); let certificateExists; @@ -681,20 +709,20 @@ class Server { this.logger.info(`SSL certificate: ${certificatePath}`); } - if (options.https.cacert) { - if (options.https.ca) { + if (options.server.options.cacert) { + if (options.server.options.ca) { this.logger.warn( - "Do not specify 'https.ca' and 'https.cacert' options together, the 'https.ca' option will be used." + "Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used." ); } else { - options.https.ca = options.https.cacert; + options.server.options.ca = options.server.options.cacert; } - delete options.https.cacert; + delete options.server.options.cacert; } - options.https.key = options.https.key || fakeCert; - options.https.cert = options.https.cert || fakeCert; + options.server.options.key = options.server.options.key || fakeCert; + options.server.options.cert = options.server.options.cert || fakeCert; } if (typeof options.ipc === "boolean") { @@ -1559,28 +1587,11 @@ class Server { } createServer() { - if (this.options.https) { - if (this.options.http2) { - // TODO: we need to replace spdy with http2 which is an internal module - this.server = require("spdy").createServer( - { - ...this.options.https, - spdy: { - protocols: ["h2", "http/1.1"], - }, - }, - this.app - ); - } else { - const https = require("https"); - - this.server = https.createServer(this.options.https, this.app); - } - } else { - const http = require("http"); - - this.server = http.createServer(this.app); - } + // eslint-disable-next-line import/no-dynamic-require + this.server = require(this.options.server.type).createServer( + this.options.server.options, + this.app + ); this.server.on("connection", (socket) => { // Add socket to list @@ -1696,7 +1707,7 @@ class Server { bonjour.publish({ name: `Webpack Dev Server ${os.hostname()}:${this.options.port}`, port: this.options.port, - type: this.options.https ? "https" : "http", + type: this.options.server.type === "http" ? "http" : "https", subtypes: ["webpack"], ...this.options.bonjour, }); @@ -1747,7 +1758,7 @@ class Server { if (this.options.ipc) { this.logger.info(`Project is running at: "${this.server.address()}"`); } else { - const protocol = this.options.https ? "https" : "http"; + const protocol = this.options.server.type === "http" ? "http" : "https"; const { address, port } = this.server.address(); const prettyPrintURL = (newHostname) => url.format({ protocol, hostname: newHostname, port, pathname: "/" }); @@ -1866,7 +1877,9 @@ class Server { if (this.options.bonjour) { const bonjourProtocol = - this.options.bonjour.type || this.options.https ? "https" : "http"; + this.options.bonjour.type || this.options.server.type === "http" + ? "http" + : "https"; this.logger.info( `Broadcasting "${bonjourProtocol}" with subtype of "webpack" via ZeroConf DNS (Bonjour)` diff --git a/lib/options.json b/lib/options.json index 875e828e82..dd6d7f5e8c 100644 --- a/lib/options.json +++ b/lib/options.json @@ -221,11 +221,11 @@ "properties": { "passphrase": { "type": "string", - "description": "Passphrase for a pfx file." + "description": "Passphrase for a pfx file. Deprecated, it will be removed in favor of the `server.options.passphrase` option." }, "requestCert": { "type": "boolean", - "description": "Request for an SSL certificate." + "description": "Request for an SSL certificate. Deprecated, it will be removed in favor of the `server.options.requestCert` option." }, "ca": { "anyOf": [ @@ -249,7 +249,7 @@ "instanceof": "Buffer" } ], - "description": "Path to an SSL CA certificate or content of an SSL CA certificate." + "description": "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.ca` option." }, "cacert": { "anyOf": [ @@ -273,7 +273,7 @@ "instanceof": "Buffer" } ], - "description": "Path to an SSL CA certificate or content of an SSL CA certificate." + "description": "Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the `server.options.cacert` option." }, "cert": { "anyOf": [ @@ -297,7 +297,7 @@ "instanceof": "Buffer" } ], - "description": "Path to an SSL certificate or content of an SSL certificate." + "description": "Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the `server.options.cert` option." }, "crl": { "anyOf": [ @@ -321,7 +321,7 @@ "instanceof": "Buffer" } ], - "description": "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists)." + "description": "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the `server.options.crl` option." }, "key": { "anyOf": [ @@ -349,7 +349,7 @@ "instanceof": "Buffer" } ], - "description": "Path to an SSL key or content of an SSL key." + "description": "Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the `server.options.key` option." }, "pfx": { "anyOf": [ @@ -377,7 +377,7 @@ "instanceof": "Buffer" } ], - "description": "Path to an SSL pfx file or content of an SSL pfx file." + "description": "Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the `server.options.pfx` option." } } } @@ -631,6 +631,215 @@ "description": "Allows to proxy requests, can be useful when you have a separate API backend development server and you want to send API requests on the same domain.", "link": "https://webpack.js.org/configuration/dev-server/#devserverproxy" }, + "Server": { + "anyOf": [ + { + "$ref": "#/definitions/ServerEnum" + }, + { + "$ref": "#/definitions/ServerString" + }, + { + "$ref": "#/definitions/ServerObject" + } + ], + "link": "https://webpack.js.org/configuration/dev-server/#devserverserver", + "description": "Allows to set server and options (by default 'http')." + }, + "ServerType": { + "enum": ["http", "https", "spdy"] + }, + "ServerEnum": { + "enum": ["http", "https", "spdy"], + "cli": { + "exclude": true + } + }, + "ServerString": { + "type": "string", + "minLength": 1, + "cli": { + "exclude": true + } + }, + "ServerObject": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/ServerType" + }, + "options": { + "$ref": "#/definitions/ServerOptions" + } + }, + "additionalProperties": false + }, + "ServerOptions": { + "type": "object", + "additionalProperties": true, + "properties": { + "passphrase": { + "type": "string", + "description": "Passphrase for a pfx file." + }, + "requestCert": { + "type": "boolean", + "description": "Request for an SSL certificate." + }, + "ca": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to an SSL CA certificate or content of an SSL CA certificate." + }, + "cacert": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to an SSL CA certificate or content of an SSL CA certificate." + }, + "cert": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to an SSL certificate or content of an SSL certificate." + }, + "crl": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists)." + }, + "key": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + }, + { + "type": "object", + "additionalProperties": true + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to an SSL key or content of an SSL key." + }, + "pfx": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Buffer" + }, + { + "type": "object", + "additionalProperties": true + } + ] + } + }, + { + "type": "string" + }, + { + "instanceof": "Buffer" + } + ], + "description": "Path to an SSL pfx file or content of an SSL pfx file." + } + } + }, "SetupExitSignals": { "type": "boolean", "description": "Allows to close dev server and exit the process on SIGINT and SIGTERM signals (enabled by default for CLI).", @@ -915,6 +1124,9 @@ "proxy": { "$ref": "#/definitions/Proxy" }, + "server": { + "$ref": "#/definitions/Server" + }, "setupExitSignals": { "$ref": "#/definitions/SetupExitSignals" }, diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 26874115f1..646e103f06 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -371,7 +371,7 @@ exports[`options validate should throw an error on the "https" option with '{"ca Details: * options.https.cacert should be one of these: [string | Buffer, ...] | string | Buffer - -> Path to an SSL CA certificate or content of an SSL CA certificate. + -> Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. Details: * options.https.cacert should be an array: [string | Buffer, ...] @@ -388,7 +388,7 @@ exports[`options validate should throw an error on the "https" option with '{"ce Details: * options.https.cert should be one of these: [string | Buffer, ...] | string | Buffer - -> Path to an SSL certificate or content of an SSL certificate. + -> Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. Details: * options.https.cert should be an array: [string | Buffer, ...] @@ -405,7 +405,7 @@ exports[`options validate should throw an error on the "https" option with '{"ke Details: * options.https.key should be one of these: [string | Buffer | object { … }, ...] | string | Buffer - -> Path to an SSL key or content of an SSL key. + -> Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. Details: * options.https.key should be an array: [string | Buffer | object { … }, ...] @@ -416,7 +416,7 @@ exports[`options validate should throw an error on the "https" option with '{"ke exports[`options validate should throw an error on the "https" option with '{"passphrase":false}' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.https.passphrase should be a string. - -> Passphrase for a pfx file." + -> Passphrase for a pfx file. Deprecated, it will be removed in favor of the \`server.options.passphrase\` option." `; exports[`options validate should throw an error on the "https" option with '{"pfx":10}' value 1`] = ` @@ -428,7 +428,7 @@ exports[`options validate should throw an error on the "https" option with '{"pf Details: * options.https.pfx should be one of these: [string | Buffer | object { … }, ...] | string | Buffer - -> Path to an SSL pfx file or content of an SSL pfx file. + -> Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. Details: * options.https.pfx should be an array: [string | Buffer | object { … }, ...] @@ -439,7 +439,7 @@ exports[`options validate should throw an error on the "https" option with '{"pf exports[`options validate should throw an error on the "https" option with '{"requestCert":"test"}' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.https.requestCert should be a boolean. - -> Request for an SSL certificate." + -> Request for an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.requestCert\` option." `; exports[`options validate should throw an error on the "ipc" option with '{}' value 1`] = ` @@ -608,6 +608,92 @@ exports[`options validate should throw an error on the "proxy" option with 'fals [object { … } | function, ...]" `; +exports[`options validate should throw an error on the "server" option with '{"type":"https","additional":"test"}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server has an unknown property 'additional'. These properties are valid: + object { type?, options? }" +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"ca":true}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.ca should be one of these: + [string | Buffer, ...] | string | Buffer + -> Path to an SSL CA certificate or content of an SSL CA certificate. + Details: + * options.server.options.ca should be an array: + [string | Buffer, ...] + * options.server.options.ca should be a string. + * options.server.options.ca should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"cert":true}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.cert should be one of these: + [string | Buffer, ...] | string | Buffer + -> Path to an SSL certificate or content of an SSL certificate. + Details: + * options.server.options.cert should be an array: + [string | Buffer, ...] + * options.server.options.cert should be a string. + * options.server.options.cert should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"key":10}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.key should be one of these: + [string | Buffer | object { … }, ...] | string | Buffer + -> Path to an SSL key or content of an SSL key. + Details: + * options.server.options.key should be an array: + [string | Buffer | object { … }, ...] + * options.server.options.key should be a string. + * options.server.options.key should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"passphrase":false}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server.options.passphrase should be a string. + -> Passphrase for a pfx file." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"pfx":10}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.pfx should be one of these: + [string | Buffer | object { … }, ...] | string | Buffer + -> Path to an SSL pfx file or content of an SSL pfx file. + Details: + * options.server.options.pfx should be an array: + [string | Buffer | object { … }, ...] + * options.server.options.pfx should be a string. + * options.server.options.pfx should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"requestCert":"false"}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server.options.requestCert should be a boolean. + -> Request for an SSL certificate." +`; + exports[`options validate should throw an error on the "static" option with '' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.static should be a non-empty string." diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 26874115f1..646e103f06 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -371,7 +371,7 @@ exports[`options validate should throw an error on the "https" option with '{"ca Details: * options.https.cacert should be one of these: [string | Buffer, ...] | string | Buffer - -> Path to an SSL CA certificate or content of an SSL CA certificate. + -> Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. Details: * options.https.cacert should be an array: [string | Buffer, ...] @@ -388,7 +388,7 @@ exports[`options validate should throw an error on the "https" option with '{"ce Details: * options.https.cert should be one of these: [string | Buffer, ...] | string | Buffer - -> Path to an SSL certificate or content of an SSL certificate. + -> Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. Details: * options.https.cert should be an array: [string | Buffer, ...] @@ -405,7 +405,7 @@ exports[`options validate should throw an error on the "https" option with '{"ke Details: * options.https.key should be one of these: [string | Buffer | object { … }, ...] | string | Buffer - -> Path to an SSL key or content of an SSL key. + -> Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. Details: * options.https.key should be an array: [string | Buffer | object { … }, ...] @@ -416,7 +416,7 @@ exports[`options validate should throw an error on the "https" option with '{"ke exports[`options validate should throw an error on the "https" option with '{"passphrase":false}' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.https.passphrase should be a string. - -> Passphrase for a pfx file." + -> Passphrase for a pfx file. Deprecated, it will be removed in favor of the \`server.options.passphrase\` option." `; exports[`options validate should throw an error on the "https" option with '{"pfx":10}' value 1`] = ` @@ -428,7 +428,7 @@ exports[`options validate should throw an error on the "https" option with '{"pf Details: * options.https.pfx should be one of these: [string | Buffer | object { … }, ...] | string | Buffer - -> Path to an SSL pfx file or content of an SSL pfx file. + -> Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. Details: * options.https.pfx should be an array: [string | Buffer | object { … }, ...] @@ -439,7 +439,7 @@ exports[`options validate should throw an error on the "https" option with '{"pf exports[`options validate should throw an error on the "https" option with '{"requestCert":"test"}' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.https.requestCert should be a boolean. - -> Request for an SSL certificate." + -> Request for an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.requestCert\` option." `; exports[`options validate should throw an error on the "ipc" option with '{}' value 1`] = ` @@ -608,6 +608,92 @@ exports[`options validate should throw an error on the "proxy" option with 'fals [object { … } | function, ...]" `; +exports[`options validate should throw an error on the "server" option with '{"type":"https","additional":"test"}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server has an unknown property 'additional'. These properties are valid: + object { type?, options? }" +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"ca":true}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.ca should be one of these: + [string | Buffer, ...] | string | Buffer + -> Path to an SSL CA certificate or content of an SSL CA certificate. + Details: + * options.server.options.ca should be an array: + [string | Buffer, ...] + * options.server.options.ca should be a string. + * options.server.options.ca should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"cert":true}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.cert should be one of these: + [string | Buffer, ...] | string | Buffer + -> Path to an SSL certificate or content of an SSL certificate. + Details: + * options.server.options.cert should be an array: + [string | Buffer, ...] + * options.server.options.cert should be a string. + * options.server.options.cert should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"key":10}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.key should be one of these: + [string | Buffer | object { … }, ...] | string | Buffer + -> Path to an SSL key or content of an SSL key. + Details: + * options.server.options.key should be an array: + [string | Buffer | object { … }, ...] + * options.server.options.key should be a string. + * options.server.options.key should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"passphrase":false}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server.options.passphrase should be a string. + -> Passphrase for a pfx file." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"pfx":10}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server should be one of these: + \\"http\\" | \\"https\\" | \\"spdy\\" | non-empty string | object { type?, options? } + -> Allows to set server and options (by default 'http'). + -> Read more at https://webpack.js.org/configuration/dev-server/#devserverserver + Details: + * options.server.options.pfx should be one of these: + [string | Buffer | object { … }, ...] | string | Buffer + -> Path to an SSL pfx file or content of an SSL pfx file. + Details: + * options.server.options.pfx should be an array: + [string | Buffer | object { … }, ...] + * options.server.options.pfx should be a string. + * options.server.options.pfx should be an instance of Buffer." +`; + +exports[`options validate should throw an error on the "server" option with '{"type":"https","options":{"requestCert":"false"}}' value 1`] = ` +"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. + - options.server.options.requestCert should be a boolean. + -> Request for an SSL certificate." +`; + exports[`options validate should throw an error on the "static" option with '' value 1`] = ` "ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options.static should be a non-empty string." diff --git a/test/cli/__snapshots__/basic.test.js.snap.webpack4 b/test/cli/__snapshots__/basic.test.js.snap.webpack4 index e0df6aac4f..447853a050 100644 --- a/test/cli/__snapshots__/basic.test.js.snap.webpack4 +++ b/test/cli/__snapshots__/basic.test.js.snap.webpack4 @@ -91,21 +91,21 @@ Options: --no-http2 Does not serve over HTTP/2 using SPDY. --https Allows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). --no-https Disallows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). - --https-passphrase Passphrase for a pfx file. - --https-request-cert Request for an SSL certificate. + --https-passphrase Passphrase for a pfx file. Deprecated, it will be removed in favor of the \`server.options.passphrase\` option. + --https-request-cert Request for an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.requestCert\` option. --no-https-request-cert Does not request for an SSL certificate. - --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. - --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-key Path to an SSL key or content of an SSL key. - --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. - --https-pfx Path to an SSL pfx file or content of an SSL pfx file. - --https-pfx-reset Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. - --https-cert Path to an SSL certificate or content of an SSL certificate. - --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. - --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). - --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.ca\` option. + --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.ca\` option. + --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. + --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. + --https-key Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. + --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. + --https-pfx Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. + --https-pfx-reset Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. + --https-cert Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. + --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. + --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the \`server.options.crl\` option. + --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the \`server.options.crl\` option. --ipc [value] Listen to a unix socket. --live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default). --no-live-reload Disables reload/refresh the page(s) when file changes are detected (enabled by default) @@ -120,6 +120,22 @@ Options: --open-target-reset Clear all items provided in 'open.target' configuration. Opens specified page in browser. --open-app-name-reset Clear all items provided in 'open.app.name' configuration. Open specified browser. --port Allows to specify a port to use. + --server-options-ca Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-ca-reset Clear all items provided in 'server.options.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cacert Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cacert-reset Clear all items provided in 'server.options.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cert Path to an SSL certificate or content of an SSL certificate. + --server-options-cert-reset Clear all items provided in 'server.options.cert' configuration. Path to an SSL certificate or content of an SSL certificate. + --server-options-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --server-options-crl-reset Clear all items provided in 'server.options.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --server-options-key Path to an SSL key or content of an SSL key. + --server-options-key-reset Clear all items provided in 'server.options.key' configuration. Path to an SSL key or content of an SSL key. + --server-options-passphrase Passphrase for a pfx file. + --server-options-pfx Path to an SSL pfx file or content of an SSL pfx file. + --server-options-pfx-reset Clear all items provided in 'server.options.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. + --server-options-request-cert Request for an SSL certificate. + --no-server-options-request-cert Negative 'server-options-request-cert' option. + --server-type Allows to set server and options (by default 'http'). --static [value...] Allows to configure options for serving static files from directory (by default 'public' directory). --no-static Negative 'static' option. --static-directory Directory for static contents. diff --git a/test/cli/__snapshots__/basic.test.js.snap.webpack5 b/test/cli/__snapshots__/basic.test.js.snap.webpack5 index bc996eea90..db8a66fbee 100644 --- a/test/cli/__snapshots__/basic.test.js.snap.webpack5 +++ b/test/cli/__snapshots__/basic.test.js.snap.webpack5 @@ -90,21 +90,21 @@ Options: --no-http2 Negative 'http2' option. --https Allows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). --no-https Negative 'https' option. - --https-passphrase Passphrase for a pfx file. - --https-request-cert Request for an SSL certificate. + --https-passphrase Passphrase for a pfx file. Deprecated, it will be removed in favor of the \`server.options.passphrase\` option. + --https-request-cert Request for an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.requestCert\` option. --no-https-request-cert Negative 'https-request-cert' option. - --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. - --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. - --https-cert Path to an SSL certificate or content of an SSL certificate. - --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. - --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). - --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). - --https-key Path to an SSL key or content of an SSL key. - --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. - --https-pfx Path to an SSL pfx file or content of an SSL pfx file. - --https-pfx-reset Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. + --https-ca Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.ca\` option. + --https-ca-reset Clear all items provided in 'https.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.ca\` option. + --https-cacert Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. + --https-cacert-reset Clear all items provided in 'https.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, it will be removed in favor of the \`server.options.cacert\` option. + --https-cert Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. + --https-cert-reset Clear all items provided in 'https.cert' configuration. Path to an SSL certificate or content of an SSL certificate. Deprecated, it will be removed in favor of the \`server.options.cert\` option. + --https-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the \`server.options.crl\` option. + --https-crl-reset Clear all items provided in 'https.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, it will be removed in favor of the \`server.options.crl\` option. + --https-key Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. + --https-key-reset Clear all items provided in 'https.key' configuration. Path to an SSL key or content of an SSL key. Deprecated, it will be removed in favor of the \`server.options.key\` option. + --https-pfx Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. + --https-pfx-reset Clear all items provided in 'https.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. Deprecated, it will be removed in favor of the \`server.options.pfx\` option. --ipc [value] Listen to a unix socket. --live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default). --no-live-reload Negative 'live-reload' option. @@ -119,6 +119,22 @@ Options: --open-target-reset Clear all items provided in 'open.target' configuration. Opens specified page in browser. --open-app-name-reset Clear all items provided in 'open.app.name' configuration. Open specified browser. --port Allows to specify a port to use. + --server-type Allows to set server and options (by default 'http'). + --server-options-passphrase Passphrase for a pfx file. + --server-options-request-cert Request for an SSL certificate. + --no-server-options-request-cert Negative 'server-options-request-cert' option. + --server-options-ca Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-ca-reset Clear all items provided in 'server.options.ca' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cacert Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cacert-reset Clear all items provided in 'server.options.cacert' configuration. Path to an SSL CA certificate or content of an SSL CA certificate. + --server-options-cert Path to an SSL certificate or content of an SSL certificate. + --server-options-cert-reset Clear all items provided in 'server.options.cert' configuration. Path to an SSL certificate or content of an SSL certificate. + --server-options-crl Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --server-options-crl-reset Clear all items provided in 'server.options.crl' configuration. Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). + --server-options-key Path to an SSL key or content of an SSL key. + --server-options-key-reset Clear all items provided in 'server.options.key' configuration. Path to an SSL key or content of an SSL key. + --server-options-pfx Path to an SSL pfx file or content of an SSL pfx file. + --server-options-pfx-reset Clear all items provided in 'server.options.pfx' configuration. Path to an SSL pfx file or content of an SSL pfx file. --static [value...] Allows to configure options for serving static files from directory (by default 'public' directory). --no-static Negative 'static' option. --static-directory Directory for static contents. diff --git a/test/cli/__snapshots__/https-option.test.js.snap.webpack4 b/test/cli/__snapshots__/https-option.test.js.snap.webpack4 index c00c673304..e4e06f2fdb 100644 --- a/test/cli/__snapshots__/https-option.test.js.snap.webpack4 +++ b/test/cli/__snapshots__/https-option.test.js.snap.webpack4 @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`"https" CLI option should warn using "--https-cacert" and "--https-ca" together 1`] = ` -" [webpack-dev-server] Do not specify 'https.ca' and 'https.cacert' options together, the 'https.ca' option will be used. +" [webpack-dev-server] Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used. [webpack-dev-server] Project is running at: [webpack-dev-server] Loopback: https://localhost:/ [webpack-dev-server] On Your Network (IPv4): https://:/ diff --git a/test/cli/__snapshots__/https-option.test.js.snap.webpack5 b/test/cli/__snapshots__/https-option.test.js.snap.webpack5 index c00c673304..e4e06f2fdb 100644 --- a/test/cli/__snapshots__/https-option.test.js.snap.webpack5 +++ b/test/cli/__snapshots__/https-option.test.js.snap.webpack5 @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`"https" CLI option should warn using "--https-cacert" and "--https-ca" together 1`] = ` -" [webpack-dev-server] Do not specify 'https.ca' and 'https.cacert' options together, the 'https.ca' option will be used. +" [webpack-dev-server] Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used. [webpack-dev-server] Project is running at: [webpack-dev-server] Loopback: https://localhost:/ [webpack-dev-server] On Your Network (IPv4): https://:/ diff --git a/test/cli/__snapshots__/server-option.test.js.snap.webpack4 b/test/cli/__snapshots__/server-option.test.js.snap.webpack4 new file mode 100644 index 0000000000..3d60d4ab2e --- /dev/null +++ b/test/cli/__snapshots__/server-option.test.js.snap.webpack4 @@ -0,0 +1,90 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`"server" CLI options should warn using "--server-options-cacert" and "--server-options-ca" together 1`] = ` +" [webpack-dev-server] Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used. + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--no-server-options-request-cert" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-ca " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-cacert " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key-reset --server-options-key --server-options-pfx-reset --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert-reset --server-options-cert --server-options-ca-reset --server-options-ca " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-request-cert" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type http" 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: http://localhost:/ + [webpack-dev-server] On Your Network (IPv4): http://:/ + [webpack-dev-server] On Your Network (IPv6): http://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type https" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type spdy" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; diff --git a/test/cli/__snapshots__/server-option.test.js.snap.webpack5 b/test/cli/__snapshots__/server-option.test.js.snap.webpack5 new file mode 100644 index 0000000000..3d60d4ab2e --- /dev/null +++ b/test/cli/__snapshots__/server-option.test.js.snap.webpack5 @@ -0,0 +1,90 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`"server" CLI options should warn using "--server-options-cacert" and "--server-options-ca" together 1`] = ` +" [webpack-dev-server] Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used. + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--no-server-options-request-cert" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-ca " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-cacert " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-key-reset --server-options-key --server-options-pfx-reset --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert-reset --server-options-cert --server-options-ca-reset --server-options-ca " 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-options-request-cert" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type http" 1`] = ` +" [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: http://localhost:/ + [webpack-dev-server] On Your Network (IPv4): http://:/ + [webpack-dev-server] On Your Network (IPv6): http://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type https" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; + +exports[`"server" CLI options should work using "--server-type spdy" 1`] = ` +" [webpack-dev-server] Generating SSL certificate... + [webpack-dev-server] SSL certificate: /node_modules/.cache/webpack-dev-server/server.pem + [webpack-dev-server] Project is running at: + [webpack-dev-server] Loopback: https://localhost:/ + [webpack-dev-server] On Your Network (IPv4): https://:/ + [webpack-dev-server] On Your Network (IPv6): https://[]:/ + [webpack-dev-server] Content not from webpack is served from '/public' directory" +`; diff --git a/test/cli/server-option.test.js b/test/cli/server-option.test.js new file mode 100644 index 0000000000..7b6d9b3eda --- /dev/null +++ b/test/cli/server-option.test.js @@ -0,0 +1,246 @@ +"use strict"; + +const path = require("path"); +const del = require("del"); +const Server = require("../../lib/Server"); +const { testBin, normalizeStderr } = require("../helpers/test-bin"); +const port = require("../ports-map")["cli-server"]; + +const httpsCertificateDirectory = path.resolve( + __dirname, + "../fixtures/https-certificate" +); + +const defaultCertificateDir = Server.findCacheDir(); + +describe('"server" CLI options', () => { + beforeEach(async () => { + await del([defaultCertificateDir]); + }); + + it('should work using "--server-type http"', async () => { + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "http", + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: false }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-type https"', async () => { + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-type spdy"', async () => { + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "spdy", + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-cacert "', async () => { + const pfxFile = path.join(httpsCertificateDirectory, "server.pfx"); + const key = path.join(httpsCertificateDirectory, "server.key"); + const cert = path.join(httpsCertificateDirectory, "server.crt"); + const cacert = path.join(httpsCertificateDirectory, "ca.pem"); + const passphrase = "webpack-dev-server"; + + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-key", + key, + "--server-options-pfx", + pfxFile, + "--server-options-passphrase", + passphrase, + "--server-options-cert", + cert, + "--server-options-cacert", + cacert, + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert --server-options-ca "', async () => { + const pfxFile = path.join(httpsCertificateDirectory, "server.pfx"); + const key = path.join(httpsCertificateDirectory, "server.key"); + const cert = path.join(httpsCertificateDirectory, "server.crt"); + const ca = path.join(httpsCertificateDirectory, "ca.pem"); + const passphrase = "webpack-dev-server"; + + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-key", + key, + "--server-options-pfx", + pfxFile, + "--server-options-passphrase", + passphrase, + "--server-options-cert", + cert, + "--server-options-ca", + ca, + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-options-key-reset --server-options-key --server-options-pfx-reset --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert-reset --server-options-cert --server-options-ca-reset --server-options-ca "', async () => { + const pfxFile = path.join(httpsCertificateDirectory, "server.pfx"); + const key = path.join(httpsCertificateDirectory, "server.key"); + const cert = path.join(httpsCertificateDirectory, "server.crt"); + const ca = path.join(httpsCertificateDirectory, "ca.pem"); + const passphrase = "webpack-dev-server"; + + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-key-reset", + "--server-options-key", + key, + "--server-options-pfx-reset", + "--server-options-pfx", + pfxFile, + "--server-options-passphrase", + passphrase, + "--server-options-cert-reset", + "--server-options-cert", + cert, + "--server-options-ca-reset", + "--server-options-ca", + ca, + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should warn using "--server-options-cacert" and "--server-options-ca" together', async () => { + const pfxFile = path.join(httpsCertificateDirectory, "server.pfx"); + const key = path.join(httpsCertificateDirectory, "server.key"); + const cert = path.join(httpsCertificateDirectory, "server.crt"); + const cacert = path.join(httpsCertificateDirectory, "ca.pem"); + const passphrase = "webpack-dev-server"; + + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-key", + key, + "--server-options-pfx", + pfxFile, + "--server-options-passphrase", + passphrase, + "--server-options-cert", + cert, + "--server-options-cacert", + cacert, + "--server-options-ca", + cacert, + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + // For https://github.com/webpack/webpack-dev-server/issues/3306 + it('should work using "--server-options-key --server-options-pfx --server-options-passphrase webpack-dev-server --server-options-cert "', async () => { + const pfxFile = path.join(httpsCertificateDirectory, "server.pfx"); + const key = path.join(httpsCertificateDirectory, "server.key"); + const cert = path.join(httpsCertificateDirectory, "server.crt"); + const passphrase = "webpack-dev-server"; + + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-key", + key, + "--server-options-pfx", + pfxFile, + "--server-options-passphrase", + passphrase, + "--server-options-cert", + cert, + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--server-options-request-cert"', async () => { + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--server-options-request-cert", + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); + + it('should work using "--no-server-options-request-cert"', async () => { + const { exitCode, stderr } = await testBin([ + "--port", + port, + "--server-type", + "https", + "--no-server-options-request-cert", + ]); + + expect(exitCode).toEqual(0); + expect( + normalizeStderr(stderr, { ipv6: true, https: true }) + ).toMatchSnapshot(); + }); +}); diff --git a/test/e2e/__snapshots__/https.test.js.snap.webpack4 b/test/e2e/__snapshots__/https.test.js.snap.webpack4 index 897728d71f..48326d2598 100644 --- a/test/e2e/__snapshots__/https.test.js.snap.webpack4 +++ b/test/e2e/__snapshots__/https.test.js.snap.webpack4 @@ -10,6 +10,7 @@ Object { "minVersion": "TLSv1.1", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -39,6 +40,7 @@ Object { "pfx": Array [ "", ], + "requestCert": false, } `; @@ -68,6 +70,7 @@ Object { "pfx": Array [ "", ], + "requestCert": false, } `; @@ -173,6 +176,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== "pfx": Array [ "", ], + "requestCert": false, } `; @@ -194,6 +198,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -223,6 +228,7 @@ Object { "buf": "", }, ], + "requestCert": false, } `; @@ -244,6 +250,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -341,6 +348,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== ", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -446,6 +454,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== "buf": "", }, ], + "requestCert": false, } `; @@ -467,6 +476,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -488,6 +498,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; diff --git a/test/e2e/__snapshots__/https.test.js.snap.webpack5 b/test/e2e/__snapshots__/https.test.js.snap.webpack5 index 897728d71f..48326d2598 100644 --- a/test/e2e/__snapshots__/https.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/https.test.js.snap.webpack5 @@ -10,6 +10,7 @@ Object { "minVersion": "TLSv1.1", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -39,6 +40,7 @@ Object { "pfx": Array [ "", ], + "requestCert": false, } `; @@ -68,6 +70,7 @@ Object { "pfx": Array [ "", ], + "requestCert": false, } `; @@ -173,6 +176,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== "pfx": Array [ "", ], + "requestCert": false, } `; @@ -194,6 +198,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -223,6 +228,7 @@ Object { "buf": "", }, ], + "requestCert": false, } `; @@ -244,6 +250,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -341,6 +348,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== ", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -446,6 +454,7 @@ QyvMqmN1kGy20SZbQDD/fLfqBQ== "buf": "", }, ], + "requestCert": false, } `; @@ -467,6 +476,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; @@ -488,6 +498,7 @@ Object { "key": "", "passphrase": "webpack-dev-server", "pfx": "", + "requestCert": false, } `; diff --git a/test/e2e/__snapshots__/server.test.js.snap.webpack4 b/test/e2e/__snapshots__/server.test.js.snap.webpack4 new file mode 100644 index 0000000000..ad324c4391 --- /dev/null +++ b/test/e2e/__snapshots__/server.test.js.snap.webpack4 @@ -0,0 +1,658 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`server option as object allow to pass more options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "minVersion": "TLSv1.1", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + ], + "cert": Array [ + "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + ], + "key": Array [ + "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": Array [ + Object { + "pem": "", + }, + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + Object { + "buf": "", + }, + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + "cert": "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + "key": "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + "cert": "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + "key": Array [ + Object { + "pem": "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + }, + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + Object { + "buf": "", + }, + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object should support the "requestCert" option should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object should support the "requestCert" option should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object should support the "requestCert" option should pass options to the 'https.createServer' method: https options 1`] = ` +Object { + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": true, +} +`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, + "spdy": Object { + "protocols": Array [ + "h2", + "http/1.1", + ], + }, +} +`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string http should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string http should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string http should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string http should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string https should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string https should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string https should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string https should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string spdy should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string spdy should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string spdy should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string spdy should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; diff --git a/test/e2e/__snapshots__/server.test.js.snap.webpack5 b/test/e2e/__snapshots__/server.test.js.snap.webpack5 new file mode 100644 index 0000000000..ad324c4391 --- /dev/null +++ b/test/e2e/__snapshots__/server.test.js.snap.webpack5 @@ -0,0 +1,658 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`server option as object allow to pass more options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "minVersion": "TLSv1.1", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object allow to pass more options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of buffers should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of paths to files should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + ], + "cert": Array [ + "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + ], + "key": Array [ + "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are array of strings should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": Array [ + Object { + "pem": "", + }, + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + Object { + "buf": "", + }, + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are buffer, key and pfx are objects should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are paths to files should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + "cert": "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + "key": "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are strings should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kv +C/hf5Ei1J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYu +Dy9WkFuMie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhs +EENnH6sUE9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2sw +duxJTWRINmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+ +T8emgklStASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABAoIBAGqWKPE1QnT3T+3J +G+ITz9P0dDFbvWltlTZmeSJh/s2q+WZloUNtBxdmwbqT/1QecnkyGgyzVCjvSKsu +CgVjWNVAhysgtNtxRT4BVflffBXLVH2qsBjpsLRGU6EcMXuPGTiEp3YRHNuO6Aj8 +oP8fEsCGPc9DlJMGgxQRAKlrVF8TN/0j6Qk+YpS4MZ0YFQfBY+WdKu04Z8TVTplQ +tTkiGpBI+Oj85jF59aQiizglJgADkAZ6zmbrctm/G9jPxh7JLS2cKI0ECZgK5yAc +pk10E1YWhoCksjr9arxy6fS9TiX9P15vv06k+s7c4c5X7XDm3X0GWeSbqBMJb8q7 +BhZQNzECgYEA4kAtymDBvFYiZFq7+lzQBRKAI1RCq7YqxlieumH0PSkie2bba3dW +NVdTi7at8+GDB9/cHUPKzg/skfJllek57MZmusiVwB/Lmp/IlW8YyGShdYZ7zQsV +KMWJljpky3BEDM5sb08wIkfrOkelI/S4Bqqabd9JzOMJzoTiVOlMam8CgYEA3ctN +yonWz2bsnCUstQvQCLdI5a8Q7GJvlH2awephxGXIKGUuRmyyop0AnRnIBEWtOQV7 +yZjW32bU+Wt+2BJ247EyJiIQ4gT+T51t+v/Wt1YNbL3dSj9ttOvwYd4H2W4E7EIO +GKIF4I39FM7r8NfG7YE7S1aVcnrqs01N3nhd9HMCgYEAjepbzpmqbAxLPk97oase +AFB+d6qetz5ozklAJwDSRprKukTmVR5hwMup5/UKX/OQURwl4WVojKCIb3NwLPxC +DTbVsUuoQv6uo6qeEr3A+dHFRQa6GP9eolhl2Ql/t+wPg0jn01oEgzxBXCkceNVD +qUrR2yE4FYBD4nqPzVsZR5kCgYEA1yTi7NkQeldIpZ6Z43T18753A/Xx4JsLyWqd +uAT3mV9x7V1Yqg++qGbLtZjQoPRFt85N6ZxMsqA5b0iK3mXq1auJDdx1rAlT9z6q +9JM/YNAkbZsvEVq9vIYxw31w98T1GYhpzBM+yDhzir+9tv5YhQKa1dXDWi1JhWwz +YN45pWkCgYEAxuVsJ4D4Th5o050ppWpnxM/WuMhIUKqaoFTVucMKFzn+g24y9pv5 +miYdNYIk4Y+4pzHG6ZGZSHJcQ9BLui6H/nLQnqkgCb2lT5nfp7/GKdus7BdcjPGs +fcV46yL7/X0m8nDb3hkwwrDTU4mKFkMrzKpjdZBsttEmW0Aw/3y36gU= +-----END RSA PRIVATE KEY----- +", + "cert": "-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJALz8gD/gAt0OMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDIzMTgyMTQ5WhcNMTkxMDIzMTgyMTQ5WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxAUVLFM+K3XDLQkBi7xt0s1Ip7JoHYDskzUDQNHjjMkUq5kvC/hf5Ei1 +J6qruJs3Xqg86Nl4+ed4ynUajAkRRibhp0P1SG1tgPssIK6iC7g8heYuDy9WkFuM +ie0513zjSn6bMEAK5TegxYAWCbaCZX/Fw9bDniabL/zuOv4sf8J4EPhsEENnH6sU +E9HxPUgQmNt1Tbd0j1Cd5PXrSTLyfVPRh0m9QhXTUHuxsse8XSn9U2swduxJTWRI +NmhffYn+O7kbJGI77xYr8u58Rsf3HCMI8DTKZNvQLChvvtLJ9ckyu7Q+T8emgklS +tASm3V2UtnriaK/IQEhgSdxqVRib3QIDAQABo1AwTjAdBgNVHQ4EFgQUDZBhVKdb +3BRhLIhuuE522Vsul0IwHwYDVR0jBBgwFoAUDZBhVKdb3BRhLIhuuE522Vsul0Iw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABh9WWZwWLgb9/DcTxL72 +6pI96t4jiF79Q+pPefkaIIi0mE6yodWrTAsBQu9I6bNRaEcCSoiXkP2bqskD/UGg +LwUFgSrDOAA3UjdHw3QU5g2NocduG7mcFwA40TB98sOsxsUyYlzSyWzoiQWwPYwb +hek1djuWkqPXsTjlj54PTPN/SjTFmo4p5Ip6nbRf2nOREl7v0rJpGbJvXiCMYyd+ +Zv+j4mRjCGo8ysMR2HjCUGkYReLAgKyyz3M7i8vevJhKslyOmy6Txn4F0nPVumaU +DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I +7Q== +-----END CERTIFICATE----- +", + "key": Array [ + Object { + "pem": "-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEBRUsUz4rdcMt +CQGLvG3SzUinsmgdgOyTNQNA0eOMyRSrmS8L+F/kSLUnqqu4mzdeqDzo2Xj553jK +dRqMCRFGJuGnQ/VIbW2A+ywgrqILuDyF5i4PL1aQW4yJ7TnXfONKfpswQArlN6DF +gBYJtoJlf8XD1sOeJpsv/O46/ix/wngQ+GwQQ2cfqxQT0fE9SBCY23VNt3SPUJ3k +9etJMvJ9U9GHSb1CFdNQe7Gyx7xdKf1TazB27ElNZEg2aF99if47uRskYjvvFivy +7nxGx/ccIwjwNMpk29AsKG++0sn1yTK7tD5Px6aCSVK0BKbdXZS2euJor8hASGBJ +3GpVGJvdAgMBAAECggEAapYo8TVCdPdP7ckb4hPP0/R0MVu9aW2VNmZ5ImH+zar5 +ZmWhQ20HF2bBupP/VB5yeTIaDLNUKO9Iqy4KBWNY1UCHKyC023FFPgFV+V98FctU +faqwGOmwtEZToRwxe48ZOISndhEc247oCPyg/x8SwIY9z0OUkwaDFBEAqWtUXxM3 +/SPpCT5ilLgxnRgVB8Fj5Z0q7ThnxNVOmVC1OSIakEj46PzmMXn1pCKLOCUmAAOQ +BnrOZuty2b8b2M/GHsktLZwojQQJmArnIBymTXQTVhaGgKSyOv1qvHLp9L1OJf0/ +Xm+/TqT6ztzhzlftcObdfQZZ5JuoEwlvyrsGFlA3MQKBgQDiQC3KYMG8ViJkWrv6 +XNAFEoAjVEKrtirGWJ66YfQ9KSJ7Zttrd1Y1V1OLtq3z4YMH39wdQ8rOD+yR8mWV +6Tnsxma6yJXAH8uan8iVbxjIZKF1hnvNCxUoxYmWOmTLcEQMzmxvTzAiR+s6R6Uj +9LgGqppt30nM4wnOhOJU6UxqbwKBgQDdy03KidbPZuycJSy1C9AIt0jlrxDsYm+U +fZrB6mHEZcgoZS5GbLKinQCdGcgERa05BXvJmNbfZtT5a37YEnbjsTImIhDiBP5P +nW36/9a3Vg1svd1KP2206/Bh3gfZbgTsQg4YogXgjf0Uzuvw18btgTtLVpVyeuqz +TU3eeF30cwKBgQCN6lvOmapsDEs+T3uhqx4AUH53qp63PmjOSUAnANJGmsq6ROZV +HmHAy6nn9Qpf85BRHCXhZWiMoIhvc3As/EINNtWxS6hC/q6jqp4SvcD50cVFBroY +/16iWGXZCX+37A+DSOfTWgSDPEFcKRx41UOpStHbITgVgEPieo/NWxlHmQKBgQDX +JOLs2RB6V0ilnpnjdPXzvncD9fHgmwvJap24BPeZX3HtXViqD76oZsu1mNCg9EW3 +zk3pnEyyoDlvSIreZerVq4kN3HWsCVP3Pqr0kz9g0CRtmy8RWr28hjHDfXD3xPUZ +iGnMEz7IOHOKv722/liFAprV1cNaLUmFbDNg3jmlaQKBgQDG5WwngPhOHmjTnSml +amfEz9a4yEhQqpqgVNW5wwoXOf6DbjL2m/maJh01giThj7inMcbpkZlIclxD0Eu6 +Lof+ctCeqSAJvaVPmd+nv8Yp26zsF1yM8ax9xXjrIvv9fSbycNveGTDCsNNTiYoW +QyvMqmN1kGy20SZbQDD/fLfqBQ== +-----END PRIVATE KEY----- +", + }, + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + Object { + "buf": "", + }, + ], + "requestCert": false, +} +`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object ca, pfx, key and cert are strings, key and pfx are objects should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object cacert and ca, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": "", + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": false, +} +`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object cacert, pfx, key and cert are buffer should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object options should be prioritized over http2 options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, +} +`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object options should be prioritized over https options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object should support the "requestCert" option should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object should support the "requestCert" option should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as object should support the "requestCert" option should pass options to the 'https.createServer' method: https options 1`] = ` +Object { + "cert": "", + "key": "", + "passphrase": "webpack-dev-server", + "pfx": "", + "requestCert": true, +} +`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): https options 1`] = ` +Object { + "ca": Array [ + "", + ], + "cert": Array [ + "", + ], + "key": Array [ + "", + ], + "passphrase": "webpack-dev-server", + "pfx": Array [ + "", + ], + "requestCert": false, + "spdy": Object { + "protocols": Array [ + "h2", + "http/1.1", + ], + }, +} +`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as object spdy server with options should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string http should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string http should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string http should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string http should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string https should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string https should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string https should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string https should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; + +exports[`server option as string spdy should handle GET request to index route (/): console messages 1`] = `Array []`; + +exports[`server option as string spdy should handle GET request to index route (/): page errors 1`] = `Array []`; + +exports[`server option as string spdy should handle GET request to index route (/): response status 1`] = `200`; + +exports[`server option as string spdy should handle GET request to index route (/): response text 1`] = ` +"Heyo. +" +`; diff --git a/test/e2e/server.test.js b/test/e2e/server.test.js new file mode 100644 index 0000000000..29c470b14f --- /dev/null +++ b/test/e2e/server.test.js @@ -0,0 +1,1587 @@ +"use strict"; + +const https = require("https"); +const path = require("path"); +const fs = require("graceful-fs"); +const request = require("supertest"); +const spdy = require("spdy"); +const webpack = require("webpack"); +const Server = require("../../lib/Server"); +const config = require("../fixtures/static-config/webpack.config"); +const runBrowser = require("../helpers/run-browser"); +const { skipTestOnWindows } = require("../helpers/conditional-test"); +const normalizeOptions = require("../helpers/normalize-options"); +const port = require("../ports-map")["server-option"]; + +const httpsCertificateDirectory = path.resolve( + __dirname, + "../fixtures/https-certificate" +); + +const staticDirectory = path.resolve( + __dirname, + "../fixtures/static-config/public" +); + +describe("server option", () => { + describe("as string", () => { + let compiler; + let server; + let page; + let browser; + let pageErrors; + let consoleMessages; + + describe("http", () => { + beforeEach(async () => { + compiler = webpack(config); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: "http", + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol + ); + + expect(HTTPVersion).not.toEqual("h2"); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("https", () => { + beforeEach(async () => { + compiler = webpack(config); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: "https", + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol + ); + + expect(HTTPVersion).not.toEqual("h2"); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("spdy", () => { + beforeEach(async () => { + compiler = webpack(config); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: "spdy", + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol + ); + + expect(HTTPVersion).toEqual("h2"); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + }); + + describe("as object", () => { + describe("ca, pfx, key and cert are buffer", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are array of buffers", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: [ + fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + ], + pfx: [ + fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + ], + key: [ + fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + ], + cert: [ + fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + ], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are strings", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), + // TODO + // pfx can't be string because it is binary format + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ) + .toString(), + cert: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ) + .toString(), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are array of strings", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: [ + fs + .readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ) + .toString(), + ], + // pfx can't be string because it is binary format + pfx: [ + fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + ], + key: [ + fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ) + .toString(), + ], + cert: [ + fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ) + .toString(), + ], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are paths to files", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: path.join(httpsCertificateDirectory, "ca.pem"), + pfx: path.join(httpsCertificateDirectory, "server.pfx"), + key: path.join(httpsCertificateDirectory, "server.key"), + cert: path.join(httpsCertificateDirectory, "server.crt"), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are array of paths to files", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: [path.join(httpsCertificateDirectory, "ca.pem")], + pfx: [path.join(httpsCertificateDirectory, "server.pfx")], + key: [path.join(httpsCertificateDirectory, "server.key")], + cert: [path.join(httpsCertificateDirectory, "server.crt")], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are symlinks", () => { + if (skipTestOnWindows("Symlinks are not supported on Windows")) { + return; + } + + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: path.join(httpsCertificateDirectory, "ca-symlink.pem"), + pfx: path.join(httpsCertificateDirectory, "server-symlink.pfx"), + key: path.join(httpsCertificateDirectory, "server-symlink.key"), + cert: path.join( + httpsCertificateDirectory, + "server-symlink.crt" + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect(response.status()).toEqual(200); + expect(await response.text()).toContain("Heyo"); + expect(consoleMessages.map((message) => message.text())).toEqual([]); + expect(pageErrors).toEqual([]); + }); + }); + + describe("cacert, pfx, key and cert are buffer", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + cacert: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("cacert and ca, pfx, key and cert are buffer", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + cacert: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are buffer, key and pfx are objects", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + pfx: [ + { + buf: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + }, + ], + key: [ + { + pem: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + }, + ], + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("ca, pfx, key and cert are strings, key and pfx are objects", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + ca: fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), + pfx: [ + { + // pfx can't be string because it is binary format + buf: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + }, + ], + key: [ + { + pem: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ) + .toString(), + }, + ], + cert: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ) + .toString(), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("allow to pass more options", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + minVersion: "TLSv1.1", + ca: fs.readFileSync( + path.join(httpsCertificateDirectory, "ca.pem") + ), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + // puppeteer having issues accepting SSL here, throwing error net::ERR_BAD_SSL_CLIENT_AUTH_CERT, hence testing with supertest + describe('should support the "requestCert" option', () => { + let compiler; + let server; + let createServerSpy; + let req; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "https", + options: { + requestCert: true, + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ), + cert: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ), + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + req = request(server.app); + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await server.stop(); + }); + + it("should pass options to the 'https.createServer' method", async () => { + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + }); + + it("should handle GET request to index route (/)", async () => { + const response = await req.get("/"); + + expect(response.status).toMatchSnapshot("response status"); + expect(response.text).toMatchSnapshot("response text"); + }); + }); + + describe("options should be prioritized over https options", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + https: { + requestCert: true, + ca: fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), + // TODO + // pfx can't be string because it is binary format + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ) + .toString(), + cert: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ) + .toString(), + passphrase: "webpack-dev-server", + }, + server: { + type: "https", + options: { + requestCert: false, + ca: [path.join(httpsCertificateDirectory, "ca.pem")], + pfx: [path.join(httpsCertificateDirectory, "server.pfx")], + key: [path.join(httpsCertificateDirectory, "server.key")], + cert: [path.join(httpsCertificateDirectory, "server.crt")], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("options should be prioritized over http2 options", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(https, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + https: { + requestCert: true, + ca: fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), + // TODO + // pfx can't be string because it is binary format + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx") + ), + key: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.key") + ) + .toString(), + cert: fs + .readFileSync( + path.join(httpsCertificateDirectory, "server.crt") + ) + .toString(), + passphrase: "webpack-dev-server", + }, + http2: true, + server: { + type: "https", + options: { + requestCert: false, + ca: [path.join(httpsCertificateDirectory, "ca.pem")], + pfx: [path.join(httpsCertificateDirectory, "server.pfx")], + key: [path.join(httpsCertificateDirectory, "server.key")], + cert: [path.join(httpsCertificateDirectory, "server.crt")], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("spdy server with options", () => { + let compiler; + let server; + let createServerSpy; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack(config); + + createServerSpy = jest.spyOn(spdy, "createServer"); + + server = new Server( + { + static: { + directory: staticDirectory, + watch: false, + }, + server: { + type: "spdy", + options: { + requestCert: false, + ca: [path.join(httpsCertificateDirectory, "ca.pem")], + pfx: [path.join(httpsCertificateDirectory, "server.pfx")], + key: [path.join(httpsCertificateDirectory, "server.key")], + cert: [path.join(httpsCertificateDirectory, "server.crt")], + passphrase: "webpack-dev-server", + }, + }, + port, + }, + compiler + ); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + createServerSpy.mockRestore(); + + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`https://127.0.0.1:${port}/`, { + waitUntil: "networkidle0", + }); + + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol + ); + + expect(HTTPVersion).toEqual("h2"); + expect( + normalizeOptions(createServerSpy.mock.calls[0][0]) + ).toMatchSnapshot("https options"); + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + }); +}); diff --git a/test/ports-map.js b/test/ports-map.js index f2bc714e5a..231f7f6640 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -75,6 +75,8 @@ const listOfTests = { port: 1, "web-socket-server-test": 1, "client-reconnect-option": 1, + "cli-server": 1, + "server-option": 1, }; let startPort = 8089; diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack4 b/test/server/__snapshots__/Server.test.js.snap.webpack4 index 2d257aa5ef..d394c36fa9 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack4 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack4 @@ -75,6 +75,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -118,6 +122,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -162,6 +170,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -208,6 +220,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -254,6 +270,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -299,6 +319,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -344,6 +368,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -388,6 +416,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -432,6 +464,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -476,6 +512,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -522,6 +562,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -568,6 +612,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -613,6 +661,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -656,6 +708,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -699,6 +755,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -742,6 +802,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -785,6 +849,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -828,6 +896,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -871,6 +943,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -914,6 +990,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -957,6 +1037,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1000,6 +1084,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1043,6 +1131,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1086,6 +1178,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1129,6 +1225,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1172,6 +1272,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1215,6 +1319,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1258,6 +1366,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1303,6 +1415,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1348,6 +1464,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1393,6 +1513,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1438,6 +1562,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1492,6 +1620,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1546,6 +1678,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1600,6 +1736,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1643,6 +1783,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": false, "watchFiles": Array [], @@ -1674,6 +1818,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1717,6 +1865,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1760,6 +1912,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1803,6 +1959,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1847,6 +2007,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1890,6 +2054,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1931,6 +2099,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1974,6 +2146,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2019,6 +2195,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2062,6 +2242,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2108,6 +2292,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2151,6 +2339,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2194,6 +2386,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { diff --git a/test/server/__snapshots__/Server.test.js.snap.webpack5 b/test/server/__snapshots__/Server.test.js.snap.webpack5 index 2d257aa5ef..d394c36fa9 100644 --- a/test/server/__snapshots__/Server.test.js.snap.webpack5 +++ b/test/server/__snapshots__/Server.test.js.snap.webpack5 @@ -75,6 +75,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -118,6 +122,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -162,6 +170,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -208,6 +220,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -254,6 +270,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -299,6 +319,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -344,6 +368,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -388,6 +416,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -432,6 +464,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -476,6 +512,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -522,6 +562,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -568,6 +612,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -613,6 +661,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -656,6 +708,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -699,6 +755,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -742,6 +802,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -785,6 +849,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -828,6 +896,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -871,6 +943,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -914,6 +990,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -957,6 +1037,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1000,6 +1084,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1043,6 +1131,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1086,6 +1178,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1129,6 +1225,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1172,6 +1272,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1215,6 +1319,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1258,6 +1366,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1303,6 +1415,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1348,6 +1464,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1393,6 +1513,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1438,6 +1562,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1492,6 +1620,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1546,6 +1678,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1600,6 +1736,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1643,6 +1783,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": false, "watchFiles": Array [], @@ -1674,6 +1818,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1717,6 +1865,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1760,6 +1912,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1803,6 +1959,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1847,6 +2007,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1890,6 +2054,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1931,6 +2099,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -1974,6 +2146,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2019,6 +2195,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2062,6 +2242,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2108,6 +2292,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2151,6 +2339,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { @@ -2194,6 +2386,10 @@ Object { "magicHtml": true, "open": Array [], "port": "", + "server": Object { + "options": Object {}, + "type": "http", + }, "setupExitSignals": true, "static": Array [ Object { diff --git a/test/validate-options.test.js b/test/validate-options.test.js index bb319acef6..fbd4fd805e 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -388,6 +388,75 @@ const tests = { ], failure: [() => {}, false], }, + server: { + success: [ + "http", + "https", + "spdy", + { + type: "http", + }, + { + type: "https", + }, + { + type: "spdy", + }, + { + type: "https", + options: { + ca: path.join(httpsCertificateDirectory, "ca.pem"), + key: path.join(httpsCertificateDirectory, "server.key"), + pfx: path.join(httpsCertificateDirectory, "server.pfx"), + cert: path.join(httpsCertificateDirectory, "server.crt"), + requestCert: true, + passphrase: "webpack-dev-server", + }, + }, + ], + failure: [ + { + type: "https", + additional: "test", + }, + { + type: "https", + options: { + key: 10, + }, + }, + { + type: "https", + options: { + cert: true, + }, + }, + { + type: "https", + options: { + ca: true, + }, + }, + { + type: "https", + options: { + pfx: 10, + }, + }, + { + type: "https", + options: { + passphrase: false, + }, + }, + { + type: "https", + options: { + requestCert: "false", + }, + }, + ], + }, static: { success: [ "path",