Просмотр исходного кода

Add CancellationToken overloads for reading multipart form sections (#41533)

Martin Costello 3 лет назад
Родитель
Сommit
0fce1c53a0

+ 5 - 14
src/Http/Http/src/Features/FormFeature.cs

@@ -25,10 +25,7 @@ public class FormFeature : IFormFeature
     /// <param name="form">The <see cref="IFormCollection"/> to use as the backing store.</param>
     public FormFeature(IFormCollection form)
     {
-        if (form == null)
-        {
-            throw new ArgumentNullException(nameof(form));
-        }
+        ArgumentNullException.ThrowIfNull(form);
 
         Form = form;
         _request = default!;
@@ -51,14 +48,8 @@ public class FormFeature : IFormFeature
     /// <param name="options">The <see cref="FormOptions"/>.</param>
     public FormFeature(HttpRequest request, FormOptions options)
     {
-        if (request == null)
-        {
-            throw new ArgumentNullException(nameof(request));
-        }
-        if (options == null)
-        {
-            throw new ArgumentNullException(nameof(options));
-        }
+        ArgumentNullException.ThrowIfNull(request);
+        ArgumentNullException.ThrowIfNull(options);
 
         _request = request;
         _options = options;
@@ -68,7 +59,7 @@ public class FormFeature : IFormFeature
     {
         get
         {
-            MediaTypeHeaderValue.TryParse(_request.ContentType, out var mt);
+            _ = MediaTypeHeaderValue.TryParse(_request.ContentType, out var mt);
             return mt;
         }
     }
@@ -247,7 +238,7 @@ public class FormFeature : IFormFeature
 
                         // Do not limit the key name length here because the multipart headers length limit is already in effect.
                         var key = formDataSection.Name;
-                        var value = await formDataSection.GetValueAsync();
+                        var value = await formDataSection.GetValueAsync(cancellationToken);
 
                         formAccumulator.Append(key, value);
                     }

+ 9 - 4
src/Http/WebUtilities/src/FormMultipartSection.cs

@@ -53,8 +53,13 @@ public class FormMultipartSection
     /// Gets the form value
     /// </summary>
     /// <returns>The form value</returns>
-    public Task<string> GetValueAsync()
-    {
-        return Section.ReadAsStringAsync();
-    }
+    public Task<string> GetValueAsync() => Section.ReadAsStringAsync();
+
+    /// <summary>
+    /// Gets the form value
+    /// </summary>
+    /// <param name="cancellationToken">The cancellation token.</param>
+    /// <returns>The form value</returns>
+    public ValueTask<string> GetValueAsync(CancellationToken cancellationToken)
+        => Section.ReadAsStringAsync(cancellationToken);
 }

+ 15 - 11
src/Http/WebUtilities/src/MultipartSectionStreamExtensions.cs

@@ -16,19 +16,25 @@ public static class MultipartSectionStreamExtensions
     /// </summary>
     /// <param name="section">The section to read from</param>
     /// <returns>The body steam as string</returns>
-    public static async Task<string> ReadAsStringAsync(this MultipartSection section)
+    public static Task<string> ReadAsStringAsync(this MultipartSection section)
+        => section.ReadAsStringAsync(CancellationToken.None).AsTask();
+
+    /// <summary>
+    /// Reads the body of the section as a string
+    /// </summary>
+    /// <param name="section">The section to read from</param>
+    /// <param name="cancellationToken">The cancellationt token.</param>
+    /// <returns>The body steam as string</returns>
+    public static async ValueTask<string> ReadAsStringAsync(this MultipartSection section, CancellationToken cancellationToken)
     {
-        if (section == null)
-        {
-            throw new ArgumentNullException(nameof(section));
-        }
+        ArgumentNullException.ThrowIfNull(section);
 
         if (section.Body is null)
         {
             throw new ArgumentException("Multipart section must have a body to be read.", nameof(section));
         }
 
-        MediaTypeHeaderValue.TryParse(section.ContentType, out var sectionMediaType);
+        _ = MediaTypeHeaderValue.TryParse(section.ContentType, out var sectionMediaType);
 
         var streamEncoding = sectionMediaType?.Encoding;
         // https://docs.microsoft.com/en-us/dotnet/core/compatibility/syslib-warnings/syslib0001
@@ -37,14 +43,12 @@ public static class MultipartSectionStreamExtensions
             streamEncoding = Encoding.UTF8;
         }
 
-        using (var reader = new StreamReader(
+        using var reader = new StreamReader(
             section.Body,
             streamEncoding,
             detectEncodingFromByteOrderMarks: true,
             bufferSize: 1024,
-            leaveOpen: true))
-        {
-            return await reader.ReadToEndAsync();
-        }
+            leaveOpen: true);
+        return await reader.ReadToEndAsync(cancellationToken);
     }
 }

+ 2 - 0
src/Http/WebUtilities/src/PublicAPI.Unshipped.txt

@@ -1,7 +1,9 @@
 #nullable enable
+Microsoft.AspNetCore.WebUtilities.FormMultipartSection.GetValueAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<string!>
 override Microsoft.AspNetCore.WebUtilities.BufferedReadStream.WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
 override Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
 override Microsoft.AspNetCore.WebUtilities.FileBufferingWriteStream.ReadAsync(System.Memory<byte> buffer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int>
 override Microsoft.AspNetCore.WebUtilities.HttpResponseStreamWriter.WriteLineAsync(char value) -> System.Threading.Tasks.Task!
 override Microsoft.AspNetCore.WebUtilities.HttpResponseStreamWriter.WriteLineAsync(char[]! values, int index, int count) -> System.Threading.Tasks.Task!
 override Microsoft.AspNetCore.WebUtilities.HttpResponseStreamWriter.WriteLineAsync(string? value) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.WebUtilities.MultipartSectionStreamExtensions.ReadAsStringAsync(this Microsoft.AspNetCore.WebUtilities.MultipartSection! section, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<string!>