@@ -91,24 +91,25 @@ public override async Task RequestProcessingAsync()
91
91
var context = _application . CreateContext ( this ) ;
92
92
try
93
93
{
94
- await _application . ProcessRequestAsync ( context ) . ConfigureAwait ( false ) ;
94
+ try
95
+ {
96
+ await _application . ProcessRequestAsync ( context ) . ConfigureAwait ( false ) ;
95
97
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 )
100
109
{
101
- _keepAlive = false ;
102
- ReportApplicationError ( new InvalidOperationException (
103
- $ "Response Content-Length mismatch: too few bytes written ({ _responseBytesWritten } of { responseHeaders . HeaderContentLengthValue . Value } ).") ) ;
110
+ ReportApplicationError ( ex ) ;
104
111
}
105
- }
106
- catch ( Exception ex )
107
- {
108
- ReportApplicationError ( ex ) ;
109
- }
110
- finally
111
- {
112
+
112
113
// Trigger OnStarting if it hasn't been called yet and the app hasn't
113
114
// already failed. If an OnStarting callback throws we can go through
114
115
// our normal error handling in ProduceEnd.
@@ -125,40 +126,43 @@ public override async Task RequestProcessingAsync()
125
126
await FireOnCompleted ( ) ;
126
127
}
127
128
128
- try
129
+ // If _requestAbort is set, the connection has already been closed.
130
+ if ( Volatile . Read ( ref _requestAborted ) == 0 )
129
131
{
130
- // If _requestAbort is set, the connection has already been closed.
131
- if ( Volatile . Read ( ref _requestAborted ) == 0 )
132
- {
133
- ResumeStreams ( ) ;
132
+ ResumeStreams ( ) ;
134
133
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 ( ) ;
140
138
}
141
139
142
140
// ProduceEnd() must be called before _application.DisposeContext(), to ensure
143
141
// HttpContext.Response.StatusCode is correctly set when
144
142
// IHttpContextFactory.Dispose(HttpContext) is called.
145
143
await ProduceEnd ( ) ;
146
144
}
147
- finally
145
+ else if ( ! HasResponseStarted )
148
146
{
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 ;
150
150
}
151
151
}
152
-
153
- StopStreams ( ) ;
154
-
155
- if ( ! _keepAlive )
152
+ finally
156
153
{
157
- // End the connection for non keep alive as data incoming may have been thrown off
158
- return ;
154
+ _application . DisposeContext ( context , _applicationException ) ;
159
155
}
160
156
}
161
157
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
+
162
166
// Don't reset frame state if we're exiting the loop. This avoids losing request rejection
163
167
// information (for 4xx response), and prevents ObjectDisposedException on HTTPS (ODEs
164
168
// will be thrown if PrepareRequest is not null and references objects disposed on connection
0 commit comments