quickblox 2.17.2-logger → 2.17.4-logger

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/package.json +1 -2
  2. package/quickblox.js +36571 -38627
  3. package/quickblox.min.js +1 -1
  4. package/src/libs/strophe/strophe.common.js +6668 -0
  5. package/src/libs/strophe/strophe.esm.js +6660 -0
  6. package/src/libs/strophe/strophe.umd.js +6873 -0
  7. package/src/libs/strophe/strophe.umd.min.js +1 -0
  8. package/src/modules/chat/qbChat.js +9 -0
  9. package/src/modules/webrtc/qbWebRTCSignalingProcessor.js +2 -1
  10. package/src/modules/webrtc/qbWebRTCSignalingProvider.js +2 -2
  11. package/src/qbConfig.js +1 -1
  12. package/src/qbStrophe.js +2 -1
  13. package/strophejs-1.4.0/.eslintrc.json +264 -0
  14. package/strophejs-1.4.0/.gitattributes +1 -0
  15. package/strophejs-1.4.0/CHANGELOG.md +250 -0
  16. package/strophejs-1.4.0/LICENSE.txt +19 -0
  17. package/strophejs-1.4.0/Makefile +92 -0
  18. package/strophejs-1.4.0/README.md +45 -0
  19. package/strophejs-1.4.0/RELEASE_CHECKLIST.md +16 -0
  20. package/strophejs-1.4.0/contrib/discojs/README.txt +42 -0
  21. package/strophejs-1.4.0/contrib/discojs/css/disco.css +16 -0
  22. package/strophejs-1.4.0/contrib/discojs/index.html +47 -0
  23. package/strophejs-1.4.0/contrib/discojs/punjab.tac +18 -0
  24. package/strophejs-1.4.0/contrib/discojs/scripts/basic.js +102 -0
  25. package/strophejs-1.4.0/contrib/discojs/scripts/disco.js +60 -0
  26. package/strophejs-1.4.0/docs.css +797 -0
  27. package/strophejs-1.4.0/examples/amd.html +21 -0
  28. package/strophejs-1.4.0/examples/attach/README +37 -0
  29. package/strophejs-1.4.0/examples/attach/__init__.py +0 -0
  30. package/strophejs-1.4.0/examples/attach/attacher/__init__.py +0 -0
  31. package/strophejs-1.4.0/examples/attach/attacher/views.py +18 -0
  32. package/strophejs-1.4.0/examples/attach/boshclient.py +158 -0
  33. package/strophejs-1.4.0/examples/attach/manage.py +11 -0
  34. package/strophejs-1.4.0/examples/attach/settings.py +85 -0
  35. package/strophejs-1.4.0/examples/attach/templates/attacher/index.html +88 -0
  36. package/strophejs-1.4.0/examples/attach/urls.py +19 -0
  37. package/strophejs-1.4.0/examples/basic.html +23 -0
  38. package/strophejs-1.4.0/examples/basic.js +73 -0
  39. package/strophejs-1.4.0/examples/echobot.html +25 -0
  40. package/strophejs-1.4.0/examples/echobot.js +79 -0
  41. package/strophejs-1.4.0/examples/main.js +59 -0
  42. package/strophejs-1.4.0/examples/prebind.html +39 -0
  43. package/strophejs-1.4.0/examples/prebind.js +103 -0
  44. package/strophejs-1.4.0/examples/restore.html +24 -0
  45. package/strophejs-1.4.0/examples/restore.js +71 -0
  46. package/strophejs-1.4.0/package-lock.json +8634 -0
  47. package/strophejs-1.4.0/package.json +84 -0
  48. package/strophejs-1.4.0/rollup.config.js +76 -0
  49. package/strophejs-1.4.0/src/bosh.js +916 -0
  50. package/strophejs-1.4.0/src/core.js +3535 -0
  51. package/strophejs-1.4.0/src/md5.js +204 -0
  52. package/strophejs-1.4.0/src/sha1.js +172 -0
  53. package/strophejs-1.4.0/src/shared-connection-worker.js +114 -0
  54. package/strophejs-1.4.0/src/shims.js +123 -0
  55. package/strophejs-1.4.0/src/strophe.js +14 -0
  56. package/strophejs-1.4.0/src/utils.js +63 -0
  57. package/strophejs-1.4.0/src/websocket.js +561 -0
  58. package/strophejs-1.4.0/src/worker-websocket.js +152 -0
  59. package/strophejs-1.4.0/tests/index.html +21 -0
  60. package/strophejs-1.4.0/tests/main.js +49 -0
  61. package/strophejs-1.4.0/tests/tests.js +929 -0
  62. package/strophejs-1.6.1/.eslintrc.json +264 -0
  63. package/strophejs-1.6.1/.gitattributes +1 -0
  64. package/strophejs-1.6.1/.nvmrc +1 -0
  65. package/strophejs-1.6.1/CHANGELOG.md +288 -0
  66. package/strophejs-1.6.1/LICENSE.txt +19 -0
  67. package/strophejs-1.6.1/Makefile +92 -0
  68. package/strophejs-1.6.1/README.md +46 -0
  69. package/strophejs-1.6.1/RELEASE_CHECKLIST.md +18 -0
  70. package/strophejs-1.6.1/babel.config.json +10 -0
  71. package/strophejs-1.6.1/contrib/discojs/README.txt +42 -0
  72. package/strophejs-1.6.1/contrib/discojs/css/disco.css +16 -0
  73. package/strophejs-1.6.1/contrib/discojs/index.html +47 -0
  74. package/strophejs-1.6.1/contrib/discojs/punjab.tac +18 -0
  75. package/strophejs-1.6.1/contrib/discojs/scripts/basic.js +102 -0
  76. package/strophejs-1.6.1/contrib/discojs/scripts/disco.js +60 -0
  77. package/strophejs-1.6.1/docs.css +797 -0
  78. package/strophejs-1.6.1/examples/amd.html +21 -0
  79. package/strophejs-1.6.1/examples/attach/README +37 -0
  80. package/strophejs-1.6.1/examples/attach/__init__.py +0 -0
  81. package/strophejs-1.6.1/examples/attach/attacher/__init__.py +0 -0
  82. package/strophejs-1.6.1/examples/attach/attacher/views.py +18 -0
  83. package/strophejs-1.6.1/examples/attach/boshclient.py +158 -0
  84. package/strophejs-1.6.1/examples/attach/manage.py +11 -0
  85. package/strophejs-1.6.1/examples/attach/settings.py +85 -0
  86. package/strophejs-1.6.1/examples/attach/templates/attacher/index.html +88 -0
  87. package/strophejs-1.6.1/examples/attach/urls.py +19 -0
  88. package/strophejs-1.6.1/examples/basic.html +23 -0
  89. package/strophejs-1.6.1/examples/basic.js +73 -0
  90. package/strophejs-1.6.1/examples/echobot.html +25 -0
  91. package/strophejs-1.6.1/examples/echobot.js +79 -0
  92. package/strophejs-1.6.1/examples/main.js +59 -0
  93. package/strophejs-1.6.1/examples/prebind.html +39 -0
  94. package/strophejs-1.6.1/examples/prebind.js +103 -0
  95. package/strophejs-1.6.1/examples/restore.html +24 -0
  96. package/strophejs-1.6.1/examples/restore.js +71 -0
  97. package/strophejs-1.6.1/package-lock.json +18461 -0
  98. package/strophejs-1.6.1/package.json +87 -0
  99. package/strophejs-1.6.1/rollup.config.js +70 -0
  100. package/strophejs-1.6.1/src/bosh.js +916 -0
  101. package/strophejs-1.6.1/src/builder.js +239 -0
  102. package/strophejs-1.6.1/src/constants.js +155 -0
  103. package/strophejs-1.6.1/src/core.js +2377 -0
  104. package/strophejs-1.6.1/src/sasl-anon.js +17 -0
  105. package/strophejs-1.6.1/src/sasl-external.js +27 -0
  106. package/strophejs-1.6.1/src/sasl-oauthbearer.js +30 -0
  107. package/strophejs-1.6.1/src/sasl-plain.js +32 -0
  108. package/strophejs-1.6.1/src/sasl-sha1.js +24 -0
  109. package/strophejs-1.6.1/src/sasl-sha256.js +24 -0
  110. package/strophejs-1.6.1/src/sasl-sha384.js +24 -0
  111. package/strophejs-1.6.1/src/sasl-sha512.js +24 -0
  112. package/strophejs-1.6.1/src/sasl-xoauth2.js +27 -0
  113. package/strophejs-1.6.1/src/sasl.js +143 -0
  114. package/strophejs-1.6.1/src/scram.js +182 -0
  115. package/strophejs-1.6.1/src/shared-connection-worker.js +114 -0
  116. package/strophejs-1.6.1/src/shims.js +122 -0
  117. package/strophejs-1.6.1/src/strophe.js +15 -0
  118. package/strophejs-1.6.1/src/utils.js +626 -0
  119. package/strophejs-1.6.1/src/websocket.js +556 -0
  120. package/strophejs-1.6.1/src/worker-websocket.js +149 -0
  121. package/strophejs-1.6.1/tests.js +993 -0
@@ -0,0 +1,916 @@
1
+ /*
2
+ This program is distributed under the terms of the MIT license.
3
+ Please see the LICENSE file for details.
4
+
5
+ Copyright 2006-2008, OGG, LLC
6
+ */
7
+
8
+ /* global ActiveXObject */
9
+
10
+ import { DOMParser } from './shims'
11
+ import { $build, Strophe } from './core';
12
+
13
+
14
+ /** PrivateClass: Strophe.Request
15
+ * _Private_ helper class that provides a cross implementation abstraction
16
+ * for a BOSH related XMLHttpRequest.
17
+ *
18
+ * The Strophe.Request class is used internally to encapsulate BOSH request
19
+ * information. It is not meant to be used from user's code.
20
+ */
21
+ Strophe.Request = class Request {
22
+
23
+ /** PrivateConstructor: Strophe.Request
24
+ * Create and initialize a new Strophe.Request object.
25
+ *
26
+ * Parameters:
27
+ * (XMLElement) elem - The XML data to be sent in the request.
28
+ * (Function) func - The function that will be called when the
29
+ * XMLHttpRequest readyState changes.
30
+ * (Integer) rid - The BOSH rid attribute associated with this request.
31
+ * (Integer) sends - The number of times this same request has been sent.
32
+ */
33
+ constructor (elem, func, rid, sends) {
34
+ this.id = ++Strophe._requestId;
35
+ this.xmlData = elem;
36
+ this.data = Strophe.serialize(elem);
37
+ // save original function in case we need to make a new request
38
+ // from this one.
39
+ this.origFunc = func;
40
+ this.func = func;
41
+ this.rid = rid;
42
+ this.date = NaN;
43
+ this.sends = sends || 0;
44
+ this.abort = false;
45
+ this.dead = null;
46
+
47
+ this.age = function () {
48
+ if (!this.date) { return 0; }
49
+ const now = new Date();
50
+ return (now - this.date) / 1000;
51
+ };
52
+ this.timeDead = function () {
53
+ if (!this.dead) { return 0; }
54
+ const now = new Date();
55
+ return (now - this.dead) / 1000;
56
+ };
57
+ this.xhr = this._newXHR();
58
+ }
59
+
60
+ /** PrivateFunction: getResponse
61
+ * Get a response from the underlying XMLHttpRequest.
62
+ *
63
+ * This function attempts to get a response from the request and checks
64
+ * for errors.
65
+ *
66
+ * Throws:
67
+ * "parsererror" - A parser error occured.
68
+ * "bad-format" - The entity has sent XML that cannot be processed.
69
+ *
70
+ * Returns:
71
+ * The DOM element tree of the response.
72
+ */
73
+ getResponse () {
74
+ let node = null;
75
+ if (this.xhr.responseXML && this.xhr.responseXML.documentElement) {
76
+ node = this.xhr.responseXML.documentElement;
77
+ if (node.tagName === "parsererror") {
78
+ Strophe.error("invalid response received");
79
+ Strophe.error("responseText: " + this.xhr.responseText);
80
+ Strophe.error("responseXML: " +
81
+ Strophe.serialize(this.xhr.responseXML));
82
+ throw new Error("parsererror");
83
+ }
84
+ } else if (this.xhr.responseText) {
85
+ // In React Native, we may get responseText but no responseXML. We can try to parse it manually.
86
+ Strophe.debug("Got responseText but no responseXML; attempting to parse it with DOMParser...");
87
+ node = new DOMParser().parseFromString(this.xhr.responseText, 'application/xml').documentElement;
88
+ if (!node) {
89
+ throw new Error('Parsing produced null node');
90
+ } else if (node.querySelector('parsererror')) {
91
+ Strophe.error("invalid response received: " + node.querySelector('parsererror').textContent);
92
+ Strophe.error("responseText: " + this.xhr.responseText);
93
+ const error = new Error();
94
+ error.name = Strophe.ErrorCondition.BAD_FORMAT;
95
+ throw error;
96
+ }
97
+ }
98
+ return node;
99
+ }
100
+
101
+ /** PrivateFunction: _newXHR
102
+ * _Private_ helper function to create XMLHttpRequests.
103
+ *
104
+ * This function creates XMLHttpRequests across all implementations.
105
+ *
106
+ * Returns:
107
+ * A new XMLHttpRequest.
108
+ */
109
+ _newXHR () {
110
+ let xhr = null;
111
+ if (window.XMLHttpRequest) {
112
+ xhr = new XMLHttpRequest();
113
+ if (xhr.overrideMimeType) {
114
+ xhr.overrideMimeType("text/xml; charset=utf-8");
115
+ }
116
+ } else if (window.ActiveXObject) {
117
+ xhr = new ActiveXObject("Microsoft.XMLHTTP");
118
+ }
119
+ // use Function.bind() to prepend ourselves as an argument
120
+ xhr.onreadystatechange = this.func.bind(null, this);
121
+ return xhr;
122
+ }
123
+ };
124
+
125
+ /** Class: Strophe.Bosh
126
+ * _Private_ helper class that handles BOSH Connections
127
+ *
128
+ * The Strophe.Bosh class is used internally by Strophe.Connection
129
+ * to encapsulate BOSH sessions. It is not meant to be used from user's code.
130
+ */
131
+
132
+ /** File: bosh.js
133
+ * A JavaScript library to enable BOSH in Strophejs.
134
+ *
135
+ * this library uses Bidirectional-streams Over Synchronous HTTP (BOSH)
136
+ * to emulate a persistent, stateful, two-way connection to an XMPP server.
137
+ * More information on BOSH can be found in XEP 124.
138
+ */
139
+
140
+ /** PrivateConstructor: Strophe.Bosh
141
+ * Create and initialize a Strophe.Bosh object.
142
+ *
143
+ * Parameters:
144
+ * (Strophe.Connection) connection - The Strophe.Connection that will use BOSH.
145
+ *
146
+ * Returns:
147
+ * A new Strophe.Bosh object.
148
+ */
149
+ Strophe.Bosh = class Bosh {
150
+
151
+ constructor (connection) {
152
+ this._conn = connection;
153
+ /* request id for body tags */
154
+ this.rid = Math.floor(Math.random() * 4294967295);
155
+ /* The current session ID. */
156
+ this.sid = null;
157
+
158
+ // default BOSH values
159
+ this.hold = 1;
160
+ this.wait = 60;
161
+ this.window = 5;
162
+ this.errors = 0;
163
+ this.inactivity = null;
164
+
165
+ this.lastResponseHeaders = null;
166
+ this._requests = [];
167
+ }
168
+
169
+ /** PrivateFunction: _buildBody
170
+ * _Private_ helper function to generate the <body/> wrapper for BOSH.
171
+ *
172
+ * Returns:
173
+ * A Strophe.Builder with a <body/> element.
174
+ */
175
+ _buildBody () {
176
+ const bodyWrap = $build('body', {
177
+ 'rid': this.rid++,
178
+ 'xmlns': Strophe.NS.HTTPBIND
179
+ });
180
+ if (this.sid !== null) {
181
+ bodyWrap.attrs({'sid': this.sid});
182
+ }
183
+ if (this._conn.options.keepalive && this._conn._sessionCachingSupported()) {
184
+ this._cacheSession();
185
+ }
186
+ return bodyWrap;
187
+ }
188
+
189
+ /** PrivateFunction: _reset
190
+ * Reset the connection.
191
+ *
192
+ * This function is called by the reset function of the Strophe Connection
193
+ */
194
+ _reset () {
195
+ this.rid = Math.floor(Math.random() * 4294967295);
196
+ this.sid = null;
197
+ this.errors = 0;
198
+ if (this._conn._sessionCachingSupported()) {
199
+ window.sessionStorage.removeItem('strophe-bosh-session');
200
+ }
201
+
202
+ this._conn.nextValidRid(this.rid);
203
+ }
204
+
205
+ /** PrivateFunction: _connect
206
+ * _Private_ function that initializes the BOSH connection.
207
+ *
208
+ * Creates and sends the Request that initializes the BOSH connection.
209
+ */
210
+ _connect (wait, hold, route) {
211
+ this.wait = wait || this.wait;
212
+ this.hold = hold || this.hold;
213
+ this.errors = 0;
214
+
215
+ const body = this._buildBody().attrs({
216
+ "to": this._conn.domain,
217
+ "xml:lang": "en",
218
+ "wait": this.wait,
219
+ "hold": this.hold,
220
+ "content": "text/xml; charset=utf-8",
221
+ "ver": "1.6",
222
+ "xmpp:version": "1.0",
223
+ "xmlns:xmpp": Strophe.NS.BOSH
224
+ });
225
+ if (route){
226
+ body.attrs({'route': route});
227
+ }
228
+
229
+ const _connect_cb = this._conn._connect_cb;
230
+ this._requests.push(
231
+ new Strophe.Request(
232
+ body.tree(),
233
+ this._onRequestStateChange.bind(this, _connect_cb.bind(this._conn)),
234
+ body.tree().getAttribute("rid")
235
+ )
236
+ );
237
+ this._throttledRequestHandler();
238
+ this._conn.clientLogger('_connect method was called with BOSH protocol');
239
+ }
240
+
241
+ /** PrivateFunction: _attach
242
+ * Attach to an already created and authenticated BOSH session.
243
+ *
244
+ * This function is provided to allow Strophe to attach to BOSH
245
+ * sessions which have been created externally, perhaps by a Web
246
+ * application. This is often used to support auto-login type features
247
+ * without putting user credentials into the page.
248
+ *
249
+ * Parameters:
250
+ * (String) jid - The full JID that is bound by the session.
251
+ * (String) sid - The SID of the BOSH session.
252
+ * (String) rid - The current RID of the BOSH session. This RID
253
+ * will be used by the next request.
254
+ * (Function) callback The connect callback function.
255
+ * (Integer) wait - The optional HTTPBIND wait value. This is the
256
+ * time the server will wait before returning an empty result for
257
+ * a request. The default setting of 60 seconds is recommended.
258
+ * Other settings will require tweaks to the Strophe.TIMEOUT value.
259
+ * (Integer) hold - The optional HTTPBIND hold value. This is the
260
+ * number of connections the server will hold at one time. This
261
+ * should almost always be set to 1 (the default).
262
+ * (Integer) wind - The optional HTTBIND window value. This is the
263
+ * allowed range of request ids that are valid. The default is 5.
264
+ */
265
+ _attach (jid, sid, rid, callback, wait, hold, wind) {
266
+ this._conn.jid = jid;
267
+ this.sid = sid;
268
+ this.rid = rid;
269
+
270
+ this._conn.connect_callback = callback;
271
+ this._conn.domain = Strophe.getDomainFromJid(this._conn.jid);
272
+ this._conn.authenticated = true;
273
+ this._conn.connected = true;
274
+
275
+ this.wait = wait || this.wait;
276
+ this.hold = hold || this.hold;
277
+ this.window = wind || this.window;
278
+
279
+ this._conn._changeConnectStatus(Strophe.Status.ATTACHED, null);
280
+ }
281
+
282
+ /** PrivateFunction: _restore
283
+ * Attempt to restore a cached BOSH session
284
+ *
285
+ * Parameters:
286
+ * (String) jid - The full JID that is bound by the session.
287
+ * This parameter is optional but recommended, specifically in cases
288
+ * where prebinded BOSH sessions are used where it's important to know
289
+ * that the right session is being restored.
290
+ * (Function) callback The connect callback function.
291
+ * (Integer) wait - The optional HTTPBIND wait value. This is the
292
+ * time the server will wait before returning an empty result for
293
+ * a request. The default setting of 60 seconds is recommended.
294
+ * Other settings will require tweaks to the Strophe.TIMEOUT value.
295
+ * (Integer) hold - The optional HTTPBIND hold value. This is the
296
+ * number of connections the server will hold at one time. This
297
+ * should almost always be set to 1 (the default).
298
+ * (Integer) wind - The optional HTTBIND window value. This is the
299
+ * allowed range of request ids that are valid. The default is 5.
300
+ */
301
+ _restore (jid, callback, wait, hold, wind) {
302
+ const session = JSON.parse(window.sessionStorage.getItem('strophe-bosh-session'));
303
+ if (typeof session !== "undefined" &&
304
+ session !== null &&
305
+ session.rid &&
306
+ session.sid &&
307
+ session.jid &&
308
+ ( typeof jid === "undefined" ||
309
+ jid === null ||
310
+ Strophe.getBareJidFromJid(session.jid) === Strophe.getBareJidFromJid(jid) ||
311
+ // If authcid is null, then it's an anonymous login, so
312
+ // we compare only the domains:
313
+ ((Strophe.getNodeFromJid(jid) === null) && (Strophe.getDomainFromJid(session.jid) === jid))
314
+ )
315
+ ) {
316
+ this._conn.restored = true;
317
+ this._attach(session.jid, session.sid, session.rid, callback, wait, hold, wind);
318
+ } else {
319
+ const error = new Error("_restore: no restoreable session.");
320
+ error.name = "StropheSessionError";
321
+ throw error;
322
+ }
323
+ }
324
+
325
+ /** PrivateFunction: _cacheSession
326
+ * _Private_ handler for the beforeunload event.
327
+ *
328
+ * This handler is used to process the Bosh-part of the initial request.
329
+ * Parameters:
330
+ * (Strophe.Request) bodyWrap - The received stanza.
331
+ */
332
+ _cacheSession () {
333
+ if (this._conn.authenticated) {
334
+ if (this._conn.jid && this.rid && this.sid) {
335
+ window.sessionStorage.setItem('strophe-bosh-session', JSON.stringify({
336
+ 'jid': this._conn.jid,
337
+ 'rid': this.rid,
338
+ 'sid': this.sid
339
+ }));
340
+ }
341
+ } else {
342
+ window.sessionStorage.removeItem('strophe-bosh-session');
343
+ }
344
+ }
345
+
346
+ /** PrivateFunction: _connect_cb
347
+ * _Private_ handler for initial connection request.
348
+ *
349
+ * This handler is used to process the Bosh-part of the initial request.
350
+ * Parameters:
351
+ * (Strophe.Request) bodyWrap - The received stanza.
352
+ */
353
+ _connect_cb (bodyWrap) {
354
+ const typ = bodyWrap.getAttribute("type");
355
+ if (typ !== null && typ === "terminate") {
356
+ // an error occurred
357
+ let cond = bodyWrap.getAttribute("condition");
358
+ Strophe.error("BOSH-Connection failed: " + cond);
359
+ const conflict = bodyWrap.getElementsByTagName("conflict");
360
+ if (cond !== null) {
361
+ if (cond === "remote-stream-error" && conflict.length > 0) {
362
+ cond = "conflict";
363
+ }
364
+ this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, cond);
365
+ } else {
366
+ this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "unknown");
367
+ }
368
+ this._conn._doDisconnect(cond);
369
+ return Strophe.Status.CONNFAIL;
370
+ }
371
+
372
+ // check to make sure we don't overwrite these if _connect_cb is
373
+ // called multiple times in the case of missing stream:features
374
+ if (!this.sid) {
375
+ this.sid = bodyWrap.getAttribute("sid");
376
+ }
377
+ const wind = bodyWrap.getAttribute('requests');
378
+ if (wind) { this.window = parseInt(wind, 10); }
379
+ const hold = bodyWrap.getAttribute('hold');
380
+ if (hold) { this.hold = parseInt(hold, 10); }
381
+ const wait = bodyWrap.getAttribute('wait');
382
+ if (wait) { this.wait = parseInt(wait, 10); }
383
+ const inactivity = bodyWrap.getAttribute('inactivity');
384
+ if (inactivity) { this.inactivity = parseInt(inactivity, 10); }
385
+ }
386
+
387
+ /** PrivateFunction: _disconnect
388
+ * _Private_ part of Connection.disconnect for Bosh
389
+ *
390
+ * Parameters:
391
+ * (Request) pres - This stanza will be sent before disconnecting.
392
+ */
393
+ _disconnect (pres) {
394
+ this._sendTerminate(pres);
395
+ }
396
+
397
+ /** PrivateFunction: _doDisconnect
398
+ * _Private_ function to disconnect.
399
+ *
400
+ * Resets the SID and RID.
401
+ */
402
+ _doDisconnect () {
403
+ this.sid = null;
404
+ this.rid = Math.floor(Math.random() * 4294967295);
405
+ if (this._conn._sessionCachingSupported()) {
406
+ window.sessionStorage.removeItem('strophe-bosh-session');
407
+ }
408
+
409
+ this._conn.nextValidRid(this.rid);
410
+ }
411
+
412
+ /** PrivateFunction: _emptyQueue
413
+ * _Private_ function to check if the Request queue is empty.
414
+ *
415
+ * Returns:
416
+ * True, if there are no Requests queued, False otherwise.
417
+ */
418
+ _emptyQueue () {
419
+ return this._requests.length === 0;
420
+ }
421
+
422
+ /** PrivateFunction: _callProtocolErrorHandlers
423
+ * _Private_ function to call error handlers registered for HTTP errors.
424
+ *
425
+ * Parameters:
426
+ * (Strophe.Request) req - The request that is changing readyState.
427
+ */
428
+ _callProtocolErrorHandlers (req) {
429
+ const reqStatus = Bosh._getRequestStatus(req);
430
+ const err_callback = this._conn.protocolErrorHandlers.HTTP[reqStatus];
431
+ if (err_callback) {
432
+ err_callback.call(this, reqStatus);
433
+ }
434
+ }
435
+
436
+ /** PrivateFunction: _hitError
437
+ * _Private_ function to handle the error count.
438
+ *
439
+ * Requests are resent automatically until their error count reaches
440
+ * 5. Each time an error is encountered, this function is called to
441
+ * increment the count and disconnect if the count is too high.
442
+ *
443
+ * Parameters:
444
+ * (Integer) reqStatus - The request status.
445
+ */
446
+ _hitError (reqStatus) {
447
+ this.errors++;
448
+ Strophe.warn("request errored, status: " + reqStatus +
449
+ ", number of errors: " + this.errors);
450
+ if (this.errors > 4) {
451
+ this._conn._onDisconnectTimeout();
452
+ }
453
+ }
454
+
455
+ /** PrivateFunction: _no_auth_received
456
+ *
457
+ * Called on stream start/restart when no stream:features
458
+ * has been received and sends a blank poll request.
459
+ */
460
+ _no_auth_received (callback) {
461
+ Strophe.warn("Server did not yet offer a supported authentication "+
462
+ "mechanism. Sending a blank poll request.");
463
+ if (callback) {
464
+ callback = callback.bind(this._conn);
465
+ } else {
466
+ callback = this._conn._connect_cb.bind(this._conn);
467
+ }
468
+ const body = this._buildBody();
469
+ this._requests.push(
470
+ new Strophe.Request(
471
+ body.tree(),
472
+ this._onRequestStateChange.bind(this, callback),
473
+ body.tree().getAttribute("rid")
474
+ )
475
+ );
476
+ this._throttledRequestHandler();
477
+ }
478
+
479
+ /** PrivateFunction: _onDisconnectTimeout
480
+ * _Private_ timeout handler for handling non-graceful disconnection.
481
+ *
482
+ * Cancels all remaining Requests and clears the queue.
483
+ */
484
+ _onDisconnectTimeout () {
485
+ this._abortAllRequests();
486
+ }
487
+
488
+ /** PrivateFunction: _abortAllRequests
489
+ * _Private_ helper function that makes sure all pending requests are aborted.
490
+ */
491
+ _abortAllRequests () {
492
+ while (this._requests.length > 0) {
493
+ const req = this._requests.pop();
494
+ req.abort = true;
495
+ req.xhr.abort();
496
+ req.xhr.onreadystatechange = function () {};
497
+ }
498
+ }
499
+
500
+ /** PrivateFunction: _onIdle
501
+ * _Private_ handler called by Strophe.Connection._onIdle
502
+ *
503
+ * Sends all queued Requests or polls with empty Request if there are none.
504
+ */
505
+ _onIdle () {
506
+ const data = this._conn._data;
507
+ // if no requests are in progress, poll
508
+ if (this._conn.authenticated && this._requests.length === 0 &&
509
+ data.length === 0 && !this._conn.disconnecting) {
510
+ Strophe.debug("no requests during idle cycle, sending blank request");
511
+ data.push(null);
512
+ }
513
+
514
+ if (this._conn.paused) {
515
+ return;
516
+ }
517
+
518
+ if (this._requests.length < 2 && data.length > 0) {
519
+ const body = this._buildBody();
520
+ for (let i=0; i<data.length; i++) {
521
+ if (data[i] !== null) {
522
+ if (data[i] === "restart") {
523
+ body.attrs({
524
+ "to": this._conn.domain,
525
+ "xml:lang": "en",
526
+ "xmpp:restart": "true",
527
+ "xmlns:xmpp": Strophe.NS.BOSH
528
+ });
529
+ } else {
530
+ body.cnode(data[i]).up();
531
+ }
532
+ }
533
+ }
534
+ delete this._conn._data;
535
+ this._conn._data = [];
536
+ this._requests.push(
537
+ new Strophe.Request(
538
+ body.tree(),
539
+ this._onRequestStateChange.bind(this, this._conn._dataRecv.bind(this._conn)),
540
+ body.tree().getAttribute("rid")
541
+ )
542
+ );
543
+ this._throttledRequestHandler();
544
+ }
545
+
546
+ if (this._requests.length > 0) {
547
+ const time_elapsed = this._requests[0].age();
548
+ if (this._requests[0].dead !== null) {
549
+ if (this._requests[0].timeDead() >
550
+ Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait)) {
551
+ this._throttledRequestHandler();
552
+ }
553
+ }
554
+ if (time_elapsed > Math.floor(Strophe.TIMEOUT * this.wait)) {
555
+ Strophe.warn("Request " +
556
+ this._requests[0].id +
557
+ " timed out, over " + Math.floor(Strophe.TIMEOUT * this.wait) +
558
+ " seconds since last activity");
559
+ this._throttledRequestHandler();
560
+ }
561
+ }
562
+ }
563
+
564
+ /** PrivateFunction: _getRequestStatus
565
+ *
566
+ * Returns the HTTP status code from a Strophe.Request
567
+ *
568
+ * Parameters:
569
+ * (Strophe.Request) req - The Strophe.Request instance.
570
+ * (Integer) def - The default value that should be returned if no
571
+ * status value was found.
572
+ */
573
+ static _getRequestStatus (req, def) {
574
+ let reqStatus;
575
+ if (req.xhr.readyState === 4) {
576
+ try {
577
+ reqStatus = req.xhr.status;
578
+ } catch (e) {
579
+ // ignore errors from undefined status attribute. Works
580
+ // around a browser bug
581
+ Strophe.error(
582
+ "Caught an error while retrieving a request's status, " +
583
+ "reqStatus: " + reqStatus);
584
+ }
585
+ }
586
+ if (typeof(reqStatus) === "undefined") {
587
+ reqStatus = typeof def === 'number' ? def : 0;
588
+ }
589
+ return reqStatus;
590
+ }
591
+
592
+ /** PrivateFunction: _onRequestStateChange
593
+ * _Private_ handler for Strophe.Request state changes.
594
+ *
595
+ * This function is called when the XMLHttpRequest readyState changes.
596
+ * It contains a lot of error handling logic for the many ways that
597
+ * requests can fail, and calls the request callback when requests
598
+ * succeed.
599
+ *
600
+ * Parameters:
601
+ * (Function) func - The handler for the request.
602
+ * (Strophe.Request) req - The request that is changing readyState.
603
+ */
604
+ _onRequestStateChange (func, req) {
605
+ Strophe.debug("request id "+req.id+"."+req.sends+
606
+ " state changed to "+req.xhr.readyState);
607
+ if (req.abort) {
608
+ req.abort = false;
609
+ return;
610
+ }
611
+ if (req.xhr.readyState !== 4) {
612
+ // The request is not yet complete
613
+ return;
614
+ }
615
+ const reqStatus = Bosh._getRequestStatus(req);
616
+ this.lastResponseHeaders = req.xhr.getAllResponseHeaders();
617
+ if (this._conn.disconnecting && reqStatus >= 400) {
618
+ this._hitError(reqStatus);
619
+ this._callProtocolErrorHandlers(req);
620
+ return;
621
+ }
622
+
623
+ const valid_request = reqStatus > 0 && reqStatus < 500;
624
+ const too_many_retries = req.sends > this._conn.maxRetries;
625
+ if (valid_request || too_many_retries) {
626
+ // remove from internal queue
627
+ this._removeRequest(req);
628
+ Strophe.debug("request id "+req.id+" should now be removed");
629
+ }
630
+
631
+ if (reqStatus === 200) {
632
+ // request succeeded
633
+ const reqIs0 = (this._requests[0] === req);
634
+ const reqIs1 = (this._requests[1] === req);
635
+ // if request 1 finished, or request 0 finished and request
636
+ // 1 is over Strophe.SECONDARY_TIMEOUT seconds old, we need to
637
+ // restart the other - both will be in the first spot, as the
638
+ // completed request has been removed from the queue already
639
+ if (reqIs1 ||
640
+ (reqIs0 && this._requests.length > 0 &&
641
+ this._requests[0].age() > Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait))) {
642
+ this._restartRequest(0);
643
+ }
644
+ this._conn.nextValidRid(Number(req.rid) + 1);
645
+ Strophe.debug("request id "+req.id+"."+req.sends+" got 200");
646
+ func(req); // call handler
647
+ this.errors = 0;
648
+ } else if (reqStatus === 0 ||
649
+ (reqStatus >= 400 && reqStatus < 600) ||
650
+ reqStatus >= 12000) {
651
+ // request failed
652
+ Strophe.error("request id "+req.id+"."+req.sends+" error "+reqStatus+" happened");
653
+ this._hitError(reqStatus);
654
+ this._callProtocolErrorHandlers(req);
655
+ if (reqStatus >= 400 && reqStatus < 500) {
656
+ this._conn._changeConnectStatus(Strophe.Status.DISCONNECTING, null);
657
+ this._conn._doDisconnect();
658
+ }
659
+ } else {
660
+ Strophe.error("request id "+req.id+"."+req.sends+" error "+reqStatus+" happened");
661
+ }
662
+
663
+ if (!valid_request && !too_many_retries) {
664
+ this._throttledRequestHandler();
665
+ } else if (too_many_retries && !this._conn.connected) {
666
+ this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "giving-up");
667
+ }
668
+ }
669
+
670
+ /** PrivateFunction: _processRequest
671
+ * _Private_ function to process a request in the queue.
672
+ *
673
+ * This function takes requests off the queue and sends them and
674
+ * restarts dead requests.
675
+ *
676
+ * Parameters:
677
+ * (Integer) i - The index of the request in the queue.
678
+ */
679
+ _processRequest (i) {
680
+ let req = this._requests[i];
681
+ const reqStatus = Bosh._getRequestStatus(req, -1);
682
+
683
+ // make sure we limit the number of retries
684
+ if (req.sends > this._conn.maxRetries) {
685
+ this._conn._onDisconnectTimeout();
686
+ return;
687
+ }
688
+ const time_elapsed = req.age();
689
+ const primary_timeout = (!isNaN(time_elapsed) && time_elapsed > Math.floor(Strophe.TIMEOUT * this.wait));
690
+ const secondary_timeout = (req.dead !== null && req.timeDead() > Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait));
691
+ const server_error = (req.xhr.readyState === 4 && (reqStatus < 1 || reqStatus >= 500));
692
+
693
+ if (primary_timeout || secondary_timeout || server_error) {
694
+ if (secondary_timeout) {
695
+ Strophe.error(`Request ${this._requests[i].id} timed out (secondary), restarting`);
696
+ }
697
+ req.abort = true;
698
+ req.xhr.abort();
699
+ // setting to null fails on IE6, so set to empty function
700
+ req.xhr.onreadystatechange = function () {};
701
+ this._requests[i] = new Strophe.Request(req.xmlData, req.origFunc, req.rid, req.sends);
702
+ req = this._requests[i];
703
+ }
704
+
705
+ if (req.xhr.readyState === 0) {
706
+ Strophe.debug("request id "+req.id+"."+req.sends+" posting");
707
+
708
+ try {
709
+ const content_type = this._conn.options.contentType || "text/xml; charset=utf-8";
710
+ req.xhr.open("POST", this._conn.service, this._conn.options.sync ? false : true);
711
+ if (typeof req.xhr.setRequestHeader !== 'undefined') {
712
+ // IE9 doesn't have setRequestHeader
713
+ req.xhr.setRequestHeader("Content-Type", content_type);
714
+ }
715
+ if (this._conn.options.withCredentials) {
716
+ req.xhr.withCredentials = true;
717
+ }
718
+ } catch (e2) {
719
+ Strophe.error("XHR open failed: " + e2.toString());
720
+ if (!this._conn.connected) {
721
+ this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "bad-service");
722
+ }
723
+ this._conn.disconnect();
724
+ return;
725
+ }
726
+
727
+ // Fires the XHR request -- may be invoked immediately
728
+ // or on a gradually expanding retry window for reconnects
729
+ const sendFunc = () => {
730
+ req.date = new Date();
731
+ if (this._conn.options.customHeaders){
732
+ const headers = this._conn.options.customHeaders;
733
+ for (const header in headers) {
734
+ if (Object.prototype.hasOwnProperty.call(headers, header)) {
735
+ req.xhr.setRequestHeader(header, headers[header]);
736
+ }
737
+ }
738
+ }
739
+ req.xhr.send(req.data);
740
+ };
741
+
742
+ // Implement progressive backoff for reconnects --
743
+ // First retry (send === 1) should also be instantaneous
744
+ if (req.sends > 1) {
745
+ // Using a cube of the retry number creates a nicely
746
+ // expanding retry window
747
+ const backoff = Math.min(Math.floor(Strophe.TIMEOUT * this.wait),
748
+ Math.pow(req.sends, 3)) * 1000;
749
+ setTimeout(function() {
750
+ // XXX: setTimeout should be called only with function expressions (23974bc1)
751
+ sendFunc();
752
+ }, backoff);
753
+ } else {
754
+ sendFunc();
755
+ }
756
+
757
+ req.sends++;
758
+
759
+ if (this._conn.xmlOutput !== Strophe.Connection.prototype.xmlOutput) {
760
+ if (req.xmlData.nodeName === this.strip && req.xmlData.childNodes.length) {
761
+ this._conn.xmlOutput(req.xmlData.childNodes[0]);
762
+ } else {
763
+ this._conn.xmlOutput(req.xmlData);
764
+ }
765
+ }
766
+ if (this._conn.rawOutput !== Strophe.Connection.prototype.rawOutput) {
767
+ this._conn.rawOutput(req.data);
768
+ }
769
+ } else {
770
+ Strophe.debug("_processRequest: " +
771
+ (i === 0 ? "first" : "second") +
772
+ " request has readyState of " +
773
+ req.xhr.readyState);
774
+ }
775
+ }
776
+
777
+ /** PrivateFunction: _removeRequest
778
+ * _Private_ function to remove a request from the queue.
779
+ *
780
+ * Parameters:
781
+ * (Strophe.Request) req - The request to remove.
782
+ */
783
+ _removeRequest (req) {
784
+ Strophe.debug("removing request");
785
+ for (let i=this._requests.length - 1; i>=0; i--) {
786
+ if (req === this._requests[i]) {
787
+ this._requests.splice(i, 1);
788
+ }
789
+ }
790
+ // IE6 fails on setting to null, so set to empty function
791
+ req.xhr.onreadystatechange = function () {};
792
+ this._throttledRequestHandler();
793
+ }
794
+
795
+ /** PrivateFunction: _restartRequest
796
+ * _Private_ function to restart a request that is presumed dead.
797
+ *
798
+ * Parameters:
799
+ * (Integer) i - The index of the request in the queue.
800
+ */
801
+ _restartRequest (i) {
802
+ const req = this._requests[i];
803
+ if (req.dead === null) {
804
+ req.dead = new Date();
805
+ }
806
+ this._processRequest(i);
807
+ }
808
+
809
+ /** PrivateFunction: _reqToData
810
+ * _Private_ function to get a stanza out of a request.
811
+ *
812
+ * Tries to extract a stanza out of a Request Object.
813
+ * When this fails the current connection will be disconnected.
814
+ *
815
+ * Parameters:
816
+ * (Object) req - The Request.
817
+ *
818
+ * Returns:
819
+ * The stanza that was passed.
820
+ */
821
+ _reqToData (req) {
822
+ try {
823
+ return req.getResponse();
824
+ } catch (e) {
825
+ if (e.message !== "parsererror") { throw e; }
826
+ this._conn.disconnect("strophe-parsererror");
827
+ }
828
+ }
829
+
830
+ /** PrivateFunction: _sendTerminate
831
+ * _Private_ function to send initial disconnect sequence.
832
+ *
833
+ * This is the first step in a graceful disconnect. It sends
834
+ * the BOSH server a terminate body and includes an unavailable
835
+ * presence if authentication has completed.
836
+ */
837
+ _sendTerminate (pres) {
838
+ Strophe.debug("_sendTerminate was called");
839
+ const body = this._buildBody().attrs({type: "terminate"});
840
+ if (pres) {
841
+ body.cnode(pres.tree());
842
+ }
843
+ const req = new Strophe.Request(
844
+ body.tree(),
845
+ this._onRequestStateChange.bind(this, this._conn._dataRecv.bind(this._conn)),
846
+ body.tree().getAttribute("rid")
847
+ );
848
+ this._requests.push(req);
849
+ this._throttledRequestHandler();
850
+ }
851
+
852
+ /** PrivateFunction: _send
853
+ * _Private_ part of the Connection.send function for BOSH
854
+ *
855
+ * Just triggers the RequestHandler to send the messages that are in the queue
856
+ */
857
+ _send () {
858
+ clearTimeout(this._conn._idleTimeout);
859
+ this._throttledRequestHandler();
860
+ this._conn._idleTimeout = setTimeout(() => this._conn._onIdle(), 100);
861
+ }
862
+
863
+ /** PrivateFunction: _sendRestart
864
+ *
865
+ * Send an xmpp:restart stanza.
866
+ */
867
+ _sendRestart () {
868
+ this._throttledRequestHandler();
869
+ clearTimeout(this._conn._idleTimeout);
870
+ }
871
+
872
+ /** PrivateFunction: _throttledRequestHandler
873
+ * _Private_ function to throttle requests to the connection window.
874
+ *
875
+ * This function makes sure we don't send requests so fast that the
876
+ * request ids overflow the connection window in the case that one
877
+ * request died.
878
+ */
879
+ _throttledRequestHandler () {
880
+ if (!this._requests) {
881
+ Strophe.debug("_throttledRequestHandler called with " +
882
+ "undefined requests");
883
+ } else {
884
+ Strophe.debug("_throttledRequestHandler called with " +
885
+ this._requests.length + " requests");
886
+ }
887
+
888
+ if (!this._requests || this._requests.length === 0) {
889
+ return;
890
+ }
891
+
892
+ if (this._requests.length > 0) {
893
+ this._processRequest(0);
894
+ }
895
+
896
+ if (this._requests.length > 1 &&
897
+ Math.abs(this._requests[0].rid -
898
+ this._requests[1].rid) < this.window) {
899
+ this._processRequest(1);
900
+ }
901
+ }
902
+ };
903
+
904
+
905
+ /** Variable: strip
906
+ *
907
+ * BOSH-Connections will have all stanzas wrapped in a <body> tag when
908
+ * passed to <Strophe.Connection.xmlInput> or <Strophe.Connection.xmlOutput>.
909
+ * To strip this tag, User code can set <Strophe.Bosh.strip> to "body":
910
+ *
911
+ * > Strophe.Bosh.prototype.strip = "body";
912
+ *
913
+ * This will enable stripping of the body tag in both
914
+ * <Strophe.Connection.xmlInput> and <Strophe.Connection.xmlOutput>.
915
+ */
916
+ Strophe.Bosh.prototype.strip = null;