@@ -52,8 +52,8 @@ class WebSocketChannel {
52
52
return ;
53
53
}
54
54
}
55
- this . _url = scheme + '://' + config . url . hostAndPort ;
56
- this . _ws = new WebSocket ( this . _url ) ;
55
+
56
+ this . _ws = createWebSocket ( scheme , config . url ) ;
57
57
this . _ws . binaryType = "arraybuffer" ;
58
58
59
59
let self = this ;
@@ -169,4 +169,55 @@ class WebSocketChannel {
169
169
let available = typeof WebSocket !== 'undefined' ;
170
170
let _websocketChannelModule = { channel : WebSocketChannel , available : available } ;
171
171
172
+ function createWebSocket ( scheme , parsedUrl ) {
173
+ const url = scheme + '://' + parsedUrl . hostAndPort ;
174
+
175
+ try {
176
+ return new WebSocket ( url ) ;
177
+ } catch ( error ) {
178
+ if ( isIPv6AddressIssueOnWindows ( error , parsedUrl ) ) {
179
+
180
+ // WebSocket in IE and Edge browsers on Windows do not support regular IPv6 address syntax because they contain ':'.
181
+ // It's an invalid character for UNC (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_UNC_path_names)
182
+ // and Windows requires IPv6 to be changes in the following way:
183
+ // 1) replace all ':' with '-'
184
+ // 2) replace '%' with 's' for link-local address
185
+ // 3) append '.ipv6-literal.net' suffix
186
+ // only then resulting string can be considered a valid IPv6 address. Yes, this is extremely weird!
187
+ // For more details see:
188
+ // https://social.msdn.microsoft.com/Forums/ie/en-US/06cca73b-63c2-4bf9-899b-b229c50449ff/whether-ie10-websocket-support-ipv6?forum=iewebdevelopment
189
+ // https://www.itdojo.com/ipv6-addresses-and-unc-path-names-overcoming-illegal/
190
+ // Creation of WebSocket with unconverted address results in SyntaxError without message or stacktrace.
191
+ // That is why here we "catch" SyntaxError and rewrite IPv6 address if needed.
192
+
193
+ const windowsFriendlyUrl = asWindowsFriendlyIPv6Address ( scheme , parsedUrl ) ;
194
+ return new WebSocket ( windowsFriendlyUrl ) ;
195
+ } else {
196
+ throw error ;
197
+ }
198
+ }
199
+ }
200
+
201
+ function isIPv6AddressIssueOnWindows ( error , parsedUrl ) {
202
+ return error . name === 'SyntaxError' && isIPv6Address ( parsedUrl ) ;
203
+ }
204
+
205
+ function isIPv6Address ( parsedUrl ) {
206
+ const hostAndPort = parsedUrl . hostAndPort ;
207
+ return hostAndPort . charAt ( 0 ) === '[' && hostAndPort . indexOf ( ']' ) !== - 1 ;
208
+ }
209
+
210
+ function asWindowsFriendlyIPv6Address ( scheme , parsedUrl ) {
211
+ // replace all ':' with '-'
212
+ const hostWithoutColons = parsedUrl . host . replace ( new RegExp ( ':' , 'g' ) , '-' ) ;
213
+
214
+ // replace '%' with 's' for link-local IPv6 address like 'fe80::1%lo0'
215
+ const hostWithoutPercent = hostWithoutColons . replace ( '%' , 's' ) ;
216
+
217
+ // append magic '.ipv6-literal.net' suffix
218
+ const ipv6Host = hostWithoutPercent + '.ipv6-literal.net' ;
219
+
220
+ return `${ scheme } ://${ ipv6Host } :${ parsedUrl . port } ` ;
221
+ }
222
+
172
223
export default _websocketChannelModule
0 commit comments