Skip to content
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

Buffer writes from sources of synchronous writes #9015

Merged
merged 7 commits into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from 4 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 { } }
public override void CopyTo(System.IO.Stream destination, int bufferSize) { }
[System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) { 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 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.
pranavkm marked this conversation as resolved.
Show resolved Hide resolved
Path.GetTempPath(); // Fall back.

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

_tempDirectory = temp;
}

return _tempDirectory;
}
}

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