123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /**
- * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
- * @returns {string}
- */
- function format(objURL) {
- var protocol = objURL.protocol || "";
- if (protocol && protocol.substr(-1) !== ":") {
- protocol += ":";
- }
- var auth = objURL.auth || "";
- if (auth) {
- auth = encodeURIComponent(auth);
- auth = auth.replace(/%3A/i, ":");
- auth += "@";
- }
- var host = "";
- if (objURL.hostname) {
- host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
- if (objURL.port) {
- host += ":".concat(objURL.port);
- }
- }
- var pathname = objURL.pathname || "";
- if (objURL.slashes) {
- host = "//".concat(host || "");
- if (pathname && pathname.charAt(0) !== "/") {
- pathname = "/".concat(pathname);
- }
- } else if (!host) {
- host = "";
- }
- var search = objURL.search || "";
- if (search && search.charAt(0) !== "?") {
- search = "?".concat(search);
- }
- var hash = objURL.hash || "";
- if (hash && hash.charAt(0) !== "#") {
- hash = "#".concat(hash);
- }
- pathname = pathname.replace(/[?#]/g,
- /**
- * @param {string} match
- * @returns {string}
- */
- function (match) {
- return encodeURIComponent(match);
- });
- search = search.replace("#", "%23");
- return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
- }
- /**
- * @param {URL & { fromCurrentScript?: boolean }} parsedURL
- * @returns {string}
- */
- function createSocketURL(parsedURL) {
- var hostname = parsedURL.hostname; // Node.js module parses it as `::`
- // `new URL(urlString, [baseURLString])` parses it as '[::]'
- var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]"; // why do we need this check?
- // hostname n/a for file protocol (example, when using electron, ionic)
- // see: https://github.com/webpack/webpack-dev-server/pull/384
- if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf("http") === 0) {
- hostname = self.location.hostname;
- }
- var socketURLProtocol = parsedURL.protocol || self.location.protocol; // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
- if (socketURLProtocol === "auto:" || hostname && isInAddrAny && self.location.protocol === "https:") {
- socketURLProtocol = self.location.protocol;
- }
- socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
- var socketURLAuth = ""; // `new URL(urlString, [baseURLstring])` doesn't have `auth` property
- // Parse authentication credentials in case we need them
- if (parsedURL.username) {
- socketURLAuth = parsedURL.username; // Since HTTP basic authentication does not allow empty username,
- // we only include password if the username is not empty.
- if (parsedURL.password) {
- // Result: <username>:<password>
- socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
- }
- } // In case the host is a raw IPv6 address, it can be enclosed in
- // the brackets as the brackets are needed in the final URL string.
- // Need to remove those as url.format blindly adds its own set of brackets
- // if the host string contains colons. That would lead to non-working
- // double brackets (e.g. [[::]]) host
- //
- // All of these web socket url params are optionally passed in through resourceQuery,
- // so we need to fall back to the default if they are not provided
- var socketURLHostname = (hostname || self.location.hostname || "localhost").replace(/^\[(.*)\]$/, "$1");
- var socketURLPort = parsedURL.port;
- if (!socketURLPort || socketURLPort === "0") {
- socketURLPort = self.location.port;
- } // If path is provided it'll be passed in via the resourceQuery as a
- // query param so it has to be parsed out of the querystring in order for the
- // client to open the socket to the correct location.
- var socketURLPathname = "/ws";
- if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
- socketURLPathname = parsedURL.pathname;
- }
- return format({
- protocol: socketURLProtocol,
- auth: socketURLAuth,
- hostname: socketURLHostname,
- port: socketURLPort,
- pathname: socketURLPathname,
- slashes: true
- });
- }
- export default createSocketURL;
|