You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -2708,33 +2708,35 @@ Host Filtering Middleware is disabled by default. To enable the middleware, defi
2708
2708
2709
2709
::: moniker-end
2710
2710
2711
-
## HTTP connection request draining
2711
+
## HTTP/1.1 request draining
2712
2712
2713
-
Opening HTTP connections is relatively demanding on server resources, so Kestrel tries to reuse connections. A request must be fully consumed to be reused. Some requests can't be fully consumed, such as a `POST` requests where the server returns a redirect. In the `POST`-redirect case:
2713
+
Opening HTTP connections is time consuming. For HTTPS, it's also resource intensive. Therefore, Kestrel tries to reuse connections per the HTTP/1.1 protocol. A request body must be fully consumed to allow the connection to be reused. The app doesn't always consume the request body, such as a `POST` requests where the server returns a redirect or 404 response. In the `POST`-redirect case:
2714
2714
2715
2715
* The client may already have sent part of the `POST` data.
2716
2716
* The server writes the 301 response.
2717
-
* The connection can't be used for a new request because the `POST` data from the previous request hasn't been fully read.
2718
-
* Kestrel tries to drain the request. Draining the request means reading and discarding the data waiting to be read without processing the data.
2717
+
* The connection can't be used for a new request until the `POST` data from the previous request body has been fully read.
2718
+
* Kestrel tries to drain the request body. Draining the request body means reading and discarding the data without processing it.
2719
2719
2720
-
The draining process makes a tradoff between allowing remaining data to be read/discarded and closing the connection without reading remaining data:
2720
+
The draining process makes a tradoff between allowing the connection to be reused and the time it takes to drain any remaining data:
2721
2721
2722
2722
* Draining has a timeout of five seconds, which isn't configurable.
2723
-
* If all of the data specified by the `Content-Length` header hasn't been read before reaching the timeout, the connection is closed.
2723
+
* If all of the data specified by the `Content-Length`or `Transfer-Encoding`header hasn't been read before the timeout, the connection is closed.
2724
2724
2725
2725
Sometimes you may want to terminate the request immediately, before or after writing the response. For example, clients may have restrictive data caps, so limiting uploaded data might be a priority. In such cases to terminate a request, call [HttpContext.Abort](xref:Microsoft.AspNetCore.Http.HttpContext.Abort%2A) from a controller, Razor Page, or middleware.
2726
2726
2727
2727
There are caveats to calling `Abort`:
2728
2728
2729
-
*It's demanding on server resources to close and open TCP connections.
2729
+
*Creating new connections can be slow and expensive.
2730
2730
* There's no guarantee that the client has read the response before the connection closes.
2731
-
* Calling `Abort` should be rare and reserved for server error cases, not common errors.
2731
+
* Calling `Abort` should be rare and reserved for severe error cases, not common errors.
2732
2732
* Only call `Abort` when a specific problem needs to be solved. For example, call `Abort` if malicious clients are trying to `POST` data or when there's a bug in client code that causes large or numerous requests.
2733
-
* Don't call `Abort`to process ordinary resonses, such as HTTP 404 (Not Found).
2733
+
* Don't call `Abort`for common error situations, such as HTTP 404 (Not Found).
2734
2734
2735
-
Calling [HttpResponse.CompleteAsync](xref:Microsoft.AspNetCore.Http.HttpResponse.CompleteAsync%2A) before calling `Abort` ensures that the response has left the server. However, client behavior isn't predictable and can't be directly controlled by the app. Clients may continue to send data after calling `CompleteAsync` and `Abort`.
2735
+
Calling [HttpResponse.CompleteAsync](xref:Microsoft.AspNetCore.Http.HttpResponse.CompleteAsync%2A) before calling `Abort` ensures that the server has completed writing the response. However, client behavior isn't predictable and they may not read the response before the connection is aborted.
2736
2736
2737
-
If possible, it's better for clients to utilize the [Expect: 100-continue](https://developer.mozilla.org/docs/Web/HTTP/Status/100) request header so that they wait for the server to respond before starting to send the request body.
2737
+
This process is different for HTTP/2 because the protocol supports aborting individual request streams without closing the connection. The five second drain timeout doesn't apply. If there's any unread request body data after completing a response, then the server sends an HTTP/2 RST frame. Additional request body data frames are ignored.
2738
+
2739
+
If possible, it's better for clients to utilize the [Expect: 100-continue](https://developer.mozilla.org/docs/Web/HTTP/Status/100) request header and wait for the server to respond before starting to send the request body. That gives the client an opportunity to examine the response and abort before sending unneeded data.
0 commit comments