Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 25b2c94

Browse files
author
Cesar Blum Silveira
committed
If request aborted and no response sent, log status code '0' when disposing context.
1 parent 579fc75 commit 25b2c94

File tree

3 files changed

+39
-36
lines changed

3 files changed

+39
-36
lines changed

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Frame.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Diagnostics;
7-
using System.Globalization;
87
using System.IO;
98
using System.Linq;
109
using System.Net;

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/FrameOfT.cs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -91,24 +91,25 @@ public override async Task RequestProcessingAsync()
9191
var context = _application.CreateContext(this);
9292
try
9393
{
94-
await _application.ProcessRequestAsync(context).ConfigureAwait(false);
94+
try
95+
{
96+
await _application.ProcessRequestAsync(context).ConfigureAwait(false);
9597

96-
var responseHeaders = FrameResponseHeaders;
97-
if (!responseHeaders.HasTransferEncoding &&
98-
responseHeaders.HasContentLength &&
99-
_responseBytesWritten < responseHeaders.HeaderContentLengthValue.Value)
98+
var responseHeaders = FrameResponseHeaders;
99+
if (!responseHeaders.HasTransferEncoding &&
100+
responseHeaders.HasContentLength &&
101+
_responseBytesWritten < responseHeaders.HeaderContentLengthValue.Value)
102+
{
103+
_keepAlive = false;
104+
ReportApplicationError(new InvalidOperationException(
105+
$"Response Content-Length mismatch: too few bytes written ({_responseBytesWritten} of {responseHeaders.HeaderContentLengthValue.Value})."));
106+
}
107+
}
108+
catch (Exception ex)
100109
{
101-
_keepAlive = false;
102-
ReportApplicationError(new InvalidOperationException(
103-
$"Response Content-Length mismatch: too few bytes written ({_responseBytesWritten} of {responseHeaders.HeaderContentLengthValue.Value})."));
110+
ReportApplicationError(ex);
104111
}
105-
}
106-
catch (Exception ex)
107-
{
108-
ReportApplicationError(ex);
109-
}
110-
finally
111-
{
112+
112113
// Trigger OnStarting if it hasn't been called yet and the app hasn't
113114
// already failed. If an OnStarting callback throws we can go through
114115
// our normal error handling in ProduceEnd.
@@ -125,40 +126,43 @@ public override async Task RequestProcessingAsync()
125126
await FireOnCompleted();
126127
}
127128

128-
try
129+
// If _requestAbort is set, the connection has already been closed.
130+
if (Volatile.Read(ref _requestAborted) == 0)
129131
{
130-
// If _requestAbort is set, the connection has already been closed.
131-
if (Volatile.Read(ref _requestAborted) == 0)
132-
{
133-
ResumeStreams();
132+
ResumeStreams();
134133

135-
if (_keepAlive)
136-
{
137-
// Finish reading the request body in case the app did not.
138-
await messageBody.Consume();
139-
}
134+
if (_keepAlive)
135+
{
136+
// Finish reading the request body in case the app did not.
137+
await messageBody.Consume();
140138
}
141139

142140
// ProduceEnd() must be called before _application.DisposeContext(), to ensure
143141
// HttpContext.Response.StatusCode is correctly set when
144142
// IHttpContextFactory.Dispose(HttpContext) is called.
145143
await ProduceEnd();
146144
}
147-
finally
145+
else if (!HasResponseStarted)
148146
{
149-
_application.DisposeContext(context, _applicationException);
147+
// If the request was aborted and no response was sent, there's no
148+
// meaningful status code to log.
149+
StatusCode = 0;
150150
}
151151
}
152-
153-
StopStreams();
154-
155-
if (!_keepAlive)
152+
finally
156153
{
157-
// End the connection for non keep alive as data incoming may have been thrown off
158-
return;
154+
_application.DisposeContext(context, _applicationException);
159155
}
160156
}
161157

158+
StopStreams();
159+
160+
if (!_keepAlive)
161+
{
162+
// End the connection for non keep alive as data incoming may have been thrown off
163+
return;
164+
}
165+
162166
// Don't reset frame state if we're exiting the loop. This avoids losing request rejection
163167
// information (for 4xx response), and prevents ObjectDisposedException on HTTPS (ODEs
164168
// will be thrown if PrepareRequest is not null and references objects disposed on connection

test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/ResponseTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public Task ResponseStatusCodeSetBeforeHttpContextDisposeRequestAborted()
210210
return TaskCache.CompletedTask;
211211
},
212212
expectedClientStatusCode: null,
213-
expectedServerStatusCode: HttpStatusCode.OK);
213+
expectedServerStatusCode: 0);
214214
}
215215

216216
[Fact]
@@ -223,7 +223,7 @@ public Task ResponseStatusCodeSetBeforeHttpContextDisposeRequestAbortedAppExcept
223223
throw new Exception();
224224
},
225225
expectedClientStatusCode: null,
226-
expectedServerStatusCode: HttpStatusCode.InternalServerError);
226+
expectedServerStatusCode: 0);
227227
}
228228

229229
[Fact]

0 commit comments

Comments
 (0)