@microsoft/1ds-post-js 3.1.8 → 3.1.11
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.
- package/README.md +124 -5
- package/bundle/{ms.post-3.1.8.gbl.js → ms.post-3.1.11.gbl.js} +353 -172
- package/bundle/ms.post-3.1.11.gbl.js.map +1 -0
- package/bundle/ms.post-3.1.11.gbl.min.js +7 -0
- package/bundle/ms.post-3.1.11.gbl.min.js.map +1 -0
- package/bundle/ms.post-3.1.11.integrity.json +46 -0
- package/bundle/{ms.post-3.1.8.js → ms.post-3.1.11.js} +353 -172
- package/bundle/ms.post-3.1.11.js.map +1 -0
- package/bundle/ms.post-3.1.11.min.js +7 -0
- package/bundle/ms.post-3.1.11.min.js.map +1 -0
- package/bundle/ms.post.gbl.js +352 -171
- package/bundle/ms.post.gbl.js.map +1 -1
- package/bundle/ms.post.gbl.min.js +2 -2
- package/bundle/ms.post.gbl.min.js.map +1 -1
- package/bundle/ms.post.integrity.json +17 -17
- package/bundle/ms.post.js +352 -171
- package/bundle/ms.post.js.map +1 -1
- package/bundle/ms.post.min.js +2 -2
- package/bundle/ms.post.min.js.map +1 -1
- package/dist/ms.post.js +238 -116
- package/dist/ms.post.js.map +1 -1
- package/dist/ms.post.min.js +2 -2
- package/dist/ms.post.min.js.map +1 -1
- package/dist-esm/src/BatchNotificationActions.js +1 -1
- package/dist-esm/src/ClockSkewManager.js +1 -1
- package/dist-esm/src/Constants.d.ts +25 -0
- package/dist-esm/src/Constants.js +31 -0
- package/dist-esm/src/Constants.js.map +1 -0
- package/dist-esm/src/DataModels.d.ts +55 -0
- package/dist-esm/src/DataModels.js +1 -1
- package/dist-esm/src/EventBatch.d.ts +5 -2
- package/dist-esm/src/EventBatch.js +35 -15
- package/dist-esm/src/EventBatch.js.map +1 -1
- package/dist-esm/src/HttpManager.d.ts +2 -2
- package/dist-esm/src/HttpManager.js +172 -85
- package/dist-esm/src/HttpManager.js.map +1 -1
- package/dist-esm/src/Index.js +1 -1
- package/dist-esm/src/KillSwitch.js +1 -1
- package/dist-esm/src/PostChannel.js +55 -31
- package/dist-esm/src/PostChannel.js.map +1 -1
- package/dist-esm/src/RetryPolicy.js +1 -1
- package/dist-esm/src/Serializer.js +1 -1
- package/dist-esm/src/typings/XDomainRequest.js +1 -1
- package/package.json +3 -3
- package/src/Constants.ts +28 -0
- package/src/DataModels.ts +68 -0
- package/src/EventBatch.ts +47 -14
- package/src/HttpManager.ts +206 -84
- package/src/PostChannel.ts +60 -31
- package/bundle/ms.post-3.1.8.gbl.js.map +0 -1
- package/bundle/ms.post-3.1.8.gbl.min.js +0 -7
- package/bundle/ms.post-3.1.8.gbl.min.js.map +0 -1
- package/bundle/ms.post-3.1.8.integrity.json +0 -46
- package/bundle/ms.post-3.1.8.js.map +0 -1
- package/bundle/ms.post-3.1.8.min.js +0 -7
- package/bundle/ms.post-3.1.8.min.js.map +0 -1
package/src/HttpManager.ts
CHANGED
|
@@ -24,6 +24,16 @@ import EVTClockSkewManager from "./ClockSkewManager";
|
|
|
24
24
|
import dynamicProto from "@microsoft/dynamicproto-js";
|
|
25
25
|
import { IChannelConfiguration } from "./Index";
|
|
26
26
|
import { XDomainRequest as IXDomainRequest } from "./typings/XDomainRequest";
|
|
27
|
+
import {
|
|
28
|
+
defaultCacheControl, defaultContentType, DisabledPropertyName, Method, strApiKey, strAuthXToken, strCacheControl,
|
|
29
|
+
strClientId, strClientVersion, strContentTypeHeader, strDropped, strKillDurationHeader, strKillDurationSecondsHeader,
|
|
30
|
+
strKillTokensHeader, strMsaDeviceTicket, strMsfpc, strNoResponseBody, strOther, strRequeue, strResponseFail, strSending, strTimeDeltaHeader,
|
|
31
|
+
strTimeDeltaToApply, strUploadTime
|
|
32
|
+
} from "./Constants";
|
|
33
|
+
|
|
34
|
+
const strSendAttempt = "sendAttempt";
|
|
35
|
+
|
|
36
|
+
const _noResponseQs = "&" + strNoResponseBody + "=true";
|
|
27
37
|
|
|
28
38
|
// TypeScript removed this interface so we need to declare the global so we can check for it's existence.
|
|
29
39
|
declare var XDomainRequest: {
|
|
@@ -31,23 +41,11 @@ declare var XDomainRequest: {
|
|
|
31
41
|
new(): IXDomainRequest;
|
|
32
42
|
};
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const strRequeue = "requeue";
|
|
40
|
-
const strResponseFail = "rspFail";
|
|
41
|
-
const strOther = "oth";
|
|
42
|
-
|
|
43
|
-
const defaultCacheControl = "no-cache, no-store";
|
|
44
|
-
const defaultContentType = "application/x-json-stream";
|
|
45
|
-
const strCacheControl = "cache-control";
|
|
46
|
-
const strContentTypeHeader = "content-type";
|
|
47
|
-
const strKillTokensHeader = "kill-tokens";
|
|
48
|
-
const strKillDurationHeader = "kill-duration";
|
|
49
|
-
const strKillDurationSecondsHeader = "kill-duration-seconds";
|
|
50
|
-
const strTimeDeltaHeader = "time-delta-millis";
|
|
44
|
+
interface IRequestUrlDetails {
|
|
45
|
+
url: string,
|
|
46
|
+
hdrs: { [key: string]: string },
|
|
47
|
+
useHdrs: boolean
|
|
48
|
+
}
|
|
51
49
|
|
|
52
50
|
/**
|
|
53
51
|
* Identifies the default notification reason to the action names
|
|
@@ -60,6 +58,27 @@ const _eventActionMap: any = {
|
|
|
60
58
|
[EventBatchNotificationReason.SizeLimitExceeded]: strDropped
|
|
61
59
|
};
|
|
62
60
|
|
|
61
|
+
const _collectorQsHeaders = { };
|
|
62
|
+
const _collectorHeaderToQs = { };
|
|
63
|
+
|
|
64
|
+
function _addCollectorHeaderQsMapping(qsName: string, headerName: string) {
|
|
65
|
+
_collectorQsHeaders[qsName] = headerName;
|
|
66
|
+
_collectorHeaderToQs[headerName] = qsName;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_addCollectorHeaderQsMapping(strMsaDeviceTicket, strMsaDeviceTicket);
|
|
70
|
+
|
|
71
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
72
|
+
// Task 12886642: Need to wait until an updated version of the collector is released to return these as allowed in the OPTIONS call
|
|
73
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
74
|
+
//_addCollectorHeaderQsMapping(strClientVersion, strClientVersion);
|
|
75
|
+
//_addCollectorHeaderQsMapping(strClientId, "Client-Id");
|
|
76
|
+
//_addCollectorHeaderQsMapping(strApiKey, strApiKey);
|
|
77
|
+
//_addCollectorHeaderQsMapping(strTimeDeltaToApply, strTimeDeltaToApply);
|
|
78
|
+
//_addCollectorHeaderQsMapping(strUploadTime, strUploadTime);
|
|
79
|
+
//_addCollectorHeaderQsMapping(strAuthXToken, strAuthXToken);
|
|
80
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
81
|
+
|
|
63
82
|
type OnCompleteCallback = (status: number, headers: { [headerName: string]: string }, response?: string) => void;
|
|
64
83
|
|
|
65
84
|
function _getResponseText(xhr: XMLHttpRequest | IXDomainRequest) {
|
|
@@ -102,10 +121,21 @@ function _hasHeader(headers: any, header: string) {
|
|
|
102
121
|
return hasHeader;
|
|
103
122
|
}
|
|
104
123
|
|
|
124
|
+
function _addRequestDetails(details: IRequestUrlDetails, name: string, value: string, useHeaders: boolean) {
|
|
125
|
+
if (name && value && value.length > 0) {
|
|
126
|
+
if (useHeaders && _collectorQsHeaders[name]) {
|
|
127
|
+
details.hdrs[_collectorQsHeaders[name]] = value;
|
|
128
|
+
details.useHdrs = true;
|
|
129
|
+
} else {
|
|
130
|
+
details.url += "&" + name + "=" + value;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
105
135
|
/**
|
|
106
136
|
* Class managing the sending of requests.
|
|
107
137
|
*/
|
|
108
|
-
export
|
|
138
|
+
export class HttpManager {
|
|
109
139
|
public sendHook: PayloadPreprocessorFunction | undefined;
|
|
110
140
|
public sendListener: PayloadListenerFunction | undefined;
|
|
111
141
|
public _responseHandlers: Array<(responseText: string) => void> = [];
|
|
@@ -114,9 +144,8 @@ export default class HttpManager {
|
|
|
114
144
|
* @constructor
|
|
115
145
|
* @param requestQueue - The queue that contains the requests to be sent.
|
|
116
146
|
*/
|
|
117
|
-
constructor(maxEventsPerBatch: number, maxConnections: number,
|
|
118
|
-
let _urlString: string = "?cors=true&" + strContentTypeHeader.toLowerCase() + "=" + defaultContentType
|
|
119
|
-
+ FullVersionString;
|
|
147
|
+
constructor(maxEventsPerBatch: number, maxConnections: number, maxRequestRetriesBeforeBackoff: number, actions: BatchNotificationActions) {
|
|
148
|
+
let _urlString: string = "?cors=true&" + strContentTypeHeader.toLowerCase() + "=" + defaultContentType;
|
|
120
149
|
let _killSwitch: EVTKillSwitch = new EVTKillSwitch();
|
|
121
150
|
let _paused = false;
|
|
122
151
|
let _clockSkewManager = new EVTClockSkewManager();
|
|
@@ -133,6 +162,9 @@ export default class HttpManager {
|
|
|
133
162
|
let _enableEventTimings = false;
|
|
134
163
|
let _cookieMgr: ICookieMgr;
|
|
135
164
|
let _isUnloading = false;
|
|
165
|
+
let _useHeaders = false;
|
|
166
|
+
let _xhrTimeout: number;
|
|
167
|
+
let _disableXhrSync: boolean;
|
|
136
168
|
|
|
137
169
|
dynamicProto(HttpManager, this, (_self) => {
|
|
138
170
|
let _sendCredentials = true;
|
|
@@ -149,6 +181,9 @@ export default class HttpManager {
|
|
|
149
181
|
}
|
|
150
182
|
|
|
151
183
|
_urlString = endpointUrl + _urlString;
|
|
184
|
+
|
|
185
|
+
// Task 12886642: Defaulting to 'false' until the Collector handles sending upload-time header in the OPTIONS call
|
|
186
|
+
_useHeaders = !isUndefined(channelConfig.avoidOptions) ? !channelConfig.avoidOptions : false;
|
|
152
187
|
_core = core;
|
|
153
188
|
_cookieMgr = core.getCookieMgr();
|
|
154
189
|
_enableEventTimings = !(_core.config as IExtendedConfiguration).disableEventTimings;
|
|
@@ -160,17 +195,15 @@ export default class HttpManager {
|
|
|
160
195
|
enableCompoundKey = !!channelConfig.enableCompoundKey;
|
|
161
196
|
}
|
|
162
197
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// if (!!channelConfig.disableCacheHeader) {
|
|
166
|
-
// // Stop Chrome from stalling/throttling requests see task #7178858
|
|
167
|
-
// _self.addHeader("Cache-control", "no-cache, no-store");
|
|
168
|
-
// }
|
|
198
|
+
_xhrTimeout = channelConfig.xhrTimeout;
|
|
199
|
+
_disableXhrSync = channelConfig.disableXhrSync;
|
|
169
200
|
|
|
170
201
|
_useBeacons = !isReactNative(); // Only use beacons if not running in React Native
|
|
171
202
|
_serializer = new Serializer(_core, valueSanitizer, stringifyObjects, enableCompoundKey);
|
|
172
203
|
|
|
173
204
|
let syncHttpInterface = httpInterface;
|
|
205
|
+
let beaconHttpInterface: IXHROverride = channelConfig.alwaysUseXhrOverride ? httpInterface : null;
|
|
206
|
+
let fetchSyncHttpInterface: IXHROverride = channelConfig.alwaysUseXhrOverride ? httpInterface : null;
|
|
174
207
|
|
|
175
208
|
if (!httpInterface) {
|
|
176
209
|
_customHttpInterface = false;
|
|
@@ -210,8 +243,8 @@ export default class HttpManager {
|
|
|
210
243
|
_sendInterfaces = {
|
|
211
244
|
[EventSendType.Batched]: httpInterface,
|
|
212
245
|
[EventSendType.Synchronous]: syncHttpInterface || _getSenderInterface([TransportType.Xhr, TransportType.Fetch, TransportType.Beacon], true),
|
|
213
|
-
[EventSendType.SendBeacon]: _getSenderInterface([TransportType.Beacon, TransportType.Fetch, TransportType.Xhr], true)
|
|
214
|
-
[EventSendType.SyncFetch]: _getSenderInterface([TransportType.Fetch, TransportType.Beacon, TransportType.Xhr], true)
|
|
246
|
+
[EventSendType.SendBeacon]: beaconHttpInterface || _getSenderInterface([TransportType.Beacon, TransportType.Fetch], true) || syncHttpInterface || _getSenderInterface([TransportType.Xhr], true),
|
|
247
|
+
[EventSendType.SyncFetch]: fetchSyncHttpInterface || _getSenderInterface([TransportType.Fetch, TransportType.Beacon], true) || syncHttpInterface || _getSenderInterface([TransportType.Xhr], true)
|
|
215
248
|
};
|
|
216
249
|
};
|
|
217
250
|
|
|
@@ -256,6 +289,9 @@ export default class HttpManager {
|
|
|
256
289
|
// It doesn't support custom headers, so no action is taken with current requestHeaders
|
|
257
290
|
let xdr = new XDomainRequest();
|
|
258
291
|
xdr.open(Method, payload.urlString);
|
|
292
|
+
if (payload.timeout) {
|
|
293
|
+
xdr.timeout = payload.timeout;
|
|
294
|
+
}
|
|
259
295
|
|
|
260
296
|
// can't get the status code in xdr.
|
|
261
297
|
xdr.onload = () => {
|
|
@@ -288,6 +324,9 @@ export default class HttpManager {
|
|
|
288
324
|
}
|
|
289
325
|
|
|
290
326
|
function _fetchSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
|
|
327
|
+
let theUrl = payload.urlString;
|
|
328
|
+
let ignoreResponse = false;
|
|
329
|
+
let responseHandled = false;
|
|
291
330
|
let requestInit: RequestInit = {
|
|
292
331
|
body: payload.data,
|
|
293
332
|
method: Method,
|
|
@@ -296,6 +335,12 @@ export default class HttpManager {
|
|
|
296
335
|
|
|
297
336
|
if (sync) {
|
|
298
337
|
requestInit.keepalive = true;
|
|
338
|
+
if ((payload as IInternalPayloadData)._sendReason === SendRequestReason.Unload) {
|
|
339
|
+
// As a sync request (during unload), it is unlikely that we will get a chance to process the response so
|
|
340
|
+
// just like beacon send assume that the events have been accepted and processed
|
|
341
|
+
ignoreResponse = true;
|
|
342
|
+
theUrl += _noResponseQs;
|
|
343
|
+
}
|
|
299
344
|
}
|
|
300
345
|
|
|
301
346
|
if (_sendCredentials) {
|
|
@@ -308,7 +353,7 @@ export default class HttpManager {
|
|
|
308
353
|
requestInit.headers = payload.headers;
|
|
309
354
|
}
|
|
310
355
|
|
|
311
|
-
fetch(
|
|
356
|
+
fetch(theUrl, requestInit).then((response) => {
|
|
312
357
|
let headerMap = {};
|
|
313
358
|
let responseText = "";
|
|
314
359
|
if (response.headers) {
|
|
@@ -321,16 +366,41 @@ export default class HttpManager {
|
|
|
321
366
|
responseText = text;
|
|
322
367
|
});
|
|
323
368
|
}
|
|
324
|
-
|
|
325
|
-
|
|
369
|
+
|
|
370
|
+
if (!responseHandled) {
|
|
371
|
+
responseHandled = true;
|
|
372
|
+
_doOnComplete(oncomplete, response.status, headerMap, responseText);
|
|
373
|
+
_handleCollectorResponse(responseText);
|
|
374
|
+
}
|
|
326
375
|
}).catch((error) => {
|
|
327
376
|
// In case there is an error in the request. Set the status to 0
|
|
328
377
|
// so that the events can be retried later.
|
|
329
|
-
|
|
378
|
+
if (!responseHandled) {
|
|
379
|
+
responseHandled = true;
|
|
380
|
+
_doOnComplete(oncomplete, 0, {});
|
|
381
|
+
}
|
|
330
382
|
});
|
|
383
|
+
|
|
384
|
+
if (ignoreResponse && !responseHandled) {
|
|
385
|
+
// Assume success during unload processing
|
|
386
|
+
responseHandled = true;
|
|
387
|
+
_doOnComplete(oncomplete, 200, {});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (!responseHandled && payload.timeout > 0) {
|
|
391
|
+
// Simulate timeout
|
|
392
|
+
_postManager._setTimeoutOverride(() => {
|
|
393
|
+
if (!responseHandled) {
|
|
394
|
+
// Assume a 500 response (which will cause a retry)
|
|
395
|
+
responseHandled = true;
|
|
396
|
+
_doOnComplete(oncomplete, 500, {});
|
|
397
|
+
}
|
|
398
|
+
}, payload.timeout);
|
|
399
|
+
}
|
|
331
400
|
}
|
|
332
401
|
|
|
333
402
|
function _xhrSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
|
|
403
|
+
let theUrl = payload.urlString;
|
|
334
404
|
|
|
335
405
|
function _appendHeader(theHeaders, xhr, name) {
|
|
336
406
|
if (!theHeaders[name] && xhr && xhr.getResponseHeader) {
|
|
@@ -363,25 +433,28 @@ export default class HttpManager {
|
|
|
363
433
|
function xhrComplete(xhr, responseTxt?) {
|
|
364
434
|
_doOnComplete(oncomplete, xhr.status, _getAllResponseHeaders(xhr), responseTxt);
|
|
365
435
|
}
|
|
436
|
+
if (sync && payload.disableXhrSync) {
|
|
437
|
+
sync = false;
|
|
438
|
+
}
|
|
366
439
|
|
|
367
|
-
let
|
|
440
|
+
let xhrRequest = openXhr(Method, theUrl, _sendCredentials, true, sync, payload.timeout);
|
|
368
441
|
|
|
369
442
|
// Set custom headers (e.g. gzip) here (after open())
|
|
370
443
|
objForEachKey(payload.headers, (name, value) => {
|
|
371
|
-
|
|
444
|
+
xhrRequest.setRequestHeader(name, value);
|
|
372
445
|
});
|
|
373
|
-
|
|
374
|
-
let response = _getResponseText(
|
|
375
|
-
xhrComplete(
|
|
446
|
+
xhrRequest.onload = () => {
|
|
447
|
+
let response = _getResponseText(xhrRequest);
|
|
448
|
+
xhrComplete(xhrRequest, response);
|
|
376
449
|
_handleCollectorResponse(response);
|
|
377
450
|
};
|
|
378
|
-
|
|
379
|
-
xhrComplete(
|
|
451
|
+
xhrRequest.onerror = () => {
|
|
452
|
+
xhrComplete(xhrRequest);
|
|
380
453
|
};
|
|
381
|
-
|
|
382
|
-
xhrComplete(
|
|
454
|
+
xhrRequest.ontimeout = () => {
|
|
455
|
+
xhrComplete(xhrRequest);
|
|
383
456
|
};
|
|
384
|
-
|
|
457
|
+
xhrRequest.send(payload.data);
|
|
385
458
|
}
|
|
386
459
|
|
|
387
460
|
function _doOnComplete(oncomplete: OnCompleteCallback, status: number, headers: { [headerName: string]: string }, response?: string) {
|
|
@@ -398,9 +471,11 @@ export default class HttpManager {
|
|
|
398
471
|
let internalPayloadData = payload as IInternalPayloadData;
|
|
399
472
|
let status = 200;
|
|
400
473
|
let thePayload = internalPayloadData._thePayload;
|
|
474
|
+
let theUrl = payload.urlString + _noResponseQs;
|
|
475
|
+
|
|
401
476
|
try {
|
|
402
477
|
let nav = getNavigator();
|
|
403
|
-
if (!nav.sendBeacon(
|
|
478
|
+
if (!nav.sendBeacon(theUrl, payload.data)) {
|
|
404
479
|
if (thePayload) {
|
|
405
480
|
// Failed to send entire payload so try and split data and try to send as much events as possible
|
|
406
481
|
let droppedBatches: EventBatch[] = [];
|
|
@@ -408,7 +483,7 @@ export default class HttpManager {
|
|
|
408
483
|
if (droppedBatches && theBatch && theBatch.count() > 0) {
|
|
409
484
|
let theEvents = theBatch.events();
|
|
410
485
|
for (let lp = 0; lp < theEvents.length; lp++) {
|
|
411
|
-
if (!nav.sendBeacon(
|
|
486
|
+
if (!nav.sendBeacon(theUrl, _serializer.getEventBlob(theEvents[lp]))) {
|
|
412
487
|
// Can't send anymore, so split the batch and drop the rest
|
|
413
488
|
droppedBatches.push(theBatch.split(lp));
|
|
414
489
|
break;
|
|
@@ -670,8 +745,36 @@ export default class HttpManager {
|
|
|
670
745
|
}
|
|
671
746
|
}
|
|
672
747
|
|
|
673
|
-
function
|
|
674
|
-
let
|
|
748
|
+
function _buildRequestDetails(thePayload: ISerializedPayload, useHeaders: boolean): IRequestUrlDetails {
|
|
749
|
+
let requestDetails: IRequestUrlDetails = {
|
|
750
|
+
url: _urlString,
|
|
751
|
+
hdrs: {},
|
|
752
|
+
useHdrs: false // Assume no headers
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
756
|
+
// Task 12886642: Need to wait until an updated version of the collector is released to return these as allowed in the OPTIONS call
|
|
757
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
758
|
+
// if (!useHeaders) {
|
|
759
|
+
// // Attempt to map headers to a query string if possible
|
|
760
|
+
// objForEachKey(_headers, (name, value) => {
|
|
761
|
+
// if (_collectorHeaderToQs[name]) {
|
|
762
|
+
// _addRequestDetails(requestDetails, _collectorHeaderToQs[name], value, false);
|
|
763
|
+
// } else {
|
|
764
|
+
// // No mapping, so just include in the headers anyway (may not get sent if using sendBeacon())
|
|
765
|
+
// requestDetails.hdrs[name] = value;
|
|
766
|
+
// requestDetails.useHdrs = true;
|
|
767
|
+
// }
|
|
768
|
+
// });
|
|
769
|
+
// } else {
|
|
770
|
+
// Copy the pre-defined headers into the payload headers
|
|
771
|
+
requestDetails.hdrs = extend(requestDetails.hdrs, _headers);
|
|
772
|
+
requestDetails.useHdrs = (objKeys(requestDetails.hdrs).length > 0);
|
|
773
|
+
// }
|
|
774
|
+
// ----------------------------------------------------------------------------------------------------------------
|
|
775
|
+
|
|
776
|
+
_addRequestDetails(requestDetails, strClientId, "NO_AUTH", useHeaders);
|
|
777
|
+
_addRequestDetails(requestDetails, strClientVersion, FullVersionString, useHeaders);
|
|
675
778
|
|
|
676
779
|
let apiQsKeys = "";
|
|
677
780
|
arrForEach(thePayload.apiKeys, (apiKey) => {
|
|
@@ -682,33 +785,30 @@ export default class HttpManager {
|
|
|
682
785
|
apiQsKeys += apiKey;
|
|
683
786
|
});
|
|
684
787
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
urlString += "&upload-time=" + dateNow().toString();
|
|
788
|
+
_addRequestDetails(requestDetails, strApiKey, apiQsKeys, useHeaders);
|
|
789
|
+
_addRequestDetails(requestDetails, strUploadTime, dateNow().toString(), useHeaders);
|
|
690
790
|
|
|
691
791
|
let msfpc = _getMsfpc(thePayload);
|
|
692
792
|
if (isValueAssigned(msfpc)) {
|
|
693
|
-
|
|
793
|
+
requestDetails.url += "&ext.intweb.msfpc=" + msfpc;
|
|
694
794
|
}
|
|
695
795
|
|
|
696
796
|
if (_clockSkewManager.shouldAddClockSkewHeaders()) {
|
|
697
|
-
|
|
797
|
+
_addRequestDetails(requestDetails, strTimeDeltaToApply, _clockSkewManager.getClockSkewHeaderValue(), useHeaders);
|
|
698
798
|
}
|
|
699
799
|
|
|
700
800
|
if (_core.getWParam) {
|
|
701
801
|
let wParam = _core.getWParam();
|
|
702
802
|
if (wParam >= 0) {
|
|
703
|
-
|
|
803
|
+
requestDetails.url += "&w=" + wParam;
|
|
704
804
|
}
|
|
705
805
|
}
|
|
706
806
|
|
|
707
807
|
for (let i = 0; i < _queryStringParameters.length; i++) {
|
|
708
|
-
|
|
808
|
+
requestDetails.url += "&" + _queryStringParameters[i].name + "=" + _queryStringParameters[i].value;
|
|
709
809
|
}
|
|
710
810
|
|
|
711
|
-
return
|
|
811
|
+
return requestDetails;
|
|
712
812
|
}
|
|
713
813
|
|
|
714
814
|
function _canUseSendBeaconApi() {
|
|
@@ -723,9 +823,25 @@ export default class HttpManager {
|
|
|
723
823
|
function _doPayloadSend(thePayload: ISerializedPayload, serializationStart: number, serializationCompleted: number, sendReason: SendRequestReason) {
|
|
724
824
|
|
|
725
825
|
if (thePayload && thePayload.payloadBlob && thePayload.payloadBlob.length > 0) {
|
|
726
|
-
let
|
|
826
|
+
let useSendHook = !!_self.sendHook;
|
|
827
|
+
let sendInterface = _sendInterfaces[thePayload.sendType];
|
|
828
|
+
|
|
829
|
+
// Send all data using a beacon style transport if closing mode is on or channel was teared down
|
|
830
|
+
if (!_isBeaconPayload(thePayload.sendType) && thePayload.isBeacon && thePayload.sendReason === SendRequestReason.Unload) {
|
|
831
|
+
sendInterface = _sendInterfaces[EventSendType.SendBeacon] || _sendInterfaces[EventSendType.SyncFetch] || sendInterface;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
let useHeaders = _useHeaders;
|
|
835
|
+
|
|
836
|
+
// Disable header usage if we know we are using sendBeacon as additional headers are not supported
|
|
837
|
+
if (thePayload.isBeacon || sendInterface._transport === TransportType.Beacon) {
|
|
838
|
+
useHeaders = false;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
let requestDetails = _buildRequestDetails(thePayload, useHeaders);
|
|
842
|
+
useHeaders = useHeaders || requestDetails.useHdrs;
|
|
843
|
+
|
|
727
844
|
let sendEventStart = getTime();
|
|
728
|
-
let strSendAttempt = "sendAttempt";
|
|
729
845
|
|
|
730
846
|
doPerf(_core, () => "HttpManager:_doPayloadSend", () => {
|
|
731
847
|
// Increment the send attempt count and add timings after packaging (So it's not serialized in the 1st attempt)
|
|
@@ -757,28 +873,29 @@ export default class HttpManager {
|
|
|
757
873
|
// eslint-disable-next-line prefer-const
|
|
758
874
|
let orgPayloadData: IInternalPayloadData = {
|
|
759
875
|
data: thePayload.payloadBlob,
|
|
760
|
-
urlString:
|
|
761
|
-
headers:
|
|
876
|
+
urlString: requestDetails.url,
|
|
877
|
+
headers: requestDetails.hdrs,
|
|
762
878
|
_thePayload: thePayload,
|
|
763
|
-
_sendReason: sendReason
|
|
879
|
+
_sendReason: sendReason,
|
|
880
|
+
timeout: _xhrTimeout
|
|
764
881
|
};
|
|
765
882
|
|
|
766
|
-
if (!
|
|
767
|
-
orgPayloadData.
|
|
883
|
+
if (!isUndefined(_disableXhrSync)) {
|
|
884
|
+
orgPayloadData.disableXhrSync = !!_disableXhrSync;
|
|
768
885
|
}
|
|
769
886
|
|
|
770
|
-
if
|
|
771
|
-
|
|
887
|
+
// Only automatically add the following headers if already sending headers and we are not attempting to avoid an options call
|
|
888
|
+
if (useHeaders) {
|
|
889
|
+
if (!_hasHeader(orgPayloadData.headers, strCacheControl)) {
|
|
890
|
+
orgPayloadData.headers[strCacheControl] = defaultCacheControl;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
if (!_hasHeader(orgPayloadData.headers, strContentTypeHeader)) {
|
|
894
|
+
orgPayloadData.headers[strContentTypeHeader] = defaultContentType;
|
|
895
|
+
}
|
|
772
896
|
}
|
|
773
897
|
|
|
774
898
|
let sender: (payload: IPayloadData) => void = null;
|
|
775
|
-
let useSendHook = !!_self.sendHook;
|
|
776
|
-
|
|
777
|
-
let sendInterface = _sendInterfaces[thePayload.sendType];
|
|
778
|
-
// Send all data using a beacon style transport if closing mode is on or channel was teared down
|
|
779
|
-
if (!_isBeaconPayload(thePayload.sendType) && thePayload.isBeacon && thePayload.sendReason === SendRequestReason.Unload) {
|
|
780
|
-
sendInterface = _sendInterfaces[EventSendType.SendBeacon] || _sendInterfaces[EventSendType.SyncFetch] || sendInterface;
|
|
781
|
-
}
|
|
782
899
|
|
|
783
900
|
if (sendInterface) {
|
|
784
901
|
// Send sync requests if the request is immediate or we are tearing down telemetry.
|
|
@@ -822,7 +939,9 @@ export default class HttpManager {
|
|
|
822
939
|
let hookData: IPayloadData = {
|
|
823
940
|
data: orgPayloadData.data,
|
|
824
941
|
urlString: orgPayloadData.urlString,
|
|
825
|
-
headers: extend({}, orgPayloadData.headers)
|
|
942
|
+
headers: extend({}, orgPayloadData.headers),
|
|
943
|
+
timeout: orgPayloadData.timeout,
|
|
944
|
+
disableXhrSync: orgPayloadData.disableXhrSync
|
|
826
945
|
};
|
|
827
946
|
|
|
828
947
|
let senderCalled = false;
|
|
@@ -908,7 +1027,7 @@ export default class HttpManager {
|
|
|
908
1027
|
|
|
909
1028
|
// Disabling triple-equals rule to avoid httpOverrides from failing because they are returning a string value
|
|
910
1029
|
// tslint:disable-next-line:triple-equals
|
|
911
|
-
if (status == 200) {
|
|
1030
|
+
if (status == 200 || status == 204) {
|
|
912
1031
|
// Response was successfully sent
|
|
913
1032
|
reason = EventBatchNotificationReason.Complete;
|
|
914
1033
|
return;
|
|
@@ -928,7 +1047,8 @@ export default class HttpManager {
|
|
|
928
1047
|
reason = EventBatchNotificationReason.RequeueEvents;
|
|
929
1048
|
let retryCount = thePayload.retryCnt;
|
|
930
1049
|
if (thePayload.sendType === EventSendType.Batched) {
|
|
931
|
-
|
|
1050
|
+
// attempt to resend the entire batch
|
|
1051
|
+
if (retryCount < maxRequestRetriesBeforeBackoff) {
|
|
932
1052
|
isRetrying = true;
|
|
933
1053
|
_doAction(() => {
|
|
934
1054
|
// try to resend the same batches
|
|
@@ -943,6 +1063,11 @@ export default class HttpManager {
|
|
|
943
1063
|
}, _isUnloading, RetryPolicy.getMillisToBackoffForRetry(retryCount));
|
|
944
1064
|
} else {
|
|
945
1065
|
backOffTrans = true;
|
|
1066
|
+
if (_isUnloading) {
|
|
1067
|
+
// we are unloading so don't try and requeue the events otherwise let the events get requeued and resent during the backoff sending
|
|
1068
|
+
// This will also cause the events to be purged based on the priority (if necessary)
|
|
1069
|
+
reason = EventBatchNotificationReason.NonRetryableStatus;
|
|
1070
|
+
}
|
|
946
1071
|
}
|
|
947
1072
|
}
|
|
948
1073
|
}
|
|
@@ -1048,12 +1173,9 @@ export default class HttpManager {
|
|
|
1048
1173
|
|
|
1049
1174
|
function _getMsfpc(thePayload: ISerializedPayload): string {
|
|
1050
1175
|
for (let lp = 0; lp < thePayload.batches.length; lp++) {
|
|
1051
|
-
let
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
if (isValueAssigned(intWeb["msfpc"])) {
|
|
1055
|
-
return encodeURIComponent(intWeb["msfpc"]);
|
|
1056
|
-
}
|
|
1176
|
+
let msfpc = thePayload.batches[lp].Msfpc();
|
|
1177
|
+
if (msfpc) {
|
|
1178
|
+
return encodeURIComponent(msfpc);
|
|
1057
1179
|
}
|
|
1058
1180
|
}
|
|
1059
1181
|
|
|
@@ -1074,9 +1196,9 @@ export default class HttpManager {
|
|
|
1074
1196
|
}
|
|
1075
1197
|
if (responseText) {
|
|
1076
1198
|
let response = JSON.parse(responseText) as ICollectorResult;
|
|
1077
|
-
if (isValueAssigned(response.webResult) && isValueAssigned(response.webResult
|
|
1199
|
+
if (isValueAssigned(response.webResult) && isValueAssigned(response.webResult[strMsfpc])) {
|
|
1078
1200
|
// Set cookie
|
|
1079
|
-
_cookieMgr.set("MSFPC", response.webResult
|
|
1201
|
+
_cookieMgr.set("MSFPC", response.webResult[strMsfpc], 365 * 86400);
|
|
1080
1202
|
}
|
|
1081
1203
|
}
|
|
1082
1204
|
} catch (ex) {
|