public void TokenizeRequestPathTests() { AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("a/bb/ccc/dddd"), "a", "bb", "ccc", "dddd"); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd"), "a", "bb", "ccc", "dddd"); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd/"), "a", "bb", "ccc", "dddd", string.Empty); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd?ee"), "a", "bb", "ccc", "dddd"); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd/?ee"), "a", "bb", "ccc", "dddd", string.Empty); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd#ee"), "a", "bb", "ccc", "dddd"); AssertAreDeepEqual(HttpParsingHelper.TokenizeRequestPath("/a/bb/ccc/dddd?ee/ff"), "a", "bb", "ccc", "dddd"); }
/// <summary> /// Tries parsing given dependency telemetry item. /// </summary> /// <param name="httpDependency">Dependency item to parse. It is expected to be of HTTP type.</param> /// <returns><code>true</code> if successfully parsed dependency.</returns> internal static bool TryParse(ref DependencyTelemetry httpDependency) { string name = httpDependency.Name; string host = httpDependency.Target; string url = httpDependency.Data; if (name == null || host == null || url == null) { return(false); } if (!HttpParsingHelper.EndsWithAny(host, AzureTableHostSuffixes)) { return(false); } //// //// Table Service REST API: https://msdn.microsoft.com/en-us/library/azure/dd179363.aspx //// string account = host.Substring(0, host.IndexOf('.')); string verb; string nameWithoutVerb; // try to parse out the verb HttpParsingHelper.ExtractVerb(name, out verb, out nameWithoutVerb, AzureTableSupportedVerbs); List <string> pathTokens = HttpParsingHelper.TokenizeRequestPath(nameWithoutVerb); string tableName = pathTokens.Count > 0 ? pathTokens[0] : string.Empty; int idx = tableName.IndexOf('('); if (idx >= 0) { tableName = tableName.Substring(0, idx); } httpDependency.Type = RemoteDependencyConstants.AzureTable; httpDependency.Name = string.IsNullOrEmpty(verb) ? account + '/' + tableName : verb + " " + account + '/' + tableName; return(true); }
internal static List <KeyValuePair <string, string> > ParseResourcePath(string requestPath) { if (!requestPath.Contains("(")) { return(HttpParsingHelper.ParseResourcePath(requestPath)); } // Parse OData v4 url format List <string> tokens = HttpParsingHelper.TokenizeRequestPath(requestPath); int pairCount = tokens.Count + 1; var results = new List <KeyValuePair <string, string> >(pairCount); for (int i = 0; i < tokens.Count; i++) { var current = tokens[i]; var valueStart = current.IndexOf('('); var valueEnd = current.IndexOf(')'); if (valueStart == -1) { var next = tokens.Count < (i + 1) ? tokens[++i] : null; results.Add(new KeyValuePair <string, string>(current, next)); } else { var key = current.Substring(0, valueStart); var value = current.Substring(valueStart + 2, valueEnd - valueStart - 3); results.Add(new KeyValuePair <string, string>(key, value)); } } return(results); }
/// <summary> /// Tries parsing given dependency telemetry item. /// </summary> /// <param name="httpDependency">Dependency item to parse. It is expected to be of HTTP type.</param> /// <returns><code>true</code> if successfully parsed dependency.</returns> internal static bool TryParse(ref DependencyTelemetry httpDependency) { string name = httpDependency.Name; string host = httpDependency.Target; string url = httpDependency.Data; if (name == null || host == null || url == null) { return(false); } if (!HttpParsingHelper.EndsWithAny(host, AzureBlobHostSuffixes)) { return(false); } //// //// Blob Service REST API: https://msdn.microsoft.com/en-us/library/azure/dd135733.aspx //// string account = host.Substring(0, host.IndexOf('.')); string verb; string nameWithoutVerb; // try to parse out the verb HttpParsingHelper.ExtractVerb(name, out verb, out nameWithoutVerb, AzureBlobSupportedVerbs); List <string> pathTokens = HttpParsingHelper.TokenizeRequestPath(nameWithoutVerb); string container = null; string blob = null; if (pathTokens.Count == 1) { container = pathTokens[0]; } else if (pathTokens.Count > 1) { Dictionary <string, string> queryParameters = HttpParsingHelper.ExtractQuryParameters(url); string resType; if (queryParameters == null || !queryParameters.TryGetValue("restype", out resType) || !string.Equals(resType, "container", StringComparison.OrdinalIgnoreCase)) { // if restype != container then the last path entry is blob name blob = pathTokens[pathTokens.Count - 1]; httpDependency.Properties["Blob"] = blob; pathTokens.RemoveAt(pathTokens.Count - 1); } container = string.Join("/", pathTokens); } if (container != null) { httpDependency.Properties["Container"] = container; } // This is very naive overwriting of Azure Blob dependency that is compatible with the today's implementation // // Possible improvements: // // 1. Use specific name for specific operations. Like "Lease Blob" for "?comp=lease" query parameter // 2. Use account name as a target instead of "account.blob.core.windows.net" httpDependency.Type = RemoteDependencyConstants.AzureBlob; httpDependency.Name = string.IsNullOrEmpty(verb) ? account : verb + " " + account; return(true); }