11const getCurrentScriptSource = require ( './getCurrentScriptSource.js' ) ;
2- const parseQuery = require ( './parseQuery.js' ) ;
32
43/**
54 * @typedef {Object } SocketUrlParts
@@ -13,10 +12,15 @@ const parseQuery = require('./parseQuery.js');
1312/**
1413 * Parse current location and Webpack's `__resourceQuery` into parts that can create a valid socket URL.
1514 * @param {string } [resourceQuery] The Webpack `__resourceQuery` string.
15+ * @param {import('./getWDSMetadata').WDSMetaObj } [metadata] The parsed WDS metadata object.
1616 * @returns {SocketUrlParts } The parsed URL parts.
1717 * @see https://webpack.js.org/api/module-variables/#__resourcequery-webpack-specific
1818 */
19- function getSocketUrlParts ( resourceQuery ) {
19+ function getSocketUrlParts ( resourceQuery , metadata ) {
20+ if ( typeof metadata === 'undefined' ) {
21+ metadata = { } ;
22+ }
23+
2024 const scriptSource = getCurrentScriptSource ( ) ;
2125
2226 let url = { } ;
@@ -36,24 +40,52 @@ function getSocketUrlParts(resourceQuery) {
3640 let hostname = url . hostname ;
3741 /** @type {string | undefined } */
3842 let protocol = url . protocol ;
39- let pathname = '/sockjs-node' ; // This is hard-coded in WDS
4043 /** @type {string | undefined } */
4144 let port = url . port ;
4245
46+ // This is hard-coded in WDS v3
47+ let pathname = '/sockjs-node' ;
48+ if ( metadata . version === 4 ) {
49+ // This is hard-coded in WDS v4
50+ pathname = '/ws' ;
51+ }
52+
4353 // Parse authentication credentials in case we need them
4454 if ( url . username ) {
4555 // Since HTTP basic authentication does not allow empty username,
4656 // we only include password if the username is not empty.
47- // Result: <username>:<password>
48- auth = [ url . username , url . password ] . filter ( Boolean ) . join ( ':' ) ;
57+ // Result: <username> or <username>:<password>
58+ auth = url . username ;
59+ if ( url . password ) {
60+ auth += ':' + url . password ;
61+ }
4962 }
5063
51- // Check for IPv4 and IPv6 host addresses that corresponds to `any`/`empty`.
52- // This is important because `hostname` can be empty for some hosts,
53- // such as `about:blank` or `file://` URLs.
54- const isEmptyHostname = url . hostname === '0.0.0.0' || url . hostname === '[::]' || ! url . hostname ;
64+ // If the resource query is available,
65+ // parse it and overwrite everything we received from the script host.
66+ const parsedQuery = { } ;
67+ if ( resourceQuery ) {
68+ const searchParams = new URLSearchParams ( resourceQuery . slice ( 1 ) ) ;
69+ searchParams . forEach ( function ( value , key ) {
70+ parsedQuery [ key ] = value ;
71+ } ) ;
72+ }
5573
56- // We only re-assign the hostname if we are using HTTP/HTTPS protocols
74+ hostname = parsedQuery . sockHost || hostname ;
75+ pathname = parsedQuery . sockPath || pathname ;
76+ port = parsedQuery . sockPort || port ;
77+
78+ // Make sure the protocol from resource query has a trailing colon
79+ if ( parsedQuery . sockProtocol ) {
80+ protocol = parsedQuery . sockProtocol + ':' ;
81+ }
82+
83+ // Check for IPv4 and IPv6 host addresses that corresponds to any/empty.
84+ // This is important because `hostname` can be empty for some hosts,
85+ // such as 'about:blank' or 'file://' URLs.
86+ const isEmptyHostname = hostname === '0.0.0.0' || hostname === '[::]' || ! hostname ;
87+ // We only re-assign the hostname if it is empty,
88+ // and if we are using HTTP/HTTPS protocols.
5789 if (
5890 isEmptyHostname &&
5991 window . location . hostname &&
@@ -64,7 +96,7 @@ function getSocketUrlParts(resourceQuery) {
6496
6597 // We only re-assign `protocol` when `hostname` is available and is empty,
6698 // since otherwise we risk creating an invalid URL.
67- // We also do this when ` https` is used as it mandates the use of secure sockets.
99+ // We also do this when ' https' is used as it mandates the use of secure sockets.
68100 if ( hostname && ( isEmptyHostname || window . location . protocol === 'https:' ) ) {
69101 protocol = window . location . protocol ;
70102 }
@@ -74,18 +106,6 @@ function getSocketUrlParts(resourceQuery) {
74106 port = window . location . port ;
75107 }
76108
77- // If the resource query is available,
78- // parse it and overwrite everything we received from the script host.
79- const parsedQuery = parseQuery ( resourceQuery || '' ) ;
80- hostname = parsedQuery . sockHost || hostname ;
81- pathname = parsedQuery . sockPath || pathname ;
82- port = parsedQuery . sockPort || port ;
83-
84- // Make sure the protocol from resource query has a trailing colon
85- if ( parsedQuery . sockProtocol ) {
86- protocol = parsedQuery . sockProtocol + ':' ;
87- }
88-
89109 if ( ! hostname || ! pathname || ! port ) {
90110 throw new Error (
91111 [
0 commit comments