Skip to content

Commit

Permalink
Merge branch 'master' into node-ci
Browse files Browse the repository at this point in the history
  • Loading branch information
anshumanv authored Jun 5, 2021
2 parents 5175dea + c0a0228 commit ab93549
Show file tree
Hide file tree
Showing 13 changed files with 434 additions and 193 deletions.
6 changes: 5 additions & 1 deletion client-src/utils/createSocketURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ function createSocketURL(parsedURL) {
hostname = self.location.hostname;
}

if (protocol === 'auto:') {
protocol = self.location.protocol;
}

// `hostname` can be empty when the script path is relative. In that case, specifying a protocol would result in an invalid URL.
// When https is used in the app, secure websockets are always necessary because the browser doesn't accept non-secure websockets.
// When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
if (hostname && isInAddrAny && self.location.protocol === 'https:') {
protocol = self.location.protocol;
}
Expand Down
79 changes: 48 additions & 31 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Server {

this.setupHooks();
this.setupApp();
this.setupCheckHostRoute();
this.setupHostHeaderCheck();
this.setupDevMiddleware();

// Should be after `webpack-dev-middleware`, otherwise other middlewares might rewrite response
Expand Down Expand Up @@ -99,7 +99,7 @@ class Server {
msg = `${msg} (${addInfo})`;
}

this.sockWrite(this.sockets, 'progress-update', {
this.sendMessage(this.sockets, 'progress-update', {
percent,
msg,
pluginName,
Expand All @@ -120,7 +120,7 @@ class Server {
setupHooks() {
// Listening for events
const invalidPlugin = () => {
this.sockWrite(this.sockets, 'invalid');
this.sendMessage(this.sockets, 'invalid');
};

const addHooks = (compiler) => {
Expand All @@ -141,9 +141,9 @@ class Server {
}
}

setupCheckHostRoute() {
setupHostHeaderCheck() {
this.app.all('*', (req, res, next) => {
if (this.checkHost(req.headers)) {
if (this.checkHostHeader(req.headers)) {
return next();
}

Expand Down Expand Up @@ -251,13 +251,22 @@ class Server {
setupHistoryApiFallbackFeature() {
const historyApiFallback = require('connect-history-api-fallback');

const fallback =
typeof this.options.historyApiFallback === 'object'
const options =
typeof this.options.historyApiFallback !== 'boolean'
? this.options.historyApiFallback
: null;
: {};

let logger;

if (typeof options.verbose === 'undefined') {
logger = this.logger.log.bind(
this.logger,
'[connect-history-api-fallback]'
);
}

// Fall back to /index.html if nothing else matches.
this.app.use(historyApiFallback(fallback));
this.app.use(historyApiFallback({ logger, ...options }));
}

setupStaticFeature() {
Expand Down Expand Up @@ -464,7 +473,7 @@ class Server {
});
}

createSocketServer() {
createWebSocketServer() {
this.socketServer = new this.SocketServerImplementation(this);

this.socketServer.onConnection((connection, headers) => {
Expand All @@ -479,8 +488,12 @@ class Server {
);
}

if (!headers || !this.checkHost(headers) || !this.checkOrigin(headers)) {
this.sockWrite([connection], 'error', 'Invalid Host/Origin header');
if (
!headers ||
!this.checkHostHeader(headers) ||
!this.checkOriginHeader(headers)
) {
this.sendMessage([connection], 'error', 'Invalid Host/Origin header');

this.socketServer.close(connection);

Expand All @@ -498,19 +511,23 @@ class Server {
});

if (this.options.hot === true || this.options.hot === 'only') {
this.sockWrite([connection], 'hot');
this.sendMessage([connection], 'hot');
}

if (this.options.liveReload) {
this.sockWrite([connection], 'liveReload');
this.sendMessage([connection], 'liveReload');
}

if (this.options.client.progress) {
this.sockWrite([connection], 'progress', this.options.client.progress);
this.sendMessage(
[connection],
'progress',
this.options.client.progress
);
}

if (this.options.client.overlay) {
this.sockWrite([connection], 'overlay', this.options.client.overlay);
this.sendMessage([connection], 'overlay', this.options.client.overlay);
}

if (!this.stats) {
Expand All @@ -521,7 +538,7 @@ class Server {
});
}

showStatus() {
logStatus() {
const useColor = getColorsOption(getCompilerConfigArray(this.compiler));
const protocol = this.options.https ? 'https' : 'http';
const { address, port } = this.server.address();
Expand Down Expand Up @@ -702,7 +719,7 @@ class Server {
this.options.host,
(error) => {
if (this.options.hot || this.options.liveReload) {
this.createSocketServer();
this.createWebSocketServer();
}

if (this.options.bonjour) {
Expand All @@ -711,7 +728,7 @@ class Server {
runBonjour(this.options);
}

this.showStatus();
this.logStatus();

if (fn) {
fn.call(this.server, error);
Expand Down Expand Up @@ -823,15 +840,15 @@ class Server {
next();
}

checkHost(headers) {
return this.checkHeaders(headers, 'host');
checkHostHeader(headers) {
return this.checkHeader(headers, 'host');
}

checkOrigin(headers) {
return this.checkHeaders(headers, 'origin');
checkOriginHeader(headers) {
return this.checkHeader(headers, 'origin');
}

checkHeaders(headers, headerToCheck) {
checkHeader(headers, headerToCheck) {
// allow user to opt out of this security check, at their own risk
// by explicitly enabling allowedHosts
if (this.options.allowedHosts === 'all') {
Expand Down Expand Up @@ -912,7 +929,7 @@ class Server {
return false;
}

sockWrite(sockets, type, data) {
sendMessage(sockets, type, data) {
sockets.forEach((socket) => {
this.socketServer.send(socket, JSON.stringify({ type, data }));
});
Expand Down Expand Up @@ -952,19 +969,19 @@ class Server {
stats.assets.every((asset) => !asset.emitted);

if (shouldEmit) {
this.sockWrite(sockets, 'still-ok');
this.sendMessage(sockets, 'still-ok');

return;
}

this.sockWrite(sockets, 'hash', stats.hash);
this.sendMessage(sockets, 'hash', stats.hash);

if (stats.errors.length > 0) {
this.sockWrite(sockets, 'errors', stats.errors);
this.sendMessage(sockets, 'errors', stats.errors);
} else if (stats.warnings.length > 0) {
this.sockWrite(sockets, 'warnings', stats.warnings);
this.sendMessage(sockets, 'warnings', stats.warnings);
} else {
this.sockWrite(sockets, 'ok');
this.sendMessage(sockets, 'ok');
}
}

Expand Down Expand Up @@ -1005,7 +1022,7 @@ class Server {
// disabling refreshing on changing the content
if (this.options.liveReload) {
watcher.on('change', () => {
this.sockWrite(this.sockets, 'static-changed', watchPath);
this.sendMessage(this.sockets, 'static-changed', watchPath);
});
}

Expand Down
12 changes: 12 additions & 0 deletions lib/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,18 @@
"type": "object",
"additionalProperties": false,
"properties": {
"protocol": {
"anyOf": [
{
"enum": ["auto"]
},
{
"type": "string",
"minLength": 1
}
],
"description": "Tells clients connected to devServer to use the provided protocol."
},
"host": {
"type": "string",
"minLength": 1,
Expand Down
13 changes: 10 additions & 3 deletions lib/utils/DevServerPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ class DevServerPlugin {
apply(compiler) {
const { options } = this;

/** @type {"ws" | "wss"} */
const protocol = options.https ? 'wss' : 'ws';
/** @type {"ws:" | "wss:" | "http:" | "https:" | "auto:"} */
let protocol;

// We are proxying dev server and need to specify custom `host`
if (typeof options.client.webSocketURL.protocol !== 'undefined') {
protocol = options.client.webSocketURL.protocol;
} else {
protocol = options.https ? 'wss:' : 'ws:';
}

/** @type {string} */
let host;
Expand Down Expand Up @@ -111,7 +118,7 @@ class DevServerPlugin {

const webSocketURL = encodeURIComponent(
new URL(
`${protocol}://${ipaddr.IPv6.isIPv6(host) ? `[${host}]` : host}${
`${protocol}//${ipaddr.IPv6.isIPv6(host) ? `[${host}]` : host}${
port ? `:${port}` : ''
}${path || '/'}${
Object.keys(searchParams).length > 0
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/normalizeOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ function normalizeOptions(compiler, options, logger) {
const parsedURL = new URL(options.client.webSocketURL);

options.client.webSocketURL = {
protocol: parsedURL.protocol,
host: parsedURL.hostname,
port: Number(parsedURL.port),
port: parsedURL.port.length > 0 ? Number(parsedURL.port) : '',
path: parsedURL.pathname,
};
} else if (typeof options.client.webSocketURL.port === 'string') {
Expand Down
Loading

0 comments on commit ab93549

Please sign in to comment.