| File: BlobAppendReferenceWrapper.cs | Web Access |
| Project: src\aspnetcore\src\Logging.AzureAppServices\src\Microsoft.Extensions.Logging.AzureAppServices.csproj (Microsoft.Extensions.Logging.AzureAppServices) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace Microsoft.Extensions.Logging.AzureAppServices; /// <inheritdoc /> internal sealed class BlobAppendReferenceWrapper : ICloudAppendBlob { private readonly Uri _fullUri; private readonly HttpClient _client; private readonly Uri _appendUri; public BlobAppendReferenceWrapper(string containerUrl, string name, HttpClient client) { var uriBuilder = new UriBuilder(containerUrl); uriBuilder.Path += "/" + name; _fullUri = uriBuilder.Uri; AppendBlockQuery(uriBuilder); _appendUri = uriBuilder.Uri; _client = client; } /// <inheritdoc /> public async Task AppendAsync(ArraySegment<byte> data, CancellationToken cancellationToken) { Task<HttpResponseMessage> AppendDataAsync() { var message = new HttpRequestMessage(HttpMethod.Put, _appendUri) { Content = new ByteArrayContent(data.Array, data.Offset, data.Count) }; AddCommonHeaders(message); return _client.SendAsync(message, cancellationToken); } var response = await AppendDataAsync().ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.NotFound) { // If no blob exists try creating it var message = new HttpRequestMessage(HttpMethod.Put, _fullUri) { // Set Content-Length to 0 to create "Append Blob" Content = new ByteArrayContent(Array.Empty<byte>()), Headers = { { "If-None-Match", "*" } } }; AddCommonHeaders(message); response = await _client.SendAsync(message, cancellationToken).ConfigureAwait(false); // If result is 2** or 412 try to append again if (response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.PreconditionFailed) { // Retry sending data after blob creation response = await AppendDataAsync().ConfigureAwait(false); } } response.EnsureSuccessStatusCode(); } private static void AddCommonHeaders(HttpRequestMessage message) { message.Headers.Add("x-ms-blob-type", "AppendBlob"); message.Headers.Add("x-ms-version", "2016-05-31"); message.Headers.Date = DateTimeOffset.UtcNow; } private static void AppendBlockQuery(UriBuilder uriBuilder) { // See https://msdn.microsoft.com/en-us/library/system.uribuilder.query.aspx for: // Note: Do not append a string directly to Query property. // If the length of Query is greater than 1, retrieve the property value // as a string, remove the leading question mark, append the new query string, // and set the property with the combined string. var queryToAppend = "comp=appendblock"; if (uriBuilder.Query != null && uriBuilder.Query.Length > 1) { #if NETFRAMEWORK || NETSTANDARD uriBuilder.Query = uriBuilder.Query.Substring(1) + "&" + queryToAppend; #else uriBuilder.Query = string.Concat(uriBuilder.Query.AsSpan(1), "&", queryToAppend); #endif } else { uriBuilder.Query = queryToAppend; } } }