-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathHttpRequestBodyReader.cs
More file actions
52 lines (41 loc) · 1.63 KB
/
Copy pathHttpRequestBodyReader.cs
File metadata and controls
52 lines (41 loc) · 1.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System.Text;
namespace RunCommandsService;
public sealed class RequestBodyTooLargeException : IOException
{
public RequestBodyTooLargeException(int maxBytes)
: base($"Request body exceeds the configured limit of {maxBytes} bytes.")
{
MaxBytes = maxBytes;
}
public int MaxBytes { get; }
}
public sealed class UnsupportedMediaTypeException : Exception
{
public UnsupportedMediaTypeException(string message) : base(message) { }
}
/// <summary>Reads an HTTP request body without allowing unbounded memory growth.</summary>
public static class HttpRequestBodyReader
{
public static string Read(Stream input, Encoding encoding, long declaredLength, int maxBytes)
{
ArgumentNullException.ThrowIfNull(input);
ArgumentNullException.ThrowIfNull(encoding);
ArgumentOutOfRangeException.ThrowIfLessThan(maxBytes, 1);
if (declaredLength > maxBytes)
throw new RequestBodyTooLargeException(maxBytes);
using var buffer = new MemoryStream(Math.Min(maxBytes, 16 * 1024));
var chunk = new byte[Math.Min(maxBytes, 8 * 1024)];
while (true)
{
var remaining = (long)maxBytes - buffer.Length;
var requested = checked((int)Math.Min(chunk.Length, remaining + 1));
var read = input.Read(chunk, 0, requested);
if (read == 0)
break;
if (buffer.Length + read > maxBytes)
throw new RequestBodyTooLargeException(maxBytes);
buffer.Write(chunk, 0, read);
}
return encoding.GetString(buffer.GetBuffer(), 0, checked((int)buffer.Length));
}
}