| 'use strict'; |
| /* global self */ |
| |
| var url = require('url'); |
| |
| var querystring = require('querystring'); |
| |
| var getCurrentScriptSource = require('./getCurrentScriptSource'); |
| |
| function createSocketUrl(resourceQuery) { |
| var urlParts; |
| |
| if (typeof resourceQuery === 'string' && resourceQuery !== '') { |
| // If this bundle is inlined, use the resource query to get the correct url. |
| urlParts = url.parse(resourceQuery.substr(1)); |
| } else { |
| // Else, get the url from the <script> this file was called with. |
| var scriptHost = getCurrentScriptSource(); // eslint-disable-next-line no-useless-escape |
| |
| scriptHost = scriptHost.replace(/\/[^\/]+$/, ''); |
| urlParts = url.parse(scriptHost || '/', false, true); |
| } |
| |
| if (!urlParts.port || urlParts.port === '0') { |
| urlParts.port = self.location.port; |
| } |
| |
| var _urlParts = urlParts, |
| auth = _urlParts.auth, |
| path = _urlParts.path; |
| var _urlParts2 = urlParts, |
| hostname = _urlParts2.hostname, |
| protocol = _urlParts2.protocol; // check ipv4 and ipv6 `all 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 ((hostname === '0.0.0.0' || hostname === '::') && self.location.hostname && // eslint-disable-next-line no-bitwise |
| !!~self.location.protocol.indexOf('http')) { |
| hostname = self.location.hostname; |
| } // `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. |
| |
| |
| if (hostname && (self.location.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) { |
| protocol = self.location.protocol; |
| } // default values of the sock url if they are not provided |
| |
| |
| var sockHost = hostname; |
| var sockPath = '/sockjs-node'; |
| var sockPort = urlParts.port; // eslint-disable-next-line no-undefined |
| |
| if (path !== null && path !== undefined && path !== '/') { |
| var parsedQuery = querystring.parse(path); // all of these sock url params are optionally passed in through |
| // resourceQuery, so we need to fall back to the default if |
| // they are not provided |
| |
| sockHost = parsedQuery.sockHost || sockHost; |
| sockPath = parsedQuery.sockPath || sockPath; |
| sockPort = parsedQuery.sockPort || sockPort; |
| } |
| |
| return url.format({ |
| protocol: protocol, |
| auth: auth, |
| hostname: sockHost, |
| port: sockPort, |
| // If sockPath 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. |
| pathname: sockPath |
| }); |
| } |
| |
| module.exports = createSocketUrl; |