Skip to content

Commit bddcbc9

Browse files
aL3891guardrexTratcherRick-Anderson
authored
Add section about request draining (#18075)
* Add section about request draining As per the discussion over at dotnet/aspnetcore#21292 Here is a request to update the Kestrel docs with information regarding request draining and how it can be avoided in cases where one might want that. cc @guardrex @tebeco @Tratcher, have i missed anything? * Fixed some wording * Apply suggestions from code review Co-authored-by: Chris Ross <Tratcher@Outlook.com> * Update kestrel.md * Update kestrel.md * Updates * Updates * Nit * Surface in File Uploads topic Co-authored-by: Luke Latham <1622880+guardrex@users.noreply.github.com> Co-authored-by: Chris Ross <Tratcher@Outlook.com> Co-authored-by: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com>
1 parent 397573f commit bddcbc9

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

aspnetcore/fundamentals/servers/kestrel.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn about Kestrel, the cross-platform web server for ASP.NET Core
55
monikerRange: '>= aspnetcore-2.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 02/10/2020
8+
ms.date: 05/03/2020
99
uid: fundamentals/servers/kestrel
1010
---
1111
# Kestrel web server implementation in ASP.NET Core
@@ -2707,6 +2707,34 @@ Host Filtering Middleware is disabled by default. To enable the middleware, defi
27072707
27082708
::: moniker-end
27092709

2710+
## HTTP connection request draining
2711+
2712+
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+
2714+
* The client may already have sent part of the `POST` data.
2715+
* The server writes the 301 response.
2716+
* The connection can't be used for a new request because the `POST` data from the previous request hasn't been fully read.
2717+
* Kestrel tries to drain the request. Draining the request means reading and discarding the data waiting to be read without processing the data.
2718+
2719+
The draining process makes a tradoff between allowing remaining data to be read/discarded and closing the connection without reading remaining data:
2720+
2721+
* Draining has a timeout of five seconds, which isn't configurable.
2722+
* If all of the data specified by the `Content-Length` header hasn't been read before reaching the timeout, the connection is closed.
2723+
2724+
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.
2725+
2726+
There are caveats to calling `Abort`:
2727+
2728+
* It's demanding on server resources to close and open TCP connections.
2729+
* There's no guarantee that the client has read the response before the connection closes.
2730+
* Calling `Abort` should be rare and reserved for server error cases, not common errors.
2731+
* 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.
2732+
* Don't call `Abort` to process ordinary resonses, such as HTTP 404 (Not Found).
2733+
2734+
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+
2736+
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+
27102738
## Additional resources
27112739

27122740
* When using UNIX sockets on Linux, the socket is not automatically deleted on app shut down. For more information, see [this GitHub issue](https://github.com/dotnet/aspnetcore/issues/14134).

aspnetcore/mvc/models/file-uploads.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: How to use model binding and streaming to upload files in ASP.NET C
55
monikerRange: '>= aspnetcore-2.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 04/18/2020
8+
ms.date: 05/03/2020
99
uid: mvc/models/file-uploads
1010
---
1111
# Upload files in ASP.NET Core
@@ -1466,6 +1466,7 @@ The examples in this topic rely upon <xref:System.IO.MemoryStream> to hold the u
14661466

14671467
## Additional resources
14681468

1469+
* [HTTP connection request draining](xref:fundamentals/servers/kestrel#http-connection-request-draining)
14691470
* [Unrestricted File Upload](https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload)
14701471
* [Azure Security: Security Frame: Input Validation | Mitigations](/azure/security/azure-security-threat-modeling-tool-input-validation)
14711472
* [Azure Cloud Design Patterns: Valet Key pattern](/azure/architecture/patterns/valet-key)

0 commit comments

Comments
 (0)