Cleanup ReadAsync calls, make IISHttpContext private (#696)
This commit is contained in:
parent
af96c91584
commit
f1058f8575
|
|
@ -17,25 +17,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads data from the Input pipe to the user.
|
/// Reads data from the Input pipe to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer"></param>
|
/// <param name="memory"></param>
|
||||||
/// <param name="offset"></param>
|
|
||||||
/// <param name="count"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
internal async Task<int> ReadAsync(Memory<byte> memory, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Start a task which will continuously call ReadFromIISAsync and WriteToIISAsync
|
|
||||||
if (buffer == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(buffer));
|
|
||||||
}
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
var memory = new Memory<byte>(buffer, offset, count);
|
|
||||||
|
|
||||||
StartProcessingRequestAndResponseBody();
|
StartProcessingRequestAndResponseBody();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
|
@ -46,7 +32,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
{
|
{
|
||||||
if (!readableBuffer.IsEmpty)
|
if (!readableBuffer.IsEmpty)
|
||||||
{
|
{
|
||||||
var actual = Math.Min(readableBuffer.Length, count);
|
var actual = Math.Min(readableBuffer.Length, memory.Length);
|
||||||
readableBuffer = readableBuffer.Slice(0, actual);
|
readableBuffer = readableBuffer.Slice(0, actual);
|
||||||
readableBuffer.CopyTo(memory.Span);
|
readableBuffer.CopyTo(memory.Span);
|
||||||
return (int)actual;
|
return (int)actual;
|
||||||
|
|
@ -69,7 +55,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
/// <param name="memory"></param>
|
/// <param name="memory"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task WriteAsync(ReadOnlyMemory<byte> memory, CancellationToken cancellationToken = default(CancellationToken))
|
internal Task WriteAsync(ReadOnlyMemory<byte> memory, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
|
|
||||||
// Want to keep exceptions consistent,
|
// Want to keep exceptions consistent,
|
||||||
|
|
@ -90,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
|
internal Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
if (!_hasResponseStarted)
|
if (!_hasResponseStarted)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
|
|
||||||
public override unsafe Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
public override unsafe Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return _httpContext.ReadAsync(buffer, offset, count, cancellationToken);
|
var memory = new Memory<byte>(buffer, offset, count);
|
||||||
|
|
||||||
|
return _httpContext.ReadAsync(memory, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override long Seek(long offset, SeekOrigin origin)
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||||
|
|
||||||
public override unsafe Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
public override unsafe Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (buffer == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
return _httpContext.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken);
|
return _httpContext.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
[InlineData("/NullBuffer")]
|
|
||||||
[InlineData("/InvalidOffsetSmall")]
|
[InlineData("/InvalidOffsetSmall")]
|
||||||
[InlineData("/InvalidOffsetLarge")]
|
[InlineData("/InvalidOffsetLarge")]
|
||||||
[InlineData("/InvalidCountSmall")]
|
[InlineData("/InvalidCountSmall")]
|
||||||
[InlineData("/InvalidCountLarge")]
|
[InlineData("/InvalidCountLarge")]
|
||||||
[InlineData("/InvalidCountWithOffset")]
|
[InlineData("/InvalidCountWithOffset")]
|
||||||
[InlineData("/InvalidCountZeroRead")]
|
|
||||||
public async Task TestInvalidReadOperations(string operation)
|
public async Task TestInvalidReadOperations(string operation)
|
||||||
{
|
{
|
||||||
var result = await _fixture.Client.GetStringAsync($"/TestInvalidReadOperations{operation}");
|
var result = await _fixture.Client.GetStringAsync($"/TestInvalidReadOperations{operation}");
|
||||||
|
|
@ -41,6 +39,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
[InlineData("/NullBuffer")]
|
[InlineData("/NullBuffer")]
|
||||||
|
[InlineData("/InvalidCountZeroRead")]
|
||||||
|
public async Task TestValidReadOperations(string operation)
|
||||||
|
{
|
||||||
|
var result = await _fixture.Client.GetStringAsync($"/TestValidReadOperations{operation}");
|
||||||
|
Assert.Equal("Success", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[InlineData("/NullBufferPost")]
|
||||||
|
[InlineData("/InvalidCountZeroReadPost")]
|
||||||
|
public async Task TestValidReadOperationsPost(string operation)
|
||||||
|
{
|
||||||
|
var result = await _fixture.Client.PostAsync($"/TestValidReadOperations{operation}", new StringContent("hello"));
|
||||||
|
Assert.Equal("Success", await result.Content.ReadAsStringAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
[InlineData("/InvalidOffsetSmall")]
|
[InlineData("/InvalidOffsetSmall")]
|
||||||
[InlineData("/InvalidOffsetLarge")]
|
[InlineData("/InvalidOffsetLarge")]
|
||||||
[InlineData("/InvalidCountSmall")]
|
[InlineData("/InvalidCountSmall")]
|
||||||
|
|
@ -51,5 +66,19 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
var result = await _fixture.Client.GetStringAsync($"/TestInvalidWriteOperations{operation}");
|
var result = await _fixture.Client.GetStringAsync($"/TestInvalidWriteOperations{operation}");
|
||||||
Assert.Equal("Success", result);
|
Assert.Equal("Success", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task TestValidWriteOperations()
|
||||||
|
{
|
||||||
|
var result = await _fixture.Client.GetStringAsync($"/TestValidWriteOperations/NullBuffer");
|
||||||
|
Assert.Equal("Success", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task TestValidWriteOperationsPost()
|
||||||
|
{
|
||||||
|
var result = await _fixture.Client.PostAsync($"/TestValidWriteOperations/NullBufferPost", new StringContent("hello"));
|
||||||
|
Assert.Equal("Success", await result.Content.ReadAsStringAsync());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ namespace IISTestSite
|
||||||
app.Map("/WebsocketRequest", WebsocketRequest);
|
app.Map("/WebsocketRequest", WebsocketRequest);
|
||||||
app.Map("/UpgradeFeatureDetection", UpgradeFeatureDetection);
|
app.Map("/UpgradeFeatureDetection", UpgradeFeatureDetection);
|
||||||
app.Map("/TestInvalidReadOperations", TestInvalidReadOperations);
|
app.Map("/TestInvalidReadOperations", TestInvalidReadOperations);
|
||||||
|
app.Map("/TestValidReadOperations", TestValidReadOperations);
|
||||||
app.Map("/TestInvalidWriteOperations", TestInvalidWriteOperations);
|
app.Map("/TestInvalidWriteOperations", TestInvalidWriteOperations);
|
||||||
|
app.Map("/TestValidWriteOperations", TestValidWriteOperations);
|
||||||
app.Map("/TestReadOffsetWorks", TestReadOffsetWorks);
|
app.Map("/TestReadOffsetWorks", TestReadOffsetWorks);
|
||||||
app.Map("/LargeResponseFile", LargeResponseFile);
|
app.Map("/LargeResponseFile", LargeResponseFile);
|
||||||
}
|
}
|
||||||
|
|
@ -471,10 +473,6 @@ namespace IISTestSite
|
||||||
{
|
{
|
||||||
await context.Request.Body.ReadAsync(null, 0, 0);
|
await context.Request.Body.ReadAsync(null, 0, 0);
|
||||||
}
|
}
|
||||||
catch (ArgumentNullException)
|
|
||||||
{
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
|
|
@ -535,42 +533,46 @@ namespace IISTestSite
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (context.Request.Path.StartsWithSegments("/InvalidCountZeroRead"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await context.Request.Body.ReadAsync(new byte[1], 0, 0);
|
|
||||||
}
|
|
||||||
catch (ArgumentOutOfRangeException)
|
|
||||||
{
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await context.Response.WriteAsync(success ? "Success" : "Failure");
|
await context.Response.WriteAsync(success ? "Success" : "Failure");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestValidReadOperations(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
var count = -1;
|
||||||
|
|
||||||
|
if (context.Request.Path.StartsWithSegments("/NullBuffer"))
|
||||||
|
{
|
||||||
|
count = await context.Request.Body.ReadAsync(null, 0, 0);
|
||||||
|
}
|
||||||
|
else if (context.Request.Path.StartsWithSegments("/NullBufferPost"))
|
||||||
|
{
|
||||||
|
count = await context.Request.Body.ReadAsync(null, 0, 0);
|
||||||
|
}
|
||||||
|
else if (context.Request.Path.StartsWithSegments("/InvalidCountZeroRead"))
|
||||||
|
{
|
||||||
|
count = await context.Request.Body.ReadAsync(new byte[1], 0, 0);
|
||||||
|
}
|
||||||
|
else if (context.Request.Path.StartsWithSegments("/InvalidCountZeroReadPost"))
|
||||||
|
{
|
||||||
|
count = await context.Request.Body.ReadAsync(new byte[1], 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.Response.WriteAsync(count == 0 ? "Success" : "Failure");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void TestInvalidWriteOperations(IApplicationBuilder app)
|
private void TestInvalidWriteOperations(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
if (context.Request.Path.StartsWithSegments("/NullBuffer"))
|
|
||||||
{
|
if (context.Request.Path.StartsWithSegments("/InvalidOffsetSmall"))
|
||||||
try
|
|
||||||
{
|
|
||||||
await context.Response.Body.WriteAsync(null, 0, 0);
|
|
||||||
}
|
|
||||||
catch (ArgumentNullException)
|
|
||||||
{
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (context.Request.Path.StartsWithSegments("/InvalidOffsetSmall"))
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -630,6 +632,24 @@ namespace IISTestSite
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestValidWriteOperations(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
|
||||||
|
if (context.Request.Path.StartsWithSegments("/NullBuffer"))
|
||||||
|
{
|
||||||
|
await context.Response.Body.WriteAsync(null, 0, 0);
|
||||||
|
}
|
||||||
|
else if (context.Request.Path.StartsWithSegments("/NullBufferPost"))
|
||||||
|
{
|
||||||
|
await context.Response.Body.WriteAsync(null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Success");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void LargeResponseFile(IApplicationBuilder app)
|
private void LargeResponseFile(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
app.Run(async ctx =>
|
app.Run(async ctx =>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue