--- title: HTTP.sys web server implementation in ASP.NET Core author: guardrex description: Learn about HTTP.sys, a web server for ASP.NET Core on Windows. Built on the HTTP.sys kernel-mode driver, HTTP.sys is an alternative to Kestrel that can be used for direct connection to the Internet without IIS. monikerRange: '>= aspnetcore-2.0' ms.author: tdykstra ms.custom: mvc ms.date: 02/21/2019 uid: fundamentals/servers/httpsys --- # HTTP.sys web server implementation in ASP.NET Core By [Tom Dykstra](https://github.com/tdykstra), [Chris Ross](https://github.com/Tratcher), and [Luke Latham](https://github.com/guardrex) [HTTP.sys](/iis/get-started/introduction-to-iis/introduction-to-iis-architecture#hypertext-transfer-protocol-stack-httpsys) is a [web server for ASP.NET Core](xref:fundamentals/servers/index) that only runs on Windows. HTTP.sys is an alternative to [Kestrel](xref:fundamentals/servers/kestrel) server and offers some features that Kestrel doesn't provide. > [!IMPORTANT] > HTTP.sys isn't compatible with the [ASP.NET Core Module](xref:host-and-deploy/aspnet-core-module) and can't be used with IIS or IIS Express. HTTP.sys supports the following features: * [Windows Authentication](xref:security/authentication/windowsauth) * Port sharing * HTTPS with SNI * HTTP/2 over TLS (Windows 10 or later) * Direct file transmission * Response caching * WebSockets (Windows 8 or later) Supported Windows versions: * Windows 7 or later * Windows Server 2008 R2 or later [View or download sample code](https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/fundamentals/servers/httpsys/sample) ([how to download](xref:index#how-to-download-a-sample)) ## When to use HTTP.sys HTTP.sys is useful for deployments where: * There's a need to expose the server directly to the Internet without using IIS. ![HTTP.sys communicates directly with the Internet](httpsys/_static/httpsys-to-internet.png) * An internal deployment requires a feature not available in Kestrel, such as [Windows Authentication](xref:security/authentication/windowsauth). ![HTTP.sys communicates directly with the internal network](httpsys/_static/httpsys-to-internal.png) HTTP.sys is mature technology that protects against many types of attacks and provides the robustness, security, and scalability of a full-featured web server. IIS itself runs as an HTTP listener on top of HTTP.sys. ## HTTP/2 support [HTTP/2](https://httpwg.org/specs/rfc7540.html) is enabled for ASP.NET Core apps if the following base requirements are met: * Windows Server 2016/Windows 10 or later * [Application-Layer Protocol Negotiation (ALPN)](https://tools.ietf.org/html/rfc7301#section-3) connection * TLS 1.2 or later connection ::: moniker range=">= aspnetcore-2.2" If an HTTP/2 connection is established, [HttpRequest.Protocol](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol*) reports `HTTP/2`. ::: moniker-end ::: moniker range="< aspnetcore-2.2" If an HTTP/2 connection is established, [HttpRequest.Protocol](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol*) reports `HTTP/1.1`. ::: moniker-end HTTP/2 is enabled by default. If an HTTP/2 connection isn't established, the connection falls back to HTTP/1.1. In a future release of Windows, HTTP/2 configuration flags will be available, including the ability to disable HTTP/2 with HTTP.sys. ## Kernel mode authentication with Kerberos HTTP.sys delegates to kernel mode authentication with the Kerberos authentication protocol. User mode authentication isn't supported with Kerberos and HTTP.sys. The machine account must be used to decrypt the Kerberos token/ticket that's obtained from Active Directory and forwarded by the client to the server to authenticate the user. Register the Service Principal Name (SPN) for the host, not the user of the app. ## How to use HTTP.sys ### Configure the ASP.NET Core app to use HTTP.sys 1. A package reference in the project file isn't required when using the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app) ([nuget.org](https://www.nuget.org/packages/Microsoft.AspNetCore.App/)) (ASP.NET Core 2.1 or later). When not using the `Microsoft.AspNetCore.App` metapackage, add a package reference to [Microsoft.AspNetCore.Server.HttpSys](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.HttpSys/). 2. Call the extension method when building Web Host, specifying any required : [!code-csharp[](httpsys/sample/Program.cs?name=snippet1&highlight=4-12)] Additional HTTP.sys configuration is handled through [registry settings](https://support.microsoft.com/help/820129/http-sys-registry-settings-for-windows). **HTTP.sys options** | Property | Description | Default | | -------- | ----------- | :-----: | | [AllowSynchronousIO](xref:Microsoft.AspNetCore.Server.HttpSys.HttpSysOptions.AllowSynchronousIO) | Control whether synchronous input/output is allowed for the `HttpContext.Request.Body` and `HttpContext.Response.Body`. | `true` | | [Authentication.AllowAnonymous](xref:Microsoft.AspNetCore.Server.HttpSys.AuthenticationManager.AllowAnonymous) | Allow anonymous requests. | `true` | | [Authentication.Schemes](xref:Microsoft.AspNetCore.Server.HttpSys.AuthenticationManager.Schemes) | Specify the allowed authentication schemes. May be modified at any time prior to disposing the listener. Values are provided by the [AuthenticationSchemes enum](xref:Microsoft.AspNetCore.Server.HttpSys.AuthenticationSchemes): `Basic`, `Kerberos`, `Negotiate`, `None`, and `NTLM`. | `None` | | [EnableResponseCaching](xref:Microsoft.AspNetCore.Server.HttpSys.HttpSysOptions.EnableResponseCaching) | Attempt [kernel-mode](/windows-hardware/drivers/gettingstarted/user-mode-and-kernel-mode) caching for responses with eligible headers. The response may not include `Set-Cookie`, `Vary`, or `Pragma` headers. It must include a `Cache-Control` header that's `public` and either a `shared-max-age` or `max-age` value, or an `Expires` header. | `true` | | | The maximum number of concurrent accepts. | 5 × [Environment.
ProcessorCount](xref:System.Environment.ProcessorCount) | | | The maximum number of concurrent connections to accept. Use `-1` for infinite. Use `null` to use the registry's machine-wide setting. | `null`
(unlimited) | | | See the MaxRequestBodySize section. | 30000000 bytes
(~28.6 MB) | | | The maximum number of requests that can be queued. | 1000 | | | Indicate if response body writes that fail due to client disconnects should throw exceptions or complete normally. | `false`
(complete normally) | | | Expose the HTTP.sys configuration, which may also be configured in the registry. Follow the API links to learn more about each setting, including default values:
  • [TimeoutManager.DrainEntityBody](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.DrainEntityBody) – Time allowed for the HTTP Server API to drain the entity body on a Keep-Alive connection.
  • [TimeoutManager.EntityBody](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.EntityBody) – Time allowed for the request entity body to arrive.
  • [TimeoutManager.HeaderWait](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.HeaderWait) – Time allowed for the HTTP Server API to parse the request header.
  • [TimeoutManager.IdleConnection](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.IdleConnection) – Time allowed for an idle connection.
  • [TimeoutManager.MinSendBytesPerSecond](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.MinSendBytesPerSecond) – The minimum send rate for the response.
  • [TimeoutManager.RequestQueue](xref:Microsoft.AspNetCore.Server.HttpSys.TimeoutManager.RequestQueue) – Time allowed for the request to remain in the request queue before the app picks it up.
| | | | Specify the to register with HTTP.sys. The most useful is [UrlPrefixCollection.Add](xref:Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection.Add*), which is used to add a prefix to the collection. These may be modified at any time prior to disposing the listener. | | **MaxRequestBodySize** The maximum allowed size of any request body in bytes. When set to `null`, the maximum request body size is unlimited. This limit has no effect on upgraded connections, which are always unlimited. The recommended method to override the limit in an ASP.NET Core MVC app for a single `IActionResult` is to use the attribute on an action method: ```csharp [RequestSizeLimit(100000000)] public IActionResult MyActionMethod() ``` An exception is thrown if the app attempts to configure the limit on a request after the app has started reading the request. An `IsReadOnly` property can be used to indicate if the `MaxRequestBodySize` property is in a read-only state, meaning it's too late to configure the limit. If the app should override per-request, use the : [!code-csharp[](httpsys/sample/Startup.cs?name=snippet1&highlight=6-7)] 3. If using Visual Studio, make sure the app isn't configured to run IIS or IIS Express. In Visual Studio, the default launch profile is for IIS Express. To run the project as a console app, manually change the selected profile, as shown in the following screen shot: ![Select console app profile](httpsys/_static/vs-choose-profile.png) ### Configure Windows Server 1. Determine the ports to open for the app and use [Windows Firewall](/windows/security/threat-protection/windows-firewall/create-an-inbound-port-rule) or the [New-NetFirewallRule](/powershell/module/netsecurity/new-netfirewallrule) PowerShell cmdlet to open firewall ports to allow traffic to reach HTTP.sys. In the following commands and app configuration, port 443 is used. 1. When deploying to an Azure VM, open the ports in the [Network Security Group](/azure/virtual-machines/windows/nsg-quickstart-portal). In the following commands and app configuration, port 443 is used. 1. Obtain and install X.509 certificates, if required. On Windows, create self-signed certificates using the [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pkiclient/new-selfsignedcertificate). For an unsupported example, see [UpdateIISExpressSSLForChrome.ps1](https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1). Install either self-signed or CA-signed certificates in the server's **Local Machine** > **Personal** store. 1. If the app is a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd), install .NET Core, .NET Framework, or both (if the app is a .NET Core app targeting the .NET Framework). * **.NET Core** – If the app requires .NET Core, obtain and run the **.NET Core Runtime** installer from [.NET Core Downloads](https://dotnet.microsoft.com/download). Don't install the full SDK on the server. * **.NET Framework** – If the app requires .NET Framework, see the [.NET Framework installation guide](/dotnet/framework/install/). Install the required .NET Framework. The installer for the latest .NET Framework is available from the [.NET Core Downloads](https://dotnet.microsoft.com/download) page. If the app is a [self-contained deployment](/dotnet/core/deploying/#framework-dependent-deployments-scd), the app includes the runtime in its deployment. No framework installation is required on the server. 1. Configure URLs and ports in the app. By default, ASP.NET Core binds to `http://localhost:5000`. To configure URL prefixes and ports, options include: * * `urls` command-line argument * `ASPNETCORE_URLS` environment variable * The following code example shows how to use with the server's local IP address `10.0.0.4` on port 443: [!code-csharp[](httpsys/sample_snapshot/Program.cs?name=snippet1&highlight=11)] An advantage of `UrlPrefixes` is that an error message is generated immediately for improperly formatted prefixes. The settings in `UrlPrefixes` override `UseUrls`/`urls`/`ASPNETCORE_URLS` settings. Therefore, an advantage of `UseUrls`, `urls`, and the `ASPNETCORE_URLS` environment variable is that it's easier to switch between Kestrel and HTTP.sys. For more information, see . HTTP.sys uses the [HTTP Server API UrlPrefix string formats](https://msdn.microsoft.com/library/windows/desktop/aa364698.aspx). > [!WARNING] > Top-level wildcard bindings (`http://*:80/` and `http://+:80`) should **not** be used. Top-level wildcard bindings create app security vulnerabilities. This applies to both strong and weak wildcards. Use explicit host names or IP addresses rather than wildcards. Subdomain wildcard binding (for example, `*.mysub.com`) isn't a security risk if you control the entire parent domain (as opposed to `*.com`, which is vulnerable). For more information, see [RFC 7230: Section 5.4: Host](https://tools.ietf.org/html/rfc7230#section-5.4). 1. Preregister URL prefixes on the server. The built-in tool for configuring HTTP.sys is *netsh.exe*. *netsh.exe* is used to reserve URL prefixes and assign X.509 certificates. The tool requires administrator privileges. Use the *netsh.exe* tool to register URLs for the app: ```console netsh http add urlacl url= user= ``` * `` – The fully qualified Uniform Resource Locator (URL). Don't use a wildcard binding. Use a valid hostname or local IP address. *The URL must include a trailing slash.* * `` – Specifies the user or user-group name. In the following example, the local IP address of the server is `10.0.0.4`: ```console netsh http add urlacl url=https://10.0.0.4:443/ user=Users ``` When a URL is registered, the tool responds with `URL reservation successfully added`. To delete a registered URL, use the `delete urlacl` command: ```console netsh http delete urlacl url= ``` 1. Register X.509 certificates on the server. Use the *netsh.exe* tool to register certificates for the app: ```console netsh http add sslcert ipport=: certhash= appid="{}" ``` * `` – Specifies the local IP address for the binding. Don't use a wildcard binding. Use a valid IP address. * `` – Specifies the port for the binding. * `` – The X.509 certificate thumbprint. * `` – A developer-generated GUID to represent the app for informational purposes. For reference purposes, store the GUID in the app as a package tag: * In Visual Studio: * Open the app's project properties by right-clicking on the app in **Solution Explorer** and selecting **Properties**. * Select the **Package** tab. * Enter the GUID that you created in the **Tags** field. * When not using Visual Studio: * Open the app's project file. * Add a `` property to a new or existing `` with the GUID that you created: ```xml 9412ee86-c21b-4eb8-bd89-f650fbf44931 ``` In the following example: * The local IP address of the server is `10.0.0.4`. * An online random GUID generator provides the `appid` value. ```console netsh http add sslcert ipport=10.0.0.4:443 certhash=b66ee04419d4ee37464ab8785ff02449980eae10 appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}" ``` When a certificate is registered, the tool responds with `SSL Certificate successfully added`. To delete a certificate registration, use the `delete sslcert` command: ```console netsh http delete sslcert ipport=: ``` Reference documentation for *netsh.exe*: * [Netsh Commands for Hypertext Transfer Protocol (HTTP)](https://technet.microsoft.com/library/cc725882.aspx) * [UrlPrefix Strings](https://msdn.microsoft.com/library/windows/desktop/aa364698.aspx) 1. Run the app. Administrator privileges aren't required to run the app when binding to localhost using HTTP (not HTTPS) with a port number greater than 1024. For other configurations (for example, using a local IP address or binding to port 443), run the app with administrator privileges. The app responds at the server's public IP address. In this example, the server is reached from the Internet at its public IP address of `104.214.79.47`. A development certificate is used in this example. The page loads securely after bypassing the browser's untrusted certificate warning. ![Browser window showing the app's Index page loaded](httpsys/_static/browser.png) ## Proxy server and load balancer scenarios For apps hosted by HTTP.sys that interact with requests from the Internet or a corporate network, additional configuration might be required when hosting behind proxy servers and load balancers. For more information, see [Configure ASP.NET Core to work with proxy servers and load balancers](xref:host-and-deploy/proxy-load-balancer). ## Additional resources * [Enable Windows Authentication with HTTP.sys](xref:security/authentication/windowsauth#enable-windows-authentication-with-httpsys) * [HTTP Server API](https://msdn.microsoft.com/library/windows/desktop/aa364510.aspx) * [aspnet/HttpSysServer GitHub repository (source code)](https://github.com/aspnet/HttpSysServer/) * [The host](xref:fundamentals/index#host) *