parent
efd765e970
commit
11ecc62ea9
|
|
@ -409,7 +409,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Task<bool> ProcessRequestAsync();
|
public abstract Task ProcessRequestAsync();
|
||||||
|
|
||||||
public void OnStarting(Func<object, Task> callback, object state)
|
public void OnStarting(Func<object, Task> callback, object state)
|
||||||
{
|
{
|
||||||
|
|
@ -599,10 +599,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
|
|
||||||
private async Task HandleRequest()
|
private async Task HandleRequest()
|
||||||
{
|
{
|
||||||
bool successfulRequest = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
successfulRequest = await ProcessRequestAsync();
|
await ProcessRequestAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -610,19 +609,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Post completion after completing the request to resume the state machine
|
|
||||||
PostCompletion(ConvertRequestCompletionResults(successfulRequest));
|
|
||||||
|
|
||||||
|
|
||||||
// Dispose the context
|
// Dispose the context
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeMethods.REQUEST_NOTIFICATION_STATUS ConvertRequestCompletionResults(bool success)
|
|
||||||
{
|
|
||||||
return success ? NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_CONTINUE
|
|
||||||
: NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,32 +21,33 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
_application = application;
|
_application = application;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<bool> ProcessRequestAsync()
|
public override async Task ProcessRequestAsync()
|
||||||
{
|
{
|
||||||
InitializeContext();
|
|
||||||
|
|
||||||
var context = default(TContext);
|
var context = default(TContext);
|
||||||
var success = true;
|
var success = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
context = _application.CreateContext(this);
|
InitializeContext();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context = _application.CreateContext(this);
|
||||||
|
|
||||||
|
await _application.ProcessRequestAsync(context);
|
||||||
|
}
|
||||||
|
catch (BadHttpRequestException ex)
|
||||||
|
{
|
||||||
|
SetBadRequestState(ex);
|
||||||
|
ReportApplicationError(ex);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportApplicationError(ex);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
await _application.ProcessRequestAsync(context);
|
|
||||||
}
|
|
||||||
catch (BadHttpRequestException ex)
|
|
||||||
{
|
|
||||||
SetBadRequestState(ex);
|
|
||||||
ReportApplicationError(ex);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ReportApplicationError(ex);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
await CompleteResponseBodyAsync();
|
await CompleteResponseBodyAsync();
|
||||||
_streams.Stop();
|
_streams.Stop();
|
||||||
|
|
||||||
|
|
@ -56,36 +57,18 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
// Dispose
|
// Dispose
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_onCompleted != null)
|
if (!_requestAborted)
|
||||||
{
|
{
|
||||||
await FireOnCompleted();
|
await ProduceEnd();
|
||||||
|
}
|
||||||
|
else if (!HasResponseStarted && _requestRejectedException == null)
|
||||||
|
{
|
||||||
|
// If the request was aborted and no response was sent, there's no
|
||||||
|
// meaningful status code to log.
|
||||||
|
StatusCode = 0;
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!_requestAborted)
|
|
||||||
{
|
|
||||||
await ProduceEnd();
|
|
||||||
}
|
|
||||||
else if (!HasResponseStarted && _requestRejectedException == null)
|
|
||||||
{
|
|
||||||
// If the request was aborted and no response was sent, there's no
|
|
||||||
// meaningful status code to log.
|
|
||||||
StatusCode = 0;
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_application.DisposeContext(context, _applicationException);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
// TODO Log this
|
|
||||||
_applicationException = _applicationException ?? ex;
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Complete response writer and request reader pipe sides
|
// Complete response writer and request reader pipe sides
|
||||||
_bodyOutput.Dispose();
|
_bodyOutput.Dispose();
|
||||||
_bodyInputPipe?.Reader.Complete();
|
_bodyInputPipe?.Reader.Complete();
|
||||||
|
|
@ -104,7 +87,36 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
await _readBodyTask;
|
await _readBodyTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return success;
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
ReportApplicationError(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// We're done with anything that touches the request or response, unblock the client.
|
||||||
|
PostCompletion(ConvertRequestCompletionResults(success));
|
||||||
|
|
||||||
|
if (_onCompleted != null)
|
||||||
|
{
|
||||||
|
await FireOnCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_application.DisposeContext(context, _applicationException);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportApplicationError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NativeMethods.REQUEST_NOTIFICATION_STATUS ConvertRequestCompletionResults(bool success)
|
||||||
|
{
|
||||||
|
return success ? NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_CONTINUE
|
||||||
|
: NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,5 +30,12 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
|
||||||
{
|
{
|
||||||
Assert.Equal(20, (await _fixture.Client.GetByteArrayAsync($"/FlushedPipeAndThenUnflushedPipe")).Length);
|
Assert.Equal(20, (await _fixture.Client.GetByteArrayAsync($"/FlushedPipeAndThenUnflushedPipe")).Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[RequiresNewHandler]
|
||||||
|
public async Task ResponseBodyTest_BodyCompletionNotBlockedByOnCompleted()
|
||||||
|
{
|
||||||
|
Assert.Equal("SlowOnCompleted", await _fixture.Client.GetStringAsync($"/SlowOnCompleted"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1016,5 +1016,12 @@ namespace TestSite
|
||||||
|
|
||||||
await context.Response.WriteAsync(httpsPort.HasValue ? httpsPort.Value.ToString() : "NOVALUE");
|
await context.Response.WriteAsync(httpsPort.HasValue ? httpsPort.Value.ToString() : "NOVALUE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task SlowOnCompleted(HttpContext context)
|
||||||
|
{
|
||||||
|
// This shouldn't block the response or the server from shutting down.
|
||||||
|
context.Response.OnCompleted(() => Task.Delay(TimeSpan.FromMinutes(5)));
|
||||||
|
await context.Response.WriteAsync("SlowOnCompleted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue