You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					88 lines
				
				2.9 KiB
			
		
		
			
		
	
	
					88 lines
				
				2.9 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								/* global self */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var url = require('url');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var getCurrentScriptSource = require('./getCurrentScriptSource');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function createSocketUrl(resourceQuery, currentLocation) {
							 | 
						||
| 
								 | 
							
								  var urlParts;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (typeof resourceQuery === 'string' && resourceQuery !== '') {
							 | 
						||
| 
								 | 
							
								    // If this bundle is inlined, use the resource query to get the correct url.
							 | 
						||
| 
								 | 
							
								    // format is like `?http://0.0.0.0:8096&sockPort=8097&sockHost=localhost`
							 | 
						||
| 
								 | 
							
								    urlParts = url.parse(resourceQuery // strip leading `?` from query string to get a valid URL
							 | 
						||
| 
								 | 
							
								    .substr(1) // replace first `&` with `?` to have a valid query string
							 | 
						||
| 
								 | 
							
								    .replace('&', '?'), true);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // Else, get the url from the <script> this file was called with.
							 | 
						||
| 
								 | 
							
								    var scriptHost = getCurrentScriptSource();
							 | 
						||
| 
								 | 
							
								    urlParts = url.parse(scriptHost || '/', true, true);
							 | 
						||
| 
								 | 
							
								  } // Use parameter to allow passing location in unit tests
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (typeof currentLocation === 'string' && currentLocation !== '') {
							 | 
						||
| 
								 | 
							
								    currentLocation = url.parse(currentLocation);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    currentLocation = self.location;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return getSocketUrl(urlParts, currentLocation);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Gets socket URL based on Script Source/Location
							 | 
						||
| 
								 | 
							
								 * (scriptSrc: URL, location: URL) -> URL
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getSocketUrl(urlParts, loc) {
							 | 
						||
| 
								 | 
							
								  var auth = urlParts.auth,
							 | 
						||
| 
								 | 
							
								      query = urlParts.query;
							 | 
						||
| 
								 | 
							
								  var hostname = urlParts.hostname,
							 | 
						||
| 
								 | 
							
								      protocol = urlParts.protocol,
							 | 
						||
| 
								 | 
							
								      port = urlParts.port;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!port || port === '0') {
							 | 
						||
| 
								 | 
							
								    port = loc.port;
							 | 
						||
| 
								 | 
							
								  } // 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 === '::') && loc.hostname && loc.protocol.indexOf('http') === 0) {
							 | 
						||
| 
								 | 
							
								    hostname = loc.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 && hostname !== '127.0.0.1' && (loc.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) {
							 | 
						||
| 
								 | 
							
								    protocol = loc.protocol;
							 | 
						||
| 
								 | 
							
								  } // 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var sockHost = query.sockHost || hostname;
							 | 
						||
| 
								 | 
							
								  var sockPath = query.sockPath || '/sockjs-node';
							 | 
						||
| 
								 | 
							
								  var sockPort = query.sockPort || port;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (sockPort === 'location') {
							 | 
						||
| 
								 | 
							
								    sockPort = loc.port;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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;
							 |