Repository: microsoft/ApplicationInsights-node.js (ts)

Issue:
Wrong target reported when using AutoDependencyTracking and HTTP_PROXY environment variable
On our environment we're using request library together with HTTP_PROXY setting. All dependency requests that go through proxy have target of 443 (this are https requests).

As I've debugged through the code, it looks like [HttpDependencyParser.getDependencyTelemetry](https://github.com/microsoft/ApplicationInsights-node.js/blob/6a772adb58dcd1a1e5577dfb071efa7414326db2/AutoCollection/HttpDependencyParser.ts#L49) gets the url without protocol in such case. For example `host.example.com:443`. With such value, the parser treats host.example.com as protocol name, and 443 as host name. This gives useless results as `target` value and also - if we have multiple hosts - all of them are aggregated into one 443 value.

I'd like to have real host value in the target field, the same as it is in case, when no HTTP_PROXY is used.

Pull request:
RDD: Correctly parse urls without protocols
Fix issue where dependency URLs without protocol prefixes are incorrectly parsed

Fixes #689


Patch:
diff --git a/AutoCollection/HttpDependencyParser.ts b/AutoCollection/HttpDependencyParser.ts
index f9db8b2..49f4fac 100644
--- a/AutoCollection/HttpDependencyParser.ts
+++ b/AutoCollection/HttpDependencyParser.ts
@@ -114,7 +114,18 @@ class HttpDependencyParser extends RequestParser {
      */
     private static _getUrlFromRequestOptions(options: any, request: http.ClientRequest) {
         if (typeof options === 'string') {
-            options = url.parse(options);
+            if (options.indexOf("http://") === 0 || options.indexOf("https://") === 0) {
+                // protocol exists, parse normally
+                options = url.parse(options);
+            } else {
+                // protocol not found, insert http/https where appropriate
+                const parsed = url.parse(options);
+                if (parsed.host === "443") {
+                    options = url.parse("https://" + options);
+                } else {
+                    options = url.parse("http://" + options)
+                }
+            }
         } else if (options && typeof (url as any).URL === 'function' && options instanceof (url as any).URL) {
             return url.format(options);
         } else {


Test patch:
diff --git a/Tests/AutoCollection/HttpDependencyParser.tests.ts b/Tests/AutoCollection/HttpDependencyParser.tests.ts
index 7c02d48..3f24b04 100644
--- a/Tests/AutoCollection/HttpDependencyParser.tests.ts
+++ b/Tests/AutoCollection/HttpDependencyParser.tests.ts
@@ -44,6 +44,36 @@ describe("AutoCollection/HttpDependencyParser", () => {
             assert.equal(dependencyTelemetry.data, "http://bing.com:123/search");
             assert.equal(dependencyTelemetry.target, "bing.com:123 | abcdefg");
         });
+        
+        it("should return correct data for a URL without a protocol (https)", () => {
+            (<any>request)["method"] = "GET";
+            let parser = new HttpDependencyParser("a.bing.com:443/search", request);
+
+            response.statusCode = 200;
+            parser.onResponse(response);
+
+            let dependencyTelemetry = parser.getDependencyTelemetry();
+            assert.equal(dependencyTelemetry.dependencyTypeName, Contracts.RemoteDependencyDataConstants.TYPE_HTTP);
+            assert.equal(dependencyTelemetry.success, true);
+            assert.equal(dependencyTelemetry.name, "GET /search");
+            assert.equal(dependencyTelemetry.data, "https://a.bing.com:443/search");
+            assert.equal(dependencyTelemetry.target, "a.bing.com:443");
+        });
+        
+        it("should return correct data for a URL without a protocol (http)", () => {
+            (<any>request)["method"] = "GET";
+            let parser = new HttpDependencyParser("a.bing.com:123/search", request);
+
+            response.statusCode = 200;
+            parser.onResponse(response);
+
+            let dependencyTelemetry = parser.getDependencyTelemetry();
+            assert.equal(dependencyTelemetry.dependencyTypeName, Contracts.RemoteDependencyDataConstants.TYPE_HTTP);
+            assert.equal(dependencyTelemetry.success, true);
+            assert.equal(dependencyTelemetry.name, "GET /search");
+            assert.equal(dependencyTelemetry.data, "http://a.bing.com:123/search");
+            assert.equal(dependencyTelemetry.target, "a.bing.com:123");
+        });
 
         if (parseInt(process.versions.node.split(".")[0]) >= 10) {
             it("should return correct data for a URL instance", () => {