diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
index 5329239167..699081e659 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
@@ -17,25 +17,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
///
/// Reads data from the Input pipe to the user.
///
- ///
- ///
- ///
+ ///
///
///
- public async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ internal async Task ReadAsync(Memory 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(buffer, offset, count);
-
StartProcessingRequestAndResponseBody();
while (true)
@@ -46,7 +32,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
if (!readableBuffer.IsEmpty)
{
- var actual = Math.Min(readableBuffer.Length, count);
+ var actual = Math.Min(readableBuffer.Length, memory.Length);
readableBuffer = readableBuffer.Slice(0, actual);
readableBuffer.CopyTo(memory.Span);
return (int)actual;
@@ -69,7 +55,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
///
///
///
- public Task WriteAsync(ReadOnlyMemory memory, CancellationToken cancellationToken = default(CancellationToken))
+ internal Task WriteAsync(ReadOnlyMemory memory, CancellationToken cancellationToken = default(CancellationToken))
{
// Want to keep exceptions consistent,
@@ -90,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
///
///
///
- public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
+ internal Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (!_hasResponseStarted)
{
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
index 7690e8450c..32afb07033 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
@@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_reasonPhrase = value;
}
}
-
+
internal IISHttpServer Server
{
get { return _server; }
@@ -333,10 +333,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
// Verifies we have sent the statuscode before writing a header
var reasonPhrase = string.IsNullOrEmpty(ReasonPhrase) ? ReasonPhrases.GetReasonPhrase(StatusCode) : ReasonPhrase;
-
+
// This copies data into the underlying buffer
NativeMethods.http_set_response_status_code(_pInProcessHandler, (ushort)StatusCode, reasonPhrase);
-
+
HttpResponseHeaders.IsReadOnly = true;
foreach (var headerPair in HttpResponseHeaders)
{
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpRequestBody.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpRequestBody.cs
index 0a51d9fc7a..be5746c0d3 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpRequestBody.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpRequestBody.cs
@@ -39,7 +39,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
public override unsafe Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
- return _httpContext.ReadAsync(buffer, offset, count, cancellationToken);
+ var memory = new Memory(buffer, offset, count);
+
+ return _httpContext.ReadAsync(memory, cancellationToken);
}
public override long Seek(long offset, SeekOrigin origin)
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpResponseBody.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpResponseBody.cs
index 38c8e64c2a..f850994a4a 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpResponseBody.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpResponseBody.cs
@@ -54,11 +54,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
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(buffer, offset, count), cancellationToken);
}
diff --git a/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs b/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs
index 524bc2931f..95c05308bd 100644
--- a/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs
+++ b/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs
@@ -26,13 +26,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
[ConditionalTheory]
- [InlineData("/NullBuffer")]
[InlineData("/InvalidOffsetSmall")]
[InlineData("/InvalidOffsetLarge")]
[InlineData("/InvalidCountSmall")]
[InlineData("/InvalidCountLarge")]
[InlineData("/InvalidCountWithOffset")]
- [InlineData("/InvalidCountZeroRead")]
public async Task TestInvalidReadOperations(string operation)
{
var result = await _fixture.Client.GetStringAsync($"/TestInvalidReadOperations{operation}");
@@ -41,6 +39,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
[ConditionalTheory]
[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("/InvalidOffsetLarge")]
[InlineData("/InvalidCountSmall")]
@@ -51,5 +66,19 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var result = await _fixture.Client.GetStringAsync($"/TestInvalidWriteOperations{operation}");
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());
+ }
}
}
diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs b/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs
index 6b9e561e40..47ca0dc808 100644
--- a/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs
+++ b/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs
@@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Equal("1", headerValues.First());
Assert.Equal("2", headerValues.Last());
}
-
+
[ConditionalFact]
public async Task ErrorCodeIsSetForExceptionDuringRequest()
{
diff --git a/test/IISTestSite/Startup.cs b/test/IISTestSite/Startup.cs
index 28460cdaf5..00b83e769d 100644
--- a/test/IISTestSite/Startup.cs
+++ b/test/IISTestSite/Startup.cs
@@ -470,10 +470,6 @@ namespace IISTestSite
{
await context.Request.Body.ReadAsync(null, 0, 0);
}
- catch (ArgumentNullException)
- {
- success = true;
- }
catch (Exception)
{
success = true;
@@ -534,42 +530,46 @@ namespace IISTestSite
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");
});
}
+
+ 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)
{
app.Run(async context =>
{
var success = false;
- if (context.Request.Path.StartsWithSegments("/NullBuffer"))
- {
- try
- {
- await context.Response.Body.WriteAsync(null, 0, 0);
- }
- catch (ArgumentNullException)
- {
- success = true;
- }
- }
- else if (context.Request.Path.StartsWithSegments("/InvalidOffsetSmall"))
+
+ if (context.Request.Path.StartsWithSegments("/InvalidOffsetSmall"))
{
try
{
@@ -629,6 +629,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)
{
app.Run(async ctx =>