/// <summary>
        /// Canonicalizes the HTTP headers.
        /// </summary>
        /// <param name="method">The HTTP method for the request.</param>
        /// <param name="contentLength">The length of the content.</param>
        /// <param name="requestHeaders">The request headers.</param>
        /// <param name="contentHeaders">The content headers.</param>
        /// <returns>A string representation of the HTTP headers.</returns>
        private static string CanonicalizeHttpHeaders(
            HttpMethod method,
            long?contentLength,
            HttpRequestHeaders requestHeaders,
            HttpContentHeaders contentHeaders)
        {
            var headerPortion = new CanonicalizedStringBuilder();

            headerPortion.Append(method.Method.ToUpperInvariant());
            if (contentHeaders == null)
            {
                headerPortion.Append(string.Empty); // Encoding
                headerPortion.Append(string.Empty); // Language
                // We treat null content lengths as a zero because when HttpClient sends a message without a body it adds a Content-Length=0 after the signing has taken place
                headerPortion.Append(0);            // Length
                headerPortion.Append(string.Empty); // MD5
                headerPortion.Append(string.Empty); // Type
            }
            else
            {
                headerPortion.Append(contentHeaders.ContentEncoding);
                headerPortion.Append(contentHeaders.ContentLanguage);
                headerPortion.Append(contentLength == null ? "0" : ((long)contentLength).ToString(CultureInfo.InvariantCulture));
                headerPortion.Append(contentHeaders.ContentMD5 == null ? string.Empty : Convert.ToBase64String(contentHeaders.ContentMD5));
                headerPortion.Append(contentHeaders.ContentType);
            }
            headerPortion.Append(requestHeaders.Date.HasValue ? requestHeaders.Date.Value.ToString("R", CultureInfo.InvariantCulture) : null);
            headerPortion.Append(requestHeaders.IfModifiedSince);
            headerPortion.Append(requestHeaders.IfMatch);
            headerPortion.Append(requestHeaders.IfNoneMatch);
            headerPortion.Append(requestHeaders.IfUnmodifiedSince);
            headerPortion.Append(requestHeaders.Range);
            return(headerPortion.ToString());
        }
        private static string CanonicalizeResource(string path, NameValueCollection queryString, string accountName)
        {
            var canonicalizedResource = new CanonicalizedStringBuilder('/' + accountName + path);

            var queryStringParameters = from q in queryString.AllKeys.Distinct() orderby q select q;

            foreach (var key in queryStringParameters)
            {
                var parameterBuilder = new StringBuilder(key.ToLowerInvariant()).Append(':');
                foreach (var value in queryString[key])
                {
                    parameterBuilder.Append(value);
                    parameterBuilder.Append(',');
                }
                canonicalizedResource.Append(parameterBuilder.ToString().TrimEnd(','));
            }

            return(canonicalizedResource.ToString());
        }
 /// <summary>
 /// Canonicalizes the HTTP headers.
 /// </summary>
 /// <param name="method">The HTTP method for the request.</param>
 /// <param name="contentLength">The length of the content.</param>
 /// <param name="requestHeaders">The request headers.</param>
 /// <param name="contentHeaders">The content headers.</param>
 /// <returns>A string representation of the HTTP headers.</returns>
 private static string CanonicalizeHttpHeaders(
     HttpMethod method,
     long? contentLength,
     HttpRequestHeaders requestHeaders,
     HttpContentHeaders contentHeaders)
 {
     var headerPortion = new CanonicalizedStringBuilder();
     headerPortion.Append(method.Method.ToUpperInvariant());
     if (contentHeaders == null)
     {
         headerPortion.Append(string.Empty); // Encoding
         headerPortion.Append(string.Empty); // Language
         // We treat null content lengths as a zero because when HttpClient sends a message without a body it adds a Content-Length=0 after the signing has taken place
         headerPortion.Append(0); // Length
         headerPortion.Append(string.Empty); // MD5
         headerPortion.Append(string.Empty); // Type
     }
     else
     {
         headerPortion.Append(contentHeaders.ContentEncoding);
         headerPortion.Append(contentHeaders.ContentLanguage);
         headerPortion.Append(contentLength == null ? "0" : ((long)contentLength).ToString(CultureInfo.InvariantCulture));
         headerPortion.Append(contentHeaders.ContentMD5 == null ? string.Empty : Convert.ToBase64String(contentHeaders.ContentMD5));
         headerPortion.Append(contentHeaders.ContentType);
     }
     headerPortion.Append(requestHeaders.Date.HasValue ? requestHeaders.Date.Value.ToString("R", CultureInfo.InvariantCulture) : null);
     headerPortion.Append(requestHeaders.IfModifiedSince);
     headerPortion.Append(requestHeaders.IfMatch);
     headerPortion.Append(requestHeaders.IfNoneMatch);
     headerPortion.Append(requestHeaders.IfUnmodifiedSince);
     headerPortion.Append(requestHeaders.Range);
     return headerPortion.ToString();
 }
        private static string CanonicalizeResource(string path, NameValueCollection queryString, string accountName)
        {
            var canonicalizedResource = new CanonicalizedStringBuilder('/' + accountName + path);

            var queryStringParameters = from q in queryString.AllKeys.Distinct() orderby q select q;
            foreach (var key in queryStringParameters)
            {
                var parameterBuilder = new StringBuilder(key.ToLowerInvariant()).Append(':');
                foreach (var value in queryString[key])
                {
                    parameterBuilder.Append(value);
                    parameterBuilder.Append(',');
                }
                canonicalizedResource.Append(parameterBuilder.ToString().TrimEnd(','));
            }

            return canonicalizedResource.ToString();
        }