UNPKG

2.98 kBJavaScriptView Raw
1'use strict';
2/* global self */
3
4var url = require('url');
5
6var getCurrentScriptSource = require('./getCurrentScriptSource');
7
8function createSocketUrl(resourceQuery, currentLocation) {
9 var urlParts;
10
11 if (typeof resourceQuery === 'string' && resourceQuery !== '') {
12 // If this bundle is inlined, use the resource query to get the correct url.
13 // format is like `?http://0.0.0.0:8096&sockPort=8097&sockHost=localhost`
14 urlParts = url.parse(resourceQuery // strip leading `?` from query string to get a valid URL
15 .substr(1) // replace first `&` with `?` to have a valid query string
16 .replace('&', '?'), true);
17 } else {
18 // Else, get the url from the <script> this file was called with.
19 var scriptHost = getCurrentScriptSource();
20 urlParts = url.parse(scriptHost || '/', true, true);
21 } // Use parameter to allow passing location in unit tests
22
23
24 if (typeof currentLocation === 'string' && currentLocation !== '') {
25 currentLocation = url.parse(currentLocation);
26 } else {
27 currentLocation = self.location;
28 }
29
30 return getSocketUrl(urlParts, currentLocation);
31}
32/*
33 * Gets socket URL based on Script Source/Location
34 * (scriptSrc: URL, location: URL) -> URL
35 */
36
37
38function getSocketUrl(urlParts, loc) {
39 var auth = urlParts.auth,
40 query = urlParts.query;
41 var hostname = urlParts.hostname,
42 protocol = urlParts.protocol,
43 port = urlParts.port;
44
45 if (!port || port === '0') {
46 port = loc.port;
47 } // check ipv4 and ipv6 `all hostname`
48 // why do we need this check?
49 // hostname n/a for file protocol (example, when using electron, ionic)
50 // see: https://github.com/webpack/webpack-dev-server/pull/384
51
52
53 if ((hostname === '0.0.0.0' || hostname === '::') && loc.hostname && loc.protocol.indexOf('http') === 0) {
54 hostname = loc.hostname;
55 } // `hostname` can be empty when the script path is relative. In that case, specifying
56 // a protocol would result in an invalid URL.
57 // When https is used in the app, secure websockets are always necessary
58 // because the browser doesn't accept non-secure websockets.
59
60
61 if (hostname && hostname !== '127.0.0.1' && (loc.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) {
62 protocol = loc.protocol;
63 } // all of these sock url params are optionally passed in through
64 // resourceQuery, so we need to fall back to the default if
65 // they are not provided
66
67
68 var sockHost = query.sockHost || hostname;
69 var sockPath = query.sockPath || '/sockjs-node';
70 var sockPort = query.sockPort || port;
71
72 if (sockPort === 'location') {
73 sockPort = loc.port;
74 }
75
76 return url.format({
77 protocol: protocol,
78 auth: auth,
79 hostname: sockHost,
80 port: sockPort,
81 // If sockPath is provided it'll be passed in via the resourceQuery as a
82 // query param so it has to be parsed out of the querystring in order for the
83 // client to open the socket to the correct location.
84 pathname: sockPath
85 });
86}
87
88module.exports = createSocketUrl;
\No newline at end of file