From 74c99880e3b6a90d86592314d8d754a015ea603c Mon Sep 17 00:00:00 2001 From: Nev Wylie Date: Tue, 12 May 2020 22:18:09 -0700 Subject: [PATCH] [BUG] Can include Correlation Header on IE can fail #1260 [BUG] ajax.ts is using string trim() which is not supported on IE7/8 #1251 --- .../src/Sender.ts | 3 +- .../src/ajax.ts | 8 +- shared/AppInsightsCommon/Tests/Util.tests.ts | 327 ++++++++++++++++++ shared/AppInsightsCommon/src/Util.ts | 95 +++-- .../src/JavaScriptSDK/CoreUtils.ts | 11 + tools/rollup-es3/src/es3/Es3Tokens.ts | 14 +- tools/rollup-es3/src/es3/Interfaces.ts | 4 +- tools/rollup-es3/src/es3/Utils.ts | 16 +- 8 files changed, 443 insertions(+), 35 deletions(-) diff --git a/channels/applicationinsights-channel-js/src/Sender.ts b/channels/applicationinsights-channel-js/src/Sender.ts index d27008a3f..bdd76aa7e 100644 --- a/channels/applicationinsights-channel-js/src/Sender.ts +++ b/channels/applicationinsights-channel-js/src/Sender.ts @@ -423,7 +423,8 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControlsAI { this._retryAt = null; } catch (e) { /* Ignore this error for IE under v10 */ - if (!Util.getIEVersion() || Util.getIEVersion() > 9) { + let ieVer = Util.getIEVersion(); + if (!ieVer || ieVer > 9) { this.diagLog().throwInternal( LoggingSeverity.CRITICAL, _InternalMessageId.TransmissionFailed, diff --git a/extensions/applicationinsights-dependencies-js/src/ajax.ts b/extensions/applicationinsights-dependencies-js/src/ajax.ts index 9af7a75c2..d614fa47a 100644 --- a/extensions/applicationinsights-dependencies-js/src/ajax.ts +++ b/extensions/applicationinsights-dependencies-js/src/ajax.ts @@ -59,10 +59,8 @@ function _supportsAjaxMonitoring(ajaxMonitorInstance:AjaxMonitor): boolean { !_isNullOrUndefined(proto.abort); } - // disable in IE8 or older (https://www.w3schools.com/jsref/jsref_trim_string.asp) - try { - " a ".trim(); - } catch (ex) { + let ieVer = Util.getIEVersion(); + if (ieVer && ieVer < 9) { result = false; } @@ -671,7 +669,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu if (headers) { // xhr.getAllResponseHeaders() method returns all the response headers, separated by CRLF, as a string or null // the regex converts the header string into an array of individual headers - const arr = headers.trim().split(/[\r\n]+/); + const arr = CoreUtils.strTrim(headers).split(/[\r\n]+/); const responseHeaderMap = {}; _arrForEach(arr, (line) => { const parts = line.split(': '); diff --git a/shared/AppInsightsCommon/Tests/Util.tests.ts b/shared/AppInsightsCommon/Tests/Util.tests.ts index 222553c81..da44fd9ec 100644 --- a/shared/AppInsightsCommon/Tests/Util.tests.ts +++ b/shared/AppInsightsCommon/Tests/Util.tests.ts @@ -57,6 +57,96 @@ export class UtilTests extends TestClass { Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com")); Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com/")); Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com/")); + + Assert.equal("portal.azure.com", UrlHelper.parseHost("https://portal.azure.com/some/endpoint", false)); + Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com", false)); + Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com/", false)); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com/", false)); + + Assert.equal("portal.azure.com", UrlHelper.parseHost("https://portal.azure.com/some/endpoint", true)); + Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com", true)); + Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com/", true)); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com/", true)); + + // Check with port included + Assert.equal("portal.azure.com", UrlHelper.parseHost("https://portal.azure.com:9999/some/endpoint")); + Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com:9999")); + Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com:9999/")); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/")); + + Assert.equal("portal.azure.com", UrlHelper.parseHost("https://portal.azure.com:9999/some/endpoint", false)); + Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com:9999", false)); + Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com:9999/", false)); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/", false)); + + Assert.equal("portal.azure.com:9999", UrlHelper.parseHost("https://portal.azure.com:9999/some/endpoint", true)); + Assert.equal("bing.com:9999", UrlHelper.parseHost("http://www.bing.com:9999", true)); + Assert.equal("bing.com:9999", UrlHelper.parseHost("https://www2.bing.com:9999/", true)); + Assert.equal("p.r.e.f.i.x.bing.com:9999", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/", true)); + + // Check with default ports present + Assert.equal("portal.azure.com", UrlHelper.parseHost("http://portal.azure.com:80/some/endpoint", true)); + Assert.equal("portal.azure.com", UrlHelper.parseHost("https://portal.azure.com:443/some/endpoint", true)); + Assert.equal("portal.azure.com:80", UrlHelper.parseHost("https://portal.azure.com:80/some/endpoint", true)); + Assert.equal("portal.azure.com:443", UrlHelper.parseHost("http://portal.azure.com:443/some/endpoint", true)); + Assert.equal("bing.com", UrlHelper.parseHost("http://www.bing.com:80", true)); + Assert.equal("bing.com", UrlHelper.parseHost("https://www2.bing.com:443/", true)); + Assert.equal("bing.com:80", UrlHelper.parseHost("https://www.bing.com:80", true)); + Assert.equal("bing.com:443", UrlHelper.parseHost("http://www2.bing.com:443/", true)); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com:80/", true)); + Assert.equal("p.r.e.f.i.x.bing.com", UrlHelper.parseHost("https://wwW2.p.r.e.f.i.x.bing.com:443/", true)); + Assert.equal("p.r.e.f.i.x.bing.com:443", UrlHelper.parseHost("http://wwW2.p.r.e.f.i.x.bing.com:443/", true)); + Assert.equal("p.r.e.f.i.x.bing.com:80", UrlHelper.parseHost("https://wwW2.p.r.e.f.i.x.bing.com:80/", true)); + } + }); + + this.testCase({ + name: "UrlHelper: parseFullHost should return correct host name", + test: () => { + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com/some/endpoint")); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com")); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com/")); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com/")); + + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com/some/endpoint", false)); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com", false)); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com/", false)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com/", false)); + + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com/some/endpoint", true)); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com", true)); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com/", true)); + + // Check with port included + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com:9999/some/endpoint")); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com:9999")); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com:9999/")); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/")); + + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com:9999/some/endpoint", false)); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com:9999", false)); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com:9999/", false)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/", false)); + + Assert.equal("portal.azure.com:9999", UrlHelper.parseFullHost("https://portal.azure.com:9999/some/endpoint", true)); + Assert.equal("www.bing.com:9999", UrlHelper.parseFullHost("http://www.bing.com:9999", true)); + Assert.equal("www2.bing.com:9999", UrlHelper.parseFullHost("https://www2.bing.com:9999/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com:9999", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com:9999/", true)); + + // Check with default ports present + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("http://portal.azure.com:80/some/endpoint", true)); + Assert.equal("portal.azure.com", UrlHelper.parseFullHost("https://portal.azure.com:443/some/endpoint", true)); + Assert.equal("portal.azure.com:80", UrlHelper.parseFullHost("https://portal.azure.com:80/some/endpoint", true)); + Assert.equal("portal.azure.com:443", UrlHelper.parseFullHost("http://portal.azure.com:443/some/endpoint", true)); + Assert.equal("www.bing.com", UrlHelper.parseFullHost("http://www.bing.com:80", true)); + Assert.equal("www2.bing.com", UrlHelper.parseFullHost("https://www2.bing.com:443/", true)); + Assert.equal("www.bing.com:80", UrlHelper.parseFullHost("https://www.bing.com:80", true)); + Assert.equal("www2.bing.com:443", UrlHelper.parseFullHost("http://www2.bing.com:443/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com:80/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com", UrlHelper.parseFullHost("https://wwW2.p.r.e.f.i.x.bing.com:443/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com:443", UrlHelper.parseFullHost("http://wwW2.p.r.e.f.i.x.bing.com:443/", true)); + Assert.equal("wwW2.p.r.e.f.i.x.bing.com:80", UrlHelper.parseFullHost("https://wwW2.p.r.e.f.i.x.bing.com:80/", true)); } }); @@ -113,6 +203,132 @@ export class UtilTests extends TestClass { } }); + this.testCase({ + name: "CorrelationidHelper: canIncludeCorrelationHeader check when the url includes the port", + test: () => { + const config = { + enableCorsCorrelation: true, + correlationHeaderExcludedDomains: ["test", "*.azure.com", "ignore.microsoft.com"], + correlationHeaderDomains: ["azure.com", "prefix.bing.com", "*.microsoft.com"] + } as ICorrelationConfig + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://azure.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:8000", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://monitor.azure.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://monitor.azure.com:443", "example.com")); + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://prefix.bing.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:8000", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://ignore.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:80", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:8080", "example.com")); + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://something.microsoft.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:8000", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:80", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:8000", "example.com")); + } + }); + + this.testCase({ + name: "CorrelationidHelper: canIncludeCorrelationHeader check when the url and include includes the port", + test: () => { + const config = { + enableCorsCorrelation: true, + correlationHeaderExcludedDomains: ["test", "*.azure.com", "ignore.microsoft.com"], + correlationHeaderDomains: ["azure.com", "prefix.bing.com", "*.microsoft.com:8080"] + } as ICorrelationConfig + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://azure.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://azure.com:8000", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://monitor.azure.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://monitor.azure.com:443", "example.com")); + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://prefix.bing.com:443", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:8000", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://ignore.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:80", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://ignore.microsoft.com:8080", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://something.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:80", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:8000", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:8080", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:80", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:8000", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:8080", "example.com")); + } + }); + + this.testCase({ + name: "CorrelationidHelper: canIncludeCorrelationHeader check when the url includes the port and disabled CorsCorrelation", + test: () => { + const config = { + enableCorsCorrelation: false, + correlationHeaderExcludedDomains: ["test", "*.azure.com", "ignore.microsoft.com"], + correlationHeaderDomains: ["azure.com", "prefix.bing.com", "*.microsoft.com", "example.com"] + } as ICorrelationConfig + + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://example.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://example.com:80", "example.com")); + Assert.equal(true, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://example.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://example.com:8000", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://example.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://example.com:8080", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://monitor.azure.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://monitor.azure.com:443", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://prefix.bing.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://prefix.bing.com:80", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://something.microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://something.microsoft.com:80", "example.com")); + + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "http://microsoft.com:443", "example.com")); + Assert.equal(false, CorrelationIdHelper.canIncludeCorrelationHeader(config, "https://microsoft.com:80", "example.com")); + } + }); + this.testCase({ name: "Check disableSameSiteCookie status", test: () => { @@ -219,5 +435,116 @@ export class UtilTests extends TestClass { } } }); + + this.testCase({ + name: "check getIEVersion", + test: () => { + let notIEValues = [ + "", + null, + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15", + "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (iPad; CPU OS 12_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; MSAppHost/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/71.0.3578.89 Mobile/15E148 Safari/605.1", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/65.0.225212226 Mobile/15E148 Safari/605.1", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16C101", + "Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.1.00.31860 Chrome/61.0.3163.100 Electron/2.0.10 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G950F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G930F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/71.0.3578.89 Mobile/15E148 Safari/605.1", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/605.1.15 (KHTML, like Gecko)", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G935F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 12_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6821.400 QQBrowser/10.3.3040.400", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Yammer/2.1.0 Chrome/66.0.3359.181 Electron/3.0.6 Safari/537.36", + "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G965F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-A520F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G955F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G950U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G960U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.1.00.31860 Chrome/61.0.3163.100 Electron/2.0.10 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15", + "Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/65.0.225212226 Mobile/15E148 Safari/605.1", + "Mozilla/5.0 (iPad; CPU OS 12_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16C50", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-N950U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 6.0.1; SM-G532M Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36", + "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36", + "Mozilla/5.0 (Linux; Android 7.0; SAMSUNG SM-G920F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6821.400 QQBrowser/10.3.3040.400", + "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 EdgiOS/42.8.6 Mobile/16C101 Safari/605.1.15", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-N950F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", + "Mozilla/5.0 (Linux; Android 8.1.0; SAMSUNG SM-J530F Build/M1AJQ) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/8.2 Chrome/63.0.3239.111 Mobile Safari/537.36" + ]; + + for (let lp = 0; lp < notIEValues.length; lp++) { + let ieVersion = Util.getIEVersion(notIEValues[lp]); + Assert.equal(null, ieVersion, "Not IE: " + notIEValues[lp]); + } + + Assert.equal(7, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)")); + Assert.equal(7, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0;)")); + Assert.equal(7, Util.getIEVersion("Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; en-US)")); + Assert.equal(8, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)")); + Assert.equal(8, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)")); + Assert.equal(8, Util.getIEVersion("Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)")); + Assert.equal(8, Util.getIEVersion("Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)")); + Assert.equal(9, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.0)")); + Assert.equal(9, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)")); + Assert.equal(10, Util.getIEVersion("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)")); + Assert.equal(10, Util.getIEVersion("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2)")); + Assert.equal(11, Util.getIEVersion("Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko")); + Assert.equal(11, Util.getIEVersion("Mozilla/5.0 (Windows NT 6.2; Trident/7.0; rv:11.0) like Gecko")); + Assert.equal(11, Util.getIEVersion("Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko")); + Assert.equal(11, Util.getIEVersion("Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko")); + Assert.equal(11, Util.getIEVersion("Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko")); + } + }); } } \ No newline at end of file diff --git a/shared/AppInsightsCommon/src/Util.ts b/shared/AppInsightsCommon/src/Util.ts index 11027d97b..ac66aef38 100644 --- a/shared/AppInsightsCommon/src/Util.ts +++ b/shared/AppInsightsCommon/src/Util.ts @@ -474,10 +474,7 @@ export class Util { /** * helper method to trim strings (IE8 does not implement String.prototype.trim) */ - public static trim(str: any): string { - if (!_isString(str)) { return str; } - return str.replace(/^\s+|\s+$/g, ""); - } + public static trim = CoreUtils.strTrim; /** * generate random id string @@ -553,11 +550,20 @@ export class Util { public static toISOStringForIE8 = CoreUtils.toISOString; /** - * Gets IE version if we are running on IE, or null otherwise + * Gets IE version returning the document emulation mode if we are running on IE, or null otherwise */ public static getIEVersion(userAgentStr: string = null): number { const myNav = userAgentStr ? userAgentStr.toLowerCase() : (_navigator ? (_navigator.userAgent ||"").toLowerCase() : ""); - return (myNav.indexOf('msie') !== -1) ? parseInt(myNav.split('msie')[1]) : null; + if (myNav.indexOf("msie") !== -1) { + return parseInt(myNav.split("msie")[1]); + } else if (myNav.indexOf("trident/")) { + let tridentVer = parseInt(myNav.split("trident/")[1]); + if (tridentVer) { + return tridentVer + 4; + } + } + + return null; } /** @@ -652,16 +658,35 @@ export class Util { export class UrlHelper { private static document: any = getDocument()||{}; - private static htmlAnchorElement: HTMLAnchorElement; + + private static _htmlAnchorIdx: number = 0; + // Use an array of temporary values as it's possible for multiple calls to parseUrl() will be called with different URLs + // Using a cache size of 5 for now as it current depth usage is at least 2, so adding a minor buffer to handle future updates + private static _htmlAnchorElement: HTMLAnchorElement[] = [null, null, null, null, null]; public static parseUrl(url: string): HTMLAnchorElement { - if (!UrlHelper.htmlAnchorElement) { - UrlHelper.htmlAnchorElement = !!UrlHelper.document.createElement ? UrlHelper.document.createElement('a') : { host: UrlHelper.parseHost(url) }; // fill host field in the fallback case as that is the only externally required field from this fn + let anchorIdx = UrlHelper._htmlAnchorIdx; + let anchorCache = UrlHelper._htmlAnchorElement; + let tempAnchor = anchorCache[anchorIdx]; + if (!UrlHelper.document.createElement) { + // Always create the temp instance if createElement is not available + tempAnchor = { host: UrlHelper.parseHost(url, true) } as HTMLAnchorElement; + } else if (!anchorCache[anchorIdx]) { + // Create and cache the unattached anchor instance + tempAnchor = anchorCache[anchorIdx] = UrlHelper.document.createElement('a'); } - UrlHelper.htmlAnchorElement.href = url; + tempAnchor.href = url; - return UrlHelper.htmlAnchorElement; + // Move the cache index forward + anchorIdx++; + if (anchorIdx >= anchorCache.length) { + anchorIdx = 0; + } + + UrlHelper._htmlAnchorIdx = anchorIdx; + + return tempAnchor; } public static getAbsoluteUrl(url: string): string { @@ -693,15 +718,43 @@ export class UrlHelper { } // Fallback method to grab host from url if document.createElement method is not available - public static parseHost(url: string) { + public static parseHost(url: string, inclPort?: boolean) { + let fullHost = UrlHelper.parseFullHost(url, inclPort); + if (fullHost ) { + const match = fullHost.match(/(www[0-9]?\.)?(.[^/:]+)(\:[\d]+)?/i); + if (match != null && match.length > 3 && _isString(match[2]) && match[2].length > 0) { + return match[2] + (match[3] ||""); + } + } + + return fullHost; + } + + /** + * Get the full host from the url, optionally including the port + */ + public static parseFullHost(url: string, inclPort?: boolean) { + let result = null; if (url) { - const match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i); + const match = url.match(/(\w*):\/\/(.[^/:]+)(\:[\d]+)?/i); if (match != null && match.length > 2 && _isString(match[2]) && match[2].length > 0) { - return match[2]; + result = match[2] || ""; + if (inclPort && match.length > 2) { + const protocol = (match[1] || "").toLowerCase(); + let port = match[3] || ""; + // IE includes the standard port so pass it off if it's the same as the protocol + if (protocol === "http" && port === ":80") { + port = ""; + } else if (protocol === "https" && port === ":443") { + port = ""; + } + + result += port; + } } } - return null; + return result; } } @@ -711,20 +764,22 @@ export class CorrelationIdHelper { /** * Checks if a request url is not on a excluded domain list and if it is safe to add correlation headers. * Headers are always included if the current domain matches the request domain. If they do not match (CORS), - * they are regexed across correlationHeaderDomains and correlationHeaderExcludedDomains to determine if headers are included. + * they are regex-ed across correlationHeaderDomains and correlationHeaderExcludedDomains to determine if headers are included. * Some environments don't give information on currentHost via window.location.host (e.g. Cordova). In these cases, the user must * manually supply domains to include correlation headers on. Else, no headers will be included at all. */ public static canIncludeCorrelationHeader(config: ICorrelationConfig, requestUrl: string, currentHost?: string) { - if (config && config.disableCorrelationHeaders) { + if (!requestUrl || (config && config.disableCorrelationHeaders)) { return false; } - if (!requestUrl) { - return false; + let requestHost = UrlHelper.parseUrl(requestUrl).host.toLowerCase(); + if (requestHost && (requestHost.indexOf(":443") !== -1 || requestHost.indexOf(":80") !== -1)) { + // [Bug #1260] IE can include the port even for http and https URLs so if present + // try and parse it to remove if it matches the default protocol port + requestHost = (UrlHelper.parseFullHost(requestUrl, true) || "").toLowerCase(); } - const requestHost = UrlHelper.parseUrl(requestUrl).host.toLowerCase(); if ((!config || !config.enableCorsCorrelation) && requestHost !== currentHost) { return false; } diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts b/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts index 2c8050c75..6370ed014 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts @@ -295,6 +295,17 @@ export class CoreUtils { return value; } + /** + * helper method to trim strings (IE8 does not implement String.prototype.trim) + */ + public static strTrim(str: any): string { + if (!CoreUtils.isString(str)) { + return str; + } + + return str.replace(/^\s+|\s+$/g, ""); + } + /** * Creates an object that has the specified prototype, and that optionally contains specified properties. This helper exists to avoid adding a polyfil * for older browsers that do not define Object.create eg. ES3 only, IE8 just in case any page checks for presence/absence of the prototype implementation. diff --git a/tools/rollup-es3/src/es3/Es3Tokens.ts b/tools/rollup-es3/src/es3/Es3Tokens.ts index 6b4bfe2a1..8f8926326 100644 --- a/tools/rollup-es3/src/es3/Es3Tokens.ts +++ b/tools/rollup-es3/src/es3/Es3Tokens.ts @@ -153,11 +153,11 @@ export const defaultEs3CheckTokens:IEs3CheckKeyword[] = [ ] }, { - funcNames: [ /([\w0-9]*)\.toISOString[\s]*\(/g ], + funcNames: [ /([\w0-9\$]*)\.toISOString[\s]*\(/g ], errorMsg: "[%funcName%] is not supported in an ES3 environment, use CoreUtils.toISOString()", ignoreFuncMatch: [ - "CoreUtils.toISOString", // Make sure this isn't a reference to CoreUtils.isISOString() - "Utils.toISOString" // or if it's a reference to Utils.isISOString() + /CoreUtils(\$[\d]+)+\.toISOString/, // Make sure this isn't a reference to CoreUtils.isISOString(); CoreUtils$1.isISOString(); + "Utils.toISOString" // or if it's a reference to Utils.isISOString() ] }, { @@ -190,6 +190,14 @@ export const defaultEs3CheckTokens:IEs3CheckKeyword[] = [ { funcNames: [ /[\s\(,][gs]et[\s]+([\w]+)[\s]*\(\)[\s]*\{/g ], errorMsg: "[%funcName%] is not supported in an ES3 environment." + }, + { + funcNames: [ /([\w0-9]*)\.(trim)[\s]*\(/g ], + errorMsg: "[%funcName%] is not a supported string method in an ES3 environment, use CoreUtils.strTrim().", + ignoreFuncMatch: [ + "Util.trim", // Make sure this isn't a reference to Util.trim() + "DataSanitizer.trim" // Make sure this isn't a reference to Util.trim() + ] } ]; diff --git a/tools/rollup-es3/src/es3/Interfaces.ts b/tools/rollup-es3/src/es3/Interfaces.ts index 88fc0b7e2..b69816fca 100644 --- a/tools/rollup-es3/src/es3/Interfaces.ts +++ b/tools/rollup-es3/src/es3/Interfaces.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** - * Because of the test infrastructure (PhamtonJS) the RegEx can't use the "s" flag (gis vs gi) or named groups + * Because of the test infrastructure (PhantomJS) the RegEx can't use the "s" flag (gis vs gi) or named groups */ export interface INamedGroups { name: string, @@ -35,7 +35,7 @@ export interface IEs3CheckKeyword { * A Set of strings to use for matching funcNames to ignore, this is required because of infra (build) issues * with negative lookbehind, internally this uses indexOf() to provide a partial existence check. */ - ignoreFuncMatch?:string[], + ignoreFuncMatch?:Array, /** * The prefix added to any reported error, defaults to "Invalid ES3 function" diff --git a/tools/rollup-es3/src/es3/Utils.ts b/tools/rollup-es3/src/es3/Utils.ts index 2a87b2cbd..043cb6187 100644 --- a/tools/rollup-es3/src/es3/Utils.ts +++ b/tools/rollup-es3/src/es3/Utils.ts @@ -57,12 +57,20 @@ export function isIgnore(id:string, keyword:IEs3CheckKeyword, isTransform:boolea export function isIgnoreFuncMatch(funcMatch:string, keyword:IEs3CheckKeyword) { let result = false; - if (keyword.ignoreFuncMatch) { + if (funcMatch && keyword.ignoreFuncMatch) { for (let ignoreIdx in keyword.ignoreFuncMatch) { let ignoreMatch = keyword.ignoreFuncMatch[ignoreIdx]; - if (funcMatch && funcMatch.indexOf(ignoreMatch) !== -1) { - result = true; - break; + if (ignoreMatch) { + if (typeof ignoreMatch === "string" && funcMatch.indexOf(ignoreMatch) !== -1) { + result = true; + break; + } else if (ignoreMatch instanceof RegExp) { + let match = ignoreMatch.exec(funcMatch); + if (match && match.length > 0) { + result = true; + break; + } + } } } }