Skip to content

Buffer writes from sources of synchronous writes #9015

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ public BindingAddress() { }
}
public static partial class BufferingHelper
{
public static string TempDirectory { get { throw null; } }
public static Microsoft.AspNetCore.Http.HttpRequest EnableRewind(this Microsoft.AspNetCore.Http.HttpRequest request, int bufferThreshold = 30720, long? bufferLimit = default(long?)) { throw null; }
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; }
}
Expand Down
35 changes: 4 additions & 31 deletions src/Http/Http/src/Internal/BufferingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.WebUtilities;

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

private readonly static Func<string> _getTempDirectory = () => TempDirectory;

private static string _tempDirectory;

public static string TempDirectory
{
get
{
if (_tempDirectory == null)
{
// Look for folders in the following order.
var temp = Environment.GetEnvironmentVariable("ASPNETCORE_TEMP") ?? // ASPNETCORE_TEMP - User set temporary location.
Path.GetTempPath(); // Fall back.

if (!Directory.Exists(temp))
{
// TODO: ???
throw new DirectoryNotFoundException(temp);
}

_tempDirectory = temp;
}

return _tempDirectory;
}
}

public static HttpRequest EnableRewind(this HttpRequest request, int bufferThreshold = DefaultBufferThreshold, long? bufferLimit = null)
{
if (request == null)
Expand All @@ -48,7 +21,7 @@ public static HttpRequest EnableRewind(this HttpRequest request, int bufferThres
var body = request.Body;
if (!body.CanSeek)
{
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, _getTempDirectory);
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, AspNetCoreTempDirectory.TempDirectoryFactory);
request.Body = fileStream;
request.HttpContext.Response.RegisterForDispose(fileStream);
}
Expand All @@ -70,11 +43,11 @@ public static MultipartSection EnableRewind(this MultipartSection section, Actio
var body = section.Body;
if (!body.CanSeek)
{
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, _getTempDirectory);
var fileStream = new FileBufferingReadStream(body, bufferThreshold, bufferLimit, AspNetCoreTempDirectory.TempDirectoryFactory);
section.Body = fileStream;
registerForDispose(fileStream);
}
return section;
}
}
}
}
1 change: 1 addition & 0 deletions src/Http/Http/src/Microsoft.AspNetCore.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<ItemGroup>
<Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" />
<Compile Include="$(SharedSourceRoot)ValueTaskExtensions\**\*.cs" />
<Compile Include="..\..\WebUtilities\src\AspNetCoreTempDirectory.cs" LinkBase="Internal" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
}
public sealed partial class FileBufferingWriteStream : System.IO.Stream
{
public FileBufferingWriteStream(int memoryThreshold = 32768, long? bufferLimit = default(long?), System.Func<string> tempFileDirectoryAccessor = null) { }
public override bool CanRead { get { throw null; } }
public override bool CanSeek { get { throw null; } }
public override bool CanWrite { get { throw null; } }
public override long Length { get { throw null; } }
public override long Position { get { throw null; } set { } }
protected override void Dispose(bool disposing) { }
[System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Stream destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override void Flush() { }
public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
public override int Read(byte[] buffer, int offset, int count) { throw null; }
public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
[System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
}
public partial class FileMultipartSection
{
public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { }
Expand Down Expand Up @@ -129,6 +152,8 @@ public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding en
public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize, System.Buffers.ArrayPool<byte> bytePool, System.Buffers.ArrayPool<char> charPool) { }
public override System.Text.Encoding Encoding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
protected override void Dispose(bool disposing) { }
[System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
public override void Flush() { }
public override System.Threading.Tasks.Task FlushAsync() { throw null; }
public override void Write(char value) { }
Expand Down
37 changes: 37 additions & 0 deletions src/Http/WebUtilities/src/AspNetCoreTempDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;

namespace Microsoft.AspNetCore.Internal
{
internal static class AspNetCoreTempDirectory
{
private static string _tempDirectory;

public static string TempDirectory
{
get
{
if (_tempDirectory == null)
{
// Look for folders in the following order.
var temp = Environment.GetEnvironmentVariable("ASPNETCORE_TEMP") ?? // ASPNETCORE_TEMP - User set temporary location.
Path.GetTempPath(); // Fall back.

if (!Directory.Exists(temp))
{
throw new DirectoryNotFoundException(temp);
}

_tempDirectory = temp;
}

return _tempDirectory;
}
}

public static Func<string> TempDirectoryFactory => () => TempDirectory;
}
}
Loading