Skip to content

Commit 92cae6f

Browse files
authored
Buffer writes from sources of synchronous writes (#9015)
* Buffer writes from sources of synchronous writes Fixes #6397
1 parent e4328b2 commit 92cae6f

37 files changed

+1364
-188
lines changed

src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp3.0.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ public BindingAddress() { }
306306
}
307307
public static partial class BufferingHelper
308308
{
309-
public static string TempDirectory { get { throw null; } }
310309
public static Microsoft.AspNetCore.Http.HttpRequest EnableRewind(this Microsoft.AspNetCore.Http.HttpRequest request, int bufferThreshold = 30720, long? bufferLimit = default(long?)) { throw null; }
311310
public static Microsoft.AspNetCore.WebUtilities.MultipartSection EnableRewind(this Microsoft.AspNetCore.WebUtilities.MultipartSection section, System.Action<System.IDisposable> registerForDispose, int bufferThreshold = 30720, long? bufferLimit = default(long?)) { throw null; }
312311
}

src/Http/Http/src/Internal/BufferingHelper.cs

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.IO;
5+
using Microsoft.AspNetCore.Internal;
66
using Microsoft.AspNetCore.WebUtilities;
77

88
namespace Microsoft.AspNetCore.Http.Internal
@@ -11,33 +11,6 @@ public static class BufferingHelper
1111
{
1212
internal const int DefaultBufferThreshold = 1024 * 30;
1313

14-
private readonly static Func<string> _getTempDirectory = () => TempDirectory;
15-
16-
private static string _tempDirectory;
17-
18-
public static string TempDirectory
19-
{
20-
get
21-
{
22-
if (_tempDirectory == null)
23-
{
24-
// Look for folders in the following order.
25-
var temp = Environment.GetEnvironmentVariable("ASPNETCORE_TEMP") ?? // ASPNETCORE_TEMP - User set temporary location.
26-
Path.GetTempPath(); // Fall back.
27-
28-
if (!Directory.Exists(temp))
29-
{
30-
// TODO: ???
31-
throw new DirectoryNotFoundException(temp);
32-
}
33-
34-
_tempDirectory = temp;
35-
}
36-
37-
return _tempDirectory;
38-
}
39-
}
40-
4114
public static HttpRequest EnableRewind(this HttpRequest request, int bufferThreshold = DefaultBufferThreshold, long? bufferLimit = null)
4215
{
4316
if (request == null)
@@ -48,7 +21,7 @@ public static HttpRequest EnableRewind(this HttpRequest request, int bufferThres
4821
var body = request.Body;
4922
if (!body.CanSeek)
5023
{
51-
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, _getTempDirectory);
24+
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, AspNetCoreTempDirectory.TempDirectoryFactory);
5225
request.Body = fileStream;
5326
request.HttpContext.Response.RegisterForDispose(fileStream);
5427
}
@@ -70,11 +43,11 @@ public static MultipartSection EnableRewind(this MultipartSection section, Actio
7043
var body = section.Body;
7144
if (!body.CanSeek)
7245
{
73-
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, _getTempDirectory);
46+
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, AspNetCoreTempDirectory.TempDirectoryFactory);
7447
section.Body = fileStream;
7548
registerForDispose(fileStream);
7649
}
7750
return section;
7851
}
7952
}
80-
}
53+
}

src/Http/Http/src/Microsoft.AspNetCore.Http.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<ItemGroup>
1414
<Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" />
1515
<Compile Include="$(SharedSourceRoot)ValueTaskExtensions\**\*.cs" />
16+
<Compile Include="..\..\WebUtilities\src\AspNetCoreTempDirectory.cs" LinkBase="Internal" />
1617
</ItemGroup>
1718

1819
<ItemGroup>

src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp3.0.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,29 @@ public override void SetLength(long value) { }
6262
public override void Write(byte[] buffer, int offset, int count) { }
6363
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
6464
}
65+
public sealed partial class FileBufferingWriteStream : System.IO.Stream
66+
{
67+
public FileBufferingWriteStream(int memoryThreshold = 32768, long? bufferLimit = default(long?), System.Func<string> tempFileDirectoryAccessor = null) { }
68+
public override bool CanRead { get { throw null; } }
69+
public override bool CanSeek { get { throw null; } }
70+
public override bool CanWrite { get { throw null; } }
71+
public override long Length { get { throw null; } }
72+
public override long Position { get { throw null; } set { } }
73+
protected override void Dispose(bool disposing) { }
74+
[System.Diagnostics.DebuggerStepThroughAttribute]
75+
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
76+
[System.Diagnostics.DebuggerStepThroughAttribute]
77+
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Stream destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
78+
public override void Flush() { }
79+
public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
80+
public override int Read(byte[] buffer, int offset, int count) { throw null; }
81+
public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
82+
public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
83+
public override void SetLength(long value) { }
84+
public override void Write(byte[] buffer, int offset, int count) { }
85+
[System.Diagnostics.DebuggerStepThroughAttribute]
86+
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
87+
}
6588
public partial class FileMultipartSection
6689
{
6790
public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { }
@@ -129,6 +152,8 @@ public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding en
129152
public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize, System.Buffers.ArrayPool<byte> bytePool, System.Buffers.ArrayPool<char> charPool) { }
130153
public override System.Text.Encoding Encoding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
131154
protected override void Dispose(bool disposing) { }
155+
[System.Diagnostics.DebuggerStepThroughAttribute]
156+
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
132157
public override void Flush() { }
133158
public override System.Threading.Tasks.Task FlushAsync() { throw null; }
134159
public override void Write(char value) { }
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.IO;
6+
7+
namespace Microsoft.AspNetCore.Internal
8+
{
9+
internal static class AspNetCoreTempDirectory
10+
{
11+
private static string _tempDirectory;
12+
13+
public static string TempDirectory
14+
{
15+
get
16+
{
17+
if (_tempDirectory == null)
18+
{
19+
// Look for folders in the following order.
20+
var temp = Environment.GetEnvironmentVariable("ASPNETCORE_TEMP") ?? // ASPNETCORE_TEMP - User set temporary location.
21+
Path.GetTempPath(); // Fall back.
22+
23+
if (!Directory.Exists(temp))
24+
{
25+
throw new DirectoryNotFoundException(temp);
26+
}
27+
28+
_tempDirectory = temp;
29+
}
30+
31+
return _tempDirectory;
32+
}
33+
}
34+
35+
public static Func<string> TempDirectoryFactory => () => TempDirectory;
36+
}
37+
}

0 commit comments

Comments
 (0)