internal static void AddHeaders(this SortedDictionary <string, string> canonicalized, IReadOnlyDictionary <string, IReadOnlyCollection <string> > headersToAdd) { if (headersToAdd == null) { return; } foreach (var pair in headersToAdd) { if (pair.Value == null) { continue; } var headerName = pair.Key.ToLowerInvariant(); // Note: the comma-space separating here is because this is what HttpClient does. // Google Cloud Storage itself will just use commas if it receives multiple values for the same header name, // but HttpClient coalesces the values itself. This approach means that if the same request is made from .NET // with the signed URL, it will succeed - but it does mean that the signed URL won't be valid when used from // another platform that sends actual multiple values. var value = string.Join(", ", pair.Value.Select(v => UrlSigner.PrepareHeaderValue(v, true))).Trim(); if (canonicalized.TryGetValue(headerName, out var existingValue)) { value = $"{existingValue}, {value}"; } canonicalized[headerName] = value; } }
internal static void AddHeader(this SortedDictionary <string, string> canonicalized, string key, string value) { if (key == null || value == null) { return; } var headerName = key.ToLowerInvariant(); // Note: the comma-space separating here is because this is what HttpClient does. // Google Cloud Storage itself will just use commas if it receives multiple values for the same header name, // but HttpClient coalesces the values itself. This approach means that if the same request is made from .NET // with the signed URL, it will succeed - but it does mean that the signed URL won't be valid when used from // another platform that sends actual multiple values. var headerValue = UrlSigner.PrepareHeaderValue(value, true).Trim(); if (canonicalized.TryGetValue(headerName, out var existingValue)) { headerValue = $"{existingValue}, {headerValue}"; } canonicalized[headerName] = headerValue; }
/// <summary> /// Creates a new <see cref="UrlSigner"/> instance for a service account. /// </summary> /// <param name="credentialData">The stream from which to read the JSON key data for a service account. Must not be null.</param> /// <exception cref="InvalidOperationException"> /// The <paramref name="credentialData"/> does not contain valid JSON service account key data. /// </exception> public static UrlSigner FromServiceAccountData(Stream credentialData) { GaxPreconditions.CheckNotNull(credentialData, nameof(credentialData)); return(UrlSigner.FromServiceAccountCredential(ServiceAccountCredential.FromServiceAccountData(credentialData))); }