123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- "use strict";
- const sockjs = require("sockjs");
- const BaseServer = require("./BaseServer");
- /** @typedef {import("../Server").WebSocketServerConfiguration} WebSocketServerConfiguration */
- /** @typedef {import("../Server").ClientConnection} ClientConnection */
- // Workaround for sockjs@~0.3.19
- // sockjs will remove Origin header, however Origin header is required for checking host.
- // See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
- {
- // @ts-ignore
- const SockjsSession = require("sockjs/lib/transport").Session;
- const decorateConnection = SockjsSession.prototype.decorateConnection;
- /**
- * @param {import("http").IncomingMessage} req
- */
- // eslint-disable-next-line func-names
- SockjsSession.prototype.decorateConnection = function (req) {
- decorateConnection.call(this, req);
- const connection = this.connection;
- if (
- connection.headers &&
- !("origin" in connection.headers) &&
- "origin" in req.headers
- ) {
- connection.headers.origin = req.headers.origin;
- }
- };
- }
- module.exports = class SockJSServer extends BaseServer {
- // options has: error (function), debug (function), server (http/s server), path (string)
- /**
- * @param {import("../Server")} server
- */
- constructor(server) {
- super(server);
- this.implementation = sockjs.createServer({
- // Use provided up-to-date sockjs-client
- sockjs_url: "/__webpack_dev_server__/sockjs.bundle.js",
- // Default logger is very annoy. Limit useless logs.
- /**
- * @param {string} severity
- * @param {string} line
- */
- log: (severity, line) => {
- if (severity === "error") {
- this.server.logger.error(line);
- } else if (severity === "info") {
- this.server.logger.log(line);
- } else {
- this.server.logger.debug(line);
- }
- },
- });
- /**
- * @param {import("sockjs").ServerOptions & { path?: string }} options
- * @returns {string | undefined}
- */
- const getPrefix = (options) => {
- if (typeof options.prefix !== "undefined") {
- return options.prefix;
- }
- return options.path;
- };
- const options = {
- .../** @type {WebSocketServerConfiguration} */
- (this.server.options.webSocketServer).options,
- prefix: getPrefix(
- /** @type {NonNullable<WebSocketServerConfiguration["options"]>} */
- (
- /** @type {WebSocketServerConfiguration} */
- (this.server.options.webSocketServer).options
- )
- ),
- };
- this.implementation.installHandlers(
- /** @type {import("http").Server} */ (this.server.server),
- options
- );
- this.implementation.on("connection", (client) => {
- // @ts-ignore
- // Implement the the same API as for `ws`
- client.send = client.write;
- // @ts-ignore
- client.terminate = client.close;
- this.clients.push(/** @type {ClientConnection} */ (client));
- client.on("close", () => {
- this.clients.splice(
- this.clients.indexOf(/** @type {ClientConnection} */ (client)),
- 1
- );
- });
- });
- // @ts-ignore
- this.implementation.close = (callback) => {
- callback();
- };
- }
- };
|