From 55590a8970972b43ec1ee291b2d84a0c64b7f931 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Sun, 25 Feb 2018 17:23:19 -0600 Subject: [PATCH 1/4] Servers > HTTP.sys UE pass Updates Updates Updates Update --- aspnetcore/fundamentals/servers/httpsys.md | 197 ++++++++---------- .../httpsys/_static/vs-choose-profile.png | Bin 44112 -> 26846 bytes .../servers/httpsys/sample/.bowerrc | 3 + ...ttpSysDemo.csproj => HttpSysSample.csproj} | 3 +- .../servers/httpsys/sample/Pages/Error.cshtml | 23 ++ .../httpsys/sample/Pages/Error.cshtml.cs | 17 ++ .../servers/httpsys/sample/Pages/Index.cshtml | 28 +++ .../httpsys/sample/Pages/Index.cshtml.cs | 11 + .../httpsys/sample/Pages/_Layout.cshtml | 70 +++++++ .../httpsys/sample/Pages/_ViewImports.cshtml | 3 + .../httpsys/sample/Pages/_ViewStart.cshtml | 3 + .../servers/httpsys/sample/Program.cs | 17 +- .../servers/httpsys/sample/README.md | 3 + .../servers/httpsys/sample/Startup.cs | 45 ++-- .../sample/appsettings.Development.json | 10 + .../sample/appsettings.Production.json | 10 + .../servers/httpsys/sample/appsettings.json | 8 + .../servers/httpsys/sample/bower.json | 10 + .../servers/httpsys/sample/bundleconfig.json | 24 +++ .../httpsys/sample/wwwroot/css/site.css | 25 +++ .../httpsys/sample/wwwroot/css/site.min.css | 1 + .../httpsys/sample/wwwroot/favicon.ico | Bin 0 -> 32038 bytes .../servers/httpsys/sample/wwwroot/js/site.js | 1 + .../httpsys/sample/wwwroot/js/site.min.js | 0 aspnetcore/fundamentals/servers/kestrel.md | 4 +- aspnetcore/includes/make-ssl-cert.md | 3 - aspnetcore/includes/make-x509-cert.md | 7 + 27 files changed, 378 insertions(+), 148 deletions(-) create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/.bowerrc rename aspnetcore/fundamentals/servers/httpsys/sample/{HttpSysDemo.csproj => HttpSysSample.csproj} (87%) create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml.cs create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml.cs create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/_Layout.cshtml create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewImports.cshtml create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewStart.cshtml create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/README.md create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Development.json create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Production.json create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/appsettings.json create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/bower.json create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/bundleconfig.json create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.css create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.min.css create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/favicon.ico create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/js/site.js create mode 100644 aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/js/site.min.js delete mode 100644 aspnetcore/includes/make-ssl-cert.md create mode 100644 aspnetcore/includes/make-x509-cert.md diff --git a/aspnetcore/fundamentals/servers/httpsys.md b/aspnetcore/fundamentals/servers/httpsys.md index 8bcd1adbd6cf..9fce007f291e 100644 --- a/aspnetcore/fundamentals/servers/httpsys.md +++ b/aspnetcore/fundamentals/servers/httpsys.md @@ -1,10 +1,11 @@ --- title: HTTP.sys web server implementation in ASP.NET Core -author: rick-anderson -description: Introduces 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. +author: tdykstra +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. manager: wpickett -ms.author: riande -ms.date: 08/07/2017 +ms.author: tdykstra +ms.custom: mvc +ms.date: 02/28/2018 ms.prod: asp.net-core ms.technology: aspnet ms.topic: article @@ -12,168 +13,142 @@ uid: fundamentals/servers/httpsys --- # HTTP.sys web server implementation in ASP.NET Core -By [Tom Dykstra](https://github.com/tdykstra) and [Chris Ross](https://github.com/Tratcher) +By [Tom Dykstra](https://github.com/tdykstra), [Chris Ross](https://github.com/Tratcher), and [Luke Latham](https://github.com/guardrex) > [!NOTE] -> This topic applies only to ASP.NET Core 2.0 and later. In earlier versions of ASP.NET Core, HTTP.sys is named [WebListener](xref:fundamentals/servers/weblistener). +> This topic applies to ASP.NET Core 2.0 or later. In earlier versions of ASP.NET Core, HTTP.sys is named [WebListener](xref:fundamentals/servers/weblistener). -HTTP.sys is a [web server for ASP.NET Core](index.md) that runs only on Windows. It's built on the [Http.Sys kernel mode driver](https://msdn.microsoft.com/library/windows/desktop/aa364510.aspx). HTTP.sys is an alternative to [Kestrel](kestrel.md) that offers some features that Kestel doesn't. **HTTP.sys can't be used with IIS or IIS Express, as it's incompatible with the [ASP.NET Core Module](aspnet-core-module.md).** +[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) and offers some features that Kestrel doesn't provide. + +**Important!** HTTP.sys is incompatible with the [ASP.NET Core Module](xref:fundamentals/servers/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) -- Direct file transmission -- Response caching -- WebSockets (Windows 8) +* [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 and Windows Server 2008 R2 and later +* Windows 7 or later +* Windows Server 2008 R2 or later [View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/servers/httpsys/sample) ([how to download](xref:tutorials/index#how-to-download-a-sample)) ## When to use HTTP.sys -HTTP.sys is useful for deployments where you 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) - -Because it's built on Http.Sys, HTTP.sys doesn't require a reverse proxy server for protection against attacks. Http.Sys is mature technology that protects against many kinds 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.sys is a good choice for internal deployments when you need a feature not available in Kestrel, such as Windows authentication. - -![HTTP.sys communicates directly with your internal network](httpsys/_static/httpsys-to-internal.png) - -## How to use HTTP.sys - -Here's an overview of setup tasks for the host OS and your ASP.NET Core application. - -### Configure Windows Server - -* Install the version of .NET that your application requires, such as [.NET Core](https://www.microsoft.com/net/download/core) or [.NET Framework](https://www.microsoft.com/net/download/framework). - -* Preregister URL prefixes to bind to HTTP.sys, and set up SSL certificates +HTTP.sys is useful for deployments where: - If you don't preregister URL prefixes in Windows, you have to run your application with administrator privileges. The only exception is if you bind to localhost using HTTP (not HTTPS) with a port number greater than 1024; in that case, administrator privileges aren't required. +* There's a need to expose the server directly to the Internet without using IIS. - For details, see [How to preregister prefixes and configure SSL](#preregister-url-prefixes-and-configure-ssl) later in this article. + ![HTTP.sys communicates directly with the Internet](httpsys/_static/httpsys-to-internet.png) -* Open firewall ports to allow traffic to reach HTTP.sys. +* An internal deployment requires a feature not available in Kestrel, such as [Windows Authentication](xref:security/authentication/windowsauth). - You can use *netsh.exe* or [PowerShell cmdlets](https://technet.microsoft.com/library/jj554906). + ![HTTP.sys communicates directly with the internal network](httpsys/_static/httpsys-to-internal.png) -There are also [Http.Sys registry settings](https://support.microsoft.com/kb/820129). +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. -### Configure your ASP.NET Core application to use HTTP.sys - -* No package install is needed if you use the [Microsoft.AspNetCore.All](xref:fundamentals/metapackage) metapackage. The [Microsoft.AspNetCore.Server.HttpSys](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.HttpSys/) package is included in the metapackage. - -* Call the `UseHttpSys` extension method on `WebHostBuilder` in your `Main` method, specifying any [HTTP.sys options](https://github.com/aspnet/HttpSysServer/blob/rel/2.0.0/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs) that you need, as shown in the following example: - - [!code-csharp[](httpsys/sample/Program.cs?name=snippet_Main&highlight=11-19)] - -### Configure HTTP.sys options - -Here are some of the HTTP.sys settings and limits that you can configure. - -**Maximum client connections** - -The maximum number of concurrent open TCP connections can be set for the entire application with the following code in *Program.cs*: - -[!code-csharp[](httpsys/sample/Program.cs?name=snippet_Options&highlight=5)] - -The maximum number of connections is unlimited (null) by default. +## How to use HTTP.sys -**Maximum request body size** +### Configure the ASP.NET Core app to use HTTP.sys -The default maximum request body size is 30,000,000 bytes, which is approximately 28.6MB. +1. A package reference in the project file isn't required when using the [Microsoft.AspNetCore.All metapackage](xref:fundamentals/metapackage) ([nuget.org](https://www.nuget.org/packages/Microsoft.AspNetCore.All/)) (ASP.NET Core 2.0 or later). When not using the `Microsoft.AspNetCore.All` metapackage, add a package reference to [Microsoft.AspNetCore.Server.HttpSys](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.HttpSys/). -The recommended way to override the limit in an ASP.NET Core MVC app is to use the [RequestSizeLimit](https://github.com/aspnet/Mvc/blob/rel/2.0.0/src/Microsoft.AspNetCore.Mvc.Core/RequestSizeLimitAttribute.cs) attribute on an action method: +1. Call the [UseHttpSys](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderhttpsysextensions.usehttpsys) extension method when building the web host, specifying any required [HTTP.sys options](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions): -```csharp -[RequestSizeLimit(100000000)] -public IActionResult MyActionMethod() -``` + [!code-csharp[](httpsys/sample/Program.cs?name=snippet1&highlight=4-12)] -Here's an example that shows how to configure the constraint for the entire application, every request: + Additional HTTP.sys configuration is handled through [registry settings](https://support.microsoft.com/kb/820129). -[!code-csharp[](httpsys/sample/Program.cs?name=snippet_Options&highlight=6)] + **HTTP.sys options** -You can override the setting on a specific request in *Startup.cs*: + | Property | Description | Default | + | -------- | ----------- | :-----: | + | [AllowSynchronousIO](/dotnet/api/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](/dotnet/api/microsoft.aspnetcore.server.httpsys.authenticationmanager.allowanonymous) | Allow anonymous requests. | `true` | + | [Authentication.Schemes](/dotnet/api/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](/dotnet/api/microsoft.aspnetcore.server.httpsys.authenticationschemes): `Basic`, `Kerberos`, `Negotiate`, `None`, and `NTLM`. | `None` | + | [EnableResponseCaching](/dotnet/api/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` | + | [MaxAccepts](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxaccepts) | The maximum number of concurrent accepts. | 5 × [Environment.
ProcessorCount](/dotnet/api/system.environment.processorcount) | + | [MaxConnections](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxconnections) | The maximum number of concurrent connections to accept. Use `-1` for infinite. Use `null` to use the registry's machine-wide setting. | `null`
(unlimited) | + | [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.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 [RequestSizeLimitAttribute](/dotnet/api/microsoft.aspnetcore.mvc.requestsizelimitattribute) attribute on an action method. For example, `[RequestSizeLimit(100000000)]`.

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.

| 30000000 bytes
(~28.6 MB) | + | [RequestQueueLimit](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.requestqueuelimit) | The maximum number of requests that can be queued. | 1000 | + | [ThrowWriteExceptions](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.throwwriteexceptions) | Indicate if response body writes that fail due to client disconnects should throw exceptions or complete normally. | `false`
(complete normally) | + | [Timeouts](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts) | Expose the HTTP.sys [TimeoutManager](/dotnet/api/microsoft.aspnetcore.server.httpsys.timeoutmanager) configuration, which may also be configured in the registry. Follow the API links to learn more about each setting, including default values: | | + | [UrlPrefixes](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.urlprefixes) | Specify the [UrlPrefixCollection](/dotnet/api/microsoft.aspnetcore.server.httpsys.urlprefixcollection) to register with HTTP.sys. The most useful is [UrlPrefixCollection.Add](/dotnet/api/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. | | -[!code-csharp[](httpsys/sample/Startup.cs?name=snippet_Configure&highlight=9-10)] - -An exception is thrown if you try to configure the limit on a request after the application has started reading the request. There's an `IsReadOnly` property that tells you if the `MaxRequestBodySize` property is in read-only state, meaning it's too late to configure the limit. +1. If the app should override [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxrequestbodysize) per-request, use the [IHttpMaxRequestBodySizeFeature](/dotnet/api/microsoft.aspnetcore.http.features.ihttpmaxrequestbodysizefeature): -For information about other HTTP.sys options, see [HttpSysOptions](https://github.com/aspnet/HttpSysServer/blob/rel/2.0.0/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs). + [!code-csharp[](httpsys/sample/Startup.cs?name=snippet1&highlight=6-7)] -### Configure URLs and ports to listen on +1. If using Visual Studio, make sure the app isn't configured to run IIS or IIS Express. -By default ASP.NET Core binds to `http://localhost:5000`. To configure URL prefixes and ports, you can use the `UseUrls` extension method, the `urls` command-line argument, the ASPNETCORE_URLS environment variable, or the `UrlPrefixes` property on [HttpSysOptions](https://github.com/aspnet/HttpSysServer/blob/rel/2.0.0/src/Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs). The following code example uses `UrlPrefixes`. + 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: -[!code-csharp[](httpsys/sample/Program.cs?name=snippet_Main&highlight=17)] + ![Select console app profile](httpsys/_static/vs-choose-profile.png) -An advantage of `UrlPrefixes` is that you get an error message immediately if you try to add a prefix that's formatted wrong. An advantage of `UseUrls` (shared with `urls` and ASPNETCORE_URLS) is that you can more easily switch between Kestrel and HTTP.sys. +### Configure Windows Server -If you use both `UseUrls` (or `urls` or ASPNETCORE_URLS) and `UrlPrefixes`, the settings in `UrlPrefixes` override the ones in `UseUrls`. For more information, see [Hosting](xref:fundamentals/hosting). +1. Install the .NET Core or ASP.NET 4.x framework if the app is a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd). -HTTP.sys uses the [HTTP Server API UrlPrefix string formats](https://msdn.microsoft.com/library/windows/desktop/aa364698.aspx). + * **.NET Core** – If the app requires .NET Core, obtain and run the .NET Core installer from [.NET Downloads](https://www.microsoft.com/net/download/windows). + * **ASP.NET 4.x** – If the app requires ASP.NET 4.x, see [.NET Framework: Installation guide](/dotnet/framework/install/) to find installation instructions. Install the required ASP.NET 4.x framework. The installer for the latest ASP.NET 4.x framework can be found at [.NET Downloads](https://www.microsoft.com/net/download/windows). -> [!NOTE] -> Make sure that you specify the same prefix strings in `UseUrls` or `UrlPrefixes` that you preregister on the server. +1. Configure URLs and ports for the app. -### Don't use IIS + By default, ASP.NET Core binds to `http://localhost:5000`. To configure URL prefixes and ports, options include using: -Make sure your application isn't configured to run IIS or IIS Express. + * [UseUrls](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useurls) + * `urls` command-line argument + * `ASPNETCORE_URLS` environment variable + * [UrlPrefixes](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.urlprefixes) -In Visual Studio, the default launch profile is for IIS Express. To run the project as a console application, manually change the selected profile, as shown in the following screen shot. + The following code example shows how to use [UrlPrefixes](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.urlprefixes): -![Select console app profile](httpsys/_static/vs-choose-profile.png) + [!code-csharp[](httpsys/sample/Program.cs?name=snippet1&highlight=11)] -## Preregister URL prefixes and configure SSL + An advantage of `UrlPrefixes` is that an error message is generated immediately for improperly formatted prefixes. -Both IIS and HTTP.sys rely on the underlying Http.Sys kernel mode driver to listen for requests and do initial processing. In IIS, the management UI gives you a relatively easy way to configure everything. However, you need to configure Http.Sys yourself. The built-in tool for doing that's *netsh.exe*. + 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 on `UseUrls`, `urls`, and `ASPNETCORE_URLS`, see [Hosting](xref:fundamentals/hosting). -With *netsh.exe* you can reserve URL prefixes and assign SSL certificates. The tool requires administrative privileges. + HTTP.sys uses the [HTTP Server API UrlPrefix string formats](https://msdn.microsoft.com/library/windows/desktop/aa364698.aspx). -The following example shows the minimum needed to reserve URL prefixes for ports 80 and 443: +1. Preregister URL prefixes to bind to HTTP.sys and set up x.509 certificates. -```console -netsh http add urlacl url=http://+:80/ user=Users -netsh http add urlacl url=https://+:443/ user=Users -``` + If URL prefixes aren't preregistered in Windows, run the app with administrator privileges. The only exception is when binding to localhost using HTTP (not HTTPS) with a port number greater than 1024. In that case, administrator privileges aren't required. -The following example shows how to assign an SSL certificate: + 1. 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. -```console -netsh http add sslcert ipport=0.0.0.0:443 certhash=MyCertHash_Here appid={00000000-0000-0000-0000-000000000000}" -``` + The following example shows the commands to reserve URL prefixes for ports 80 and 443: -Here is the reference documentation for *netsh.exe*: + ```console + netsh http add urlacl url=http://+:80/ user=Users + netsh http add urlacl url=https://+:443/ user=Users + ``` -* [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) + The following example shows how to assign an X.509 certificate: -The following resources provide detailed instructions for several scenarios. Articles that refer to HttpListener apply equally to HTTP.sys, as both are based on Http.Sys. + ```console + netsh http add sslcert ipport=0.0.0.0:443 certhash=MyCertHash_Here appid={00000000-0000-0000-0000-000000000000}" + ``` -* [How to: Configure a Port with an SSL Certificate](https://docs.microsoft.com/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate) -* [HTTPS Communication - HttpListener based Hosting and Client Certification](http://sunshaking.blogspot.com/2012/11/https-communication-httplistener-based.html) This is a third-party blog and is fairly old but still has useful information. -* [How To: Walkthrough Using HttpListener or Http Server unmanaged code (C++) as an SSL Simple Server](https://blogs.msdn.microsoft.com/jpsanders/2009/09/29/how-to-walkthrough-using-httplistener-or-http-server-unmanaged-code-c-as-an-ssl-simple-server/) This too is an older blog with useful information. + Reference documentation for *netsh.exe*: -Here are some third-party tools that can be easier to use than the *netsh.exe* command line. These are not provided by or endorsed by Microsoft. The tools run as administrator by default, since *netsh.exe* itself requires administrator privileges. + * [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) -* [http.sys Manager](http://httpsysmanager.codeplex.com/) provides UI for listing and configuring SSL certificates and options, prefix reservations, and certificate trust lists. -* [HttpConfig](http://www.stevestechspot.com/ABetterHttpcfg.aspx) lets you list or configure SSL certificates and URL prefixes. The UI is more refined than http.sys Manager and exposes a few more configuration options, but otherwise it provides similar functionality. It cannot create a new certificate trust list (CTL), but can assign existing ones. + 1. Create self-signed X.509 certificates, if required. -[!INCLUDE[How to make an SSL cert](../../includes/make-ssl-cert.md)] + [!INCLUDE[How to make an X.509 cert](../../includes/make-x509-cert.md)] -## Next steps +1. Open firewall ports to allow traffic to reach HTTP.sys. Use *netsh.exe* or [PowerShell cmdlets](https://technet.microsoft.com/library/jj554906). -For more information, see the following resources: +## Additional resources -* [Sample app for this article](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/servers/httpsys/sample) -* [HTTP.sys source code](https://github.com/aspnet/HttpSysServer/) +* [HTTP Server API](https://msdn.microsoft.com/library/windows/desktop/aa364510.aspx) +* [aspnet/HttpSysServer GitHub repository (source code)](https://github.com/aspnet/HttpSysServer/) * [Hosting](xref:fundamentals/hosting) diff --git a/aspnetcore/fundamentals/servers/httpsys/_static/vs-choose-profile.png b/aspnetcore/fundamentals/servers/httpsys/_static/vs-choose-profile.png index 4fcd45e7fe8cf21ac983d61f99f4de10f981522d..1dde2fd081936160a9fc675c8b7e6ff7637ba0e5 100644 GIT binary patch literal 26846 zcmZ^KWmFtZ)aDR^LmY_37E4A&1cxFSN|d{VuF(BeMC3E>U`{AxbhK|Ix&jSiIQ$~a4$+_J zfV|M~;pa`yJgfP(`@ONZ`UT$o^6Sjn379Te#3XTM1y*0g5CI0IdWfbcmc-z;{%W zP+@>M7odDXHCzOs&Hz9&mHNv8Sfm9oNT`{L1F9MUUE?SSH2_#d0E0qk5GCNVCqRFY zgv1RHmy;9@8qz0kvQ+-e>wT8R-2ZxBC7A&m;jG7u90mZlkCN&zH!6$<>e!3p_ zRBR?c7UYfVQ2-z(7X4$j*RO8lUqIvIY|#y0^k|Pdq2GxO4Y%KRC(7*k0f0?s;M5xp zeJzeJ7qqX<+aJ=i&*r)aIlt~BOly$&>j623%WBv5|7atU`@4B*X?JI5QSz^#mcg)^ z_nTRdUYFXd^&^n`<^Fb~W9x?>la8O*=ZB4+(HrRkyoortK*QC&7_pZ|g!dQx8REYZ zhRy0!Xxj?k9HNEOBCnYWh{FWqDEmmK-;KAxG|!N{U{*ktB`<_$EN!ul5#*f|If}Y- z*Va7%aMfzpJxc)#>1!UaIpO+#&i5*oLkjRUm56fy0Ca_a&?yhs@(sWO0Kz$bR8<1F zH{Dn?UC?;lP^;YtFZyhOfQk2c3sMA+RpC?V)6eqbvvet#2glog zq3cm;`od$6{A2)|)lJdn2lrWE5Ej*dXgL(ZFkGD^8WuA(=z*wP{PVYnAK!;U(G-ZK zVp+u*6~mRktBB)Y@i>0s2+i&_hlfUo2He z*7Ei7FP0$_V~Dyq4axks7*u)`&rqSi>_5JR2{Dm3|NbOVov%FoZCZ5NR*~e8rX-z3 z9ET)+XxZ4R28JVn<~#LZ&`#z~?+)`0?hetF7JQ~5zeE0m(iVl{u%#sSF3K*;F0@Gs zlYmNIn&Mh-nb$n1)~QHgql%cr(?ljnPIzPRi;Q6V$Vci4=6LRGajexry{4? zsi;#mPz6OS`qn%T3QQ{V| zNH;T@Xj_#gB`2wuiI*vqi5<7IfliAu3)@9nHJ<&x2nGbjo6&NHMByR@BHcxTq&51^dB1c;EYj6M9w&}O&&m)5- zBO;TMIg&X`Q?x8`dZX18!uayHE-5ib=fe~P|}E9wYvzt z0&1{n@HQ|r#58N{1NEN8x5s<8ct^eRz#xSzeJR7�NUnIihi@a;~S1XPohQ_uV8N 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

judA;Ufe1l`qf*^ zU-11Gc7M?a9>eUTVkAIxC2_B}f6T^MmT-??&ITU^*{ZkDo&CxC+ZQh8oNWD3o9d|P z9n!uZ9&<18bl(#!f+yl{77;NP3bb~YmK*FXr?vJY*%viRBIIse{B8(?k)OE7wH^^nM`-JnzG1alQN^;-o!F+!euGvmNxw7Gfu6-F82dQ zrS1Hj+?=AwH_&F90@f8+FALDW!1a((oe8(5>#LwWmD=e?J{Dp5B15e>lp5sQJMH4u z(;U_bF87R+ng6xOPp=8mLdlTpb1}?d&74t6Pl)yaP#VjI%&^8yY4m>H+gWPAwx~EJ zuXtln*v((tY5jearEqQfvdL}wo3MxGIdSzN_AA#kn`P5Mjfb`6!kKz7-|xqi!HvsU zT77xKJ!hSr5OB?*OyU!$5*X^OzyPNb8O}ZCv6ZgeS#R&`eGIvk9;&8j5DqnA&UOoK zcrPw<(~a58rwU^BJ6{v>scnXtY>-nvJso6wTY7=$-4IO1!R&!A-tY`Zd8PmZjUFEv zKW%ASST~0l_pi+bM$Q5ZJjfNprm|}7(_kvBMEpwDdmD+~!t9^1J zR0sMnN^g(?zON%2nu;E#A(KS=(;m*~{*S5}AsWn1Ezd@H6`XcQKlDtKJ17E$NJix` zP-|aCf!u?ncdib4}P)^esHdnv1N6V#f)U5DPS)b*%8C!x|L@S(4>K4VT5Zs{-BWXm16gS*=@n{p^UKjP)7vpTE{=SjD^pXE|{c<={?LKKhTHn+2 z?vuqCjQXc1hW?w#(d}@onD!bZ(S*iHRjl7iZCinJ_=yR>eM0wA}ure`3$~KdN>VcjVC` znY{&UGD5!wQ8P1JpIhGr7vfxwNc;=`Jalk&&Fb@VFxeY9a^UhIo#!_LDI0;ik8i$| zDMe@xr}^4qIO|;HrF#?FE_d45obRU=e7}jSWw?M~Zp+&66fhQ}m3hEXhx~*wpZnC^ zti!Ai2@4-D&#nHk{_u01GCv{8Sv8--cho$bX-0f_W*RY*eH)+tm)EVztZ@05jGS*6 zn-5}$XwHF?s-hC^M(n9@C#$f8!_Uf(j?MgY#)oN&7+J%cvEp%&9mq(0TNtfpg7@a@ zNqeFU&a(Xn8M)ANC-Fd;T7X@uAk+DYeipeIn9`+s5X1C6Z+SE7>~VS<{@#_Hp>%Ng55)(v*a*9< zxCIs4ls$FT%yJ`>;$&i{UE3E=aLYdUVtH_(nD&4htd#_W?q*e;_q&}j#L*Z5ZO%}~^{3dFy> zsf#A5c#j{D#*DNCrNZAo1*cvvL#u;Qin#Mxh;HyjjXkzjWQIo8$C34-N7(B#4>GR4 z-?Wvp4<+E`_eM==!!Ea$=;5q2h3_IQ*^7k5J#By?y~Q$f+e~mQpt}S79UcE3l$M@= z1yWgG^~VFASVKhs;hW5otbpAo3cPhnt_^+L$a43l8b+&klf1eU(xdrlU>OaSBmD%k zP;qVytUdY$+(?U$ZYCXm0X>_l+E}}rfqe;`D_z(cETVf~%eb4351iI|Fg$b2Or#_P z=PAA8@v6u}k+2jmvX_6dm?9qixP~;CpM%P@LIoUBW~hy>ca>kNpMW_(nj~)P?~GuF zn4_|(V*6E06Gb`_Ukn&J`>d1=xQ!EaKW)Kyp@)Pqe4UvoHr*L_O3HEKFR};D)J9`{2lrU2@u6R~#T#|ST z{Z=`~{ItE@g2TuoI1R^+d=28i1q-MT7m;EI#}_0=i=!TNaDmWIiYEZ&jB*vGfT|BQ zvfcoFLG8M*l-{SQzQo>UIQ(R{iAO)td3zJxopzKfpfeX#40vbLm|18N(B1ig< netcoreapp2.0 - Exe - + diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml new file mode 100644 index 000000000000..0341fe884a5f --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml @@ -0,0 +1,23 @@ +@page +@model ErrorModel +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +@if (Model.ShowRequestId) +{ +

+ Request ID: @Model.RequestId +

+} + +

Development Mode

+

+ Swapping to the Development environment displays detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. It can result in displaying sensitive information from exceptions to end users. For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development and restarting the app or adding .UseEnvironment("Development") to WebHost in Program.cs and restarting the app. +

diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml.cs b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml.cs new file mode 100644 index 000000000000..6e5ae9327c1e --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Error.cshtml.cs @@ -0,0 +1,17 @@ +using System.Diagnostics; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace HttpSysSample.Pages +{ + public class ErrorModel : PageModel + { + public string RequestId { get; private set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + public void OnGet() + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml new file mode 100644 index 000000000000..3e34bda5655b --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml @@ -0,0 +1,28 @@ +@page +@model IndexModel +@{ + ViewData["Title"] = "HTTP.sys Demo"; +} + +

@ViewData["Title"]

+ +
+
+
+
+

Instructions

+
+
+

Run the app from a command prompt by executing the following command from the project's folder:

+

dotnet run

+

Logging indicates that the HttpSysListener is ready to receive requests:

+

+

info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
+    Start
+info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
+    Listening on prefix: http://localhost:5000/
+

+
+
+
+
diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml.cs b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml.cs new file mode 100644 index 000000000000..9b0aa8048871 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/Index.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace HttpSysSample.Pages +{ + public class IndexModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_Layout.cshtml b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_Layout.cshtml new file mode 100644 index 000000000000..4415f623a350 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_Layout.cshtml @@ -0,0 +1,70 @@ + + + + + + @ViewData["Title"] + + + + + + + + + + +
+
+ @RenderBody() +
+
+

©@System.DateTime.Now.Year - HTTP.sys Demo

+
+
+ + + + + + + + + + + + + @RenderSection("Scripts", required: false) + + diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewImports.cshtml b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewImports.cshtml new file mode 100644 index 000000000000..31bcc8509675 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using HttpSysSample +@namespace HttpSysSample.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewStart.cshtml b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewStart.cshtml new file mode 100644 index 000000000000..a5f10045db97 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Pages/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Program.cs b/aspnetcore/fundamentals/servers/httpsys/sample/Program.cs index dc8ed4850e63..0604d6824fe8 100644 --- a/aspnetcore/fundamentals/servers/httpsys/sample/Program.cs +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Program.cs @@ -1,38 +1,29 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Server.HttpSys; -using System; -// The default listening address is http://localhost:5000 if none is specified. - -namespace HttpSysDemo +namespace HttpSysSample { - /// - /// Executing the "dotnet run" command in the application folder will run this app. - /// public class Program { - #region snippet_Main public static void Main(string[] args) { - Console.WriteLine("Running demo with HTTP.sys."); - BuildWebHost(args).Run(); } + #region snippet1 public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() - #region snippet_Options .UseHttpSys(options => { + // The following options are set to default values. options.Authentication.Schemes = AuthenticationSchemes.None; options.Authentication.AllowAnonymous = true; - options.MaxConnections = 100; + options.MaxConnections = null; options.MaxRequestBodySize = 30000000; options.UrlPrefixes.Add("http://localhost:5000"); }) - #endregion .Build(); #endregion } diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/README.md b/aspnetcore/fundamentals/servers/httpsys/sample/README.md new file mode 100644 index 000000000000..cc8aba58b3f5 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/README.md @@ -0,0 +1,3 @@ +# ASP.NET Core HTTP.sys Sample + +This sample illustrates the use of HTTP.sys. This sample demonstrates the features described in the [HTTP.sys web server implementation](https://docs.microsoft.com/aspnet/core/fundamentals/servers/httpsys) topic. diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/Startup.cs b/aspnetcore/fundamentals/servers/httpsys/sample/Startup.cs index a41518f2bdaa..b8a0b23c712d 100644 --- a/aspnetcore/fundamentals/servers/httpsys/sample/Startup.cs +++ b/aspnetcore/fundamentals/servers/httpsys/sample/Startup.cs @@ -1,38 +1,49 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server.Features; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace HttpSysDemo +namespace HttpSysSample { public class Startup { - #region snippet_Configure - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) + public void ConfigureServices(IServiceCollection services) { - var serverAddressesFeature = app.ServerFeatures.Get(); - - app.UseStaticFiles(); + services.AddMvc(); + } - app.Run(async (context) => + #region snippet1 + public void Configure(IApplicationBuilder app, IHostingEnvironment env, + ILogger logger) + { + app.Use(async (context, next) => { context.Features.Get() .MaxRequestBodySize = 10 * 1024; - context.Response.ContentType = "text/html"; - await context.Response.WriteAsync("

Hosted by HTTP.sys

"); + var serverAddressesFeature = app.ServerFeatures.Get(); + var addresses = string.Join(", ", serverAddressesFeature?.Addresses); - if (serverAddressesFeature != null) - { - await context.Response.WriteAsync($"

Listening on the following addresses: {string.Join(", ", serverAddressesFeature.Addresses)}

"); - } + logger.LogInformation($"Addresses: {addresses}"); - await context.Response.WriteAsync($"

Request URL: {context.Request.GetDisplayUrl()}

"); + await next.Invoke(); }); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseDatabaseErrorPage(); + } + else + { + app.UseExceptionHandler("/Error"); + } + + app.UseStaticFiles(); + app.UseMvc(); } -#endregion + #endregion } } diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Development.json b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Development.json new file mode 100644 index 000000000000..fa8ce71a97a3 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Production.json b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Production.json new file mode 100644 index 000000000000..05d41950658c --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.Production.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Error", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.json b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.json new file mode 100644 index 000000000000..20aa907654ab --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug" + } + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/bower.json b/aspnetcore/fundamentals/servers/httpsys/sample/bower.json new file mode 100644 index 000000000000..b07e3cc5ae5d --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/bower.json @@ -0,0 +1,10 @@ +{ + "name": "asp.net", + "private": true, + "dependencies": { + "bootstrap": "3.3.7", + "jquery": "2.2.0", + "jquery-validation": "1.14.0", + "jquery-validation-unobtrusive": "3.2.6" + } +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/bundleconfig.json b/aspnetcore/fundamentals/servers/httpsys/sample/bundleconfig.json new file mode 100644 index 000000000000..6d3f9a57aea2 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/bundleconfig.json @@ -0,0 +1,24 @@ +// Configure bundling and minification for the project. +// More info at https://go.microsoft.com/fwlink/?LinkId=808241 +[ + { + "outputFileName": "wwwroot/css/site.min.css", + // An array of relative input file paths. Globbing patterns supported + "inputFiles": [ + "wwwroot/css/site.css" + ] + }, + { + "outputFileName": "wwwroot/js/site.min.js", + "inputFiles": [ + "wwwroot/js/site.js" + ], + // Optionally specify minification options + "minify": { + "enabled": true, + "renameLocals": true + }, + // Optionally generate .map file + "sourceMap": false + } +] diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.css b/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.css new file mode 100644 index 000000000000..64634c996c41 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.css @@ -0,0 +1,25 @@ +body { + padding-top: 50px; + padding-bottom: 20px; +} + +h1 { + font-size: 24px; +} + +h2 { + font-size: 20px; +} + +h3 { + font-size:16px +} + +.body-content { + padding-left: 15px; + padding-right: 15px; +} + +.panel-body { + font-size: 16px; +} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.min.css b/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.min.css new file mode 100644 index 000000000000..099af93ef1d3 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/css/site.min.css @@ -0,0 +1 @@ +body{padding-top:50px;padding-bottom:20px}h1{font-size:24px}h2{font-size:20px}h3{font-size:16px}.body-content{padding-left:15px;padding-right:15px}.panel-body{font-size:16px} diff --git a/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/favicon.ico b/aspnetcore/fundamentals/servers/httpsys/sample/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a3a799985c43bc7309d701b2cad129023377dc71 GIT binary patch literal 32038 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 [!NOTE] > HTTPS and HTTP cannot be hosted on the same port. -[!INCLUDE[How to make an SSL cert](../../includes/make-ssl-cert.md)] +[!INCLUDE[How to make an X.509 cert](../../includes/make-x509-cert.md)] --- ## Next steps diff --git a/aspnetcore/includes/make-ssl-cert.md b/aspnetcore/includes/make-ssl-cert.md deleted file mode 100644 index 8f0d7b1b4dc3..000000000000 --- a/aspnetcore/includes/make-ssl-cert.md +++ /dev/null @@ -1,3 +0,0 @@ -For generating self-signed SSL certificates on Windows, you can use the PowerShell cmdlet [New-SelfSignedCertificate](/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps). For a third-party tool that makes it easier for you to generate self-signed certificates, see [SelfCert](https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net). - -On macOS and Linux you can create a self-signed certificate using [OpenSSL](https://www.openssl.org/). diff --git a/aspnetcore/includes/make-x509-cert.md b/aspnetcore/includes/make-x509-cert.md new file mode 100644 index 000000000000..86354cf1b360 --- /dev/null +++ b/aspnetcore/includes/make-x509-cert.md @@ -0,0 +1,7 @@ +To create self-signed X.509 certificates on Windows, options include: + +* [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps) +* [SelfCert](https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net) +* [OpenSSL](https://www.openssl.org/) + +On macOS and Linux, self-signed certificates can be created using [OpenSSL](https://www.openssl.org/). From 275e35b1870fc74a2abf1c5ea47487592457b9ef Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 28 Feb 2018 18:36:47 -0600 Subject: [PATCH 2/4] Move MaxRequestBodySize to a section --- aspnetcore/fundamentals/servers/httpsys.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/aspnetcore/fundamentals/servers/httpsys.md b/aspnetcore/fundamentals/servers/httpsys.md index 9fce007f291e..f0aec2634cac 100644 --- a/aspnetcore/fundamentals/servers/httpsys.md +++ b/aspnetcore/fundamentals/servers/httpsys.md @@ -75,13 +75,27 @@ HTTP.sys is mature technology that protects against many types of attacks and pr | [EnableResponseCaching](/dotnet/api/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` | | [MaxAccepts](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxaccepts) | The maximum number of concurrent accepts. | 5 × [Environment.
ProcessorCount](/dotnet/api/system.environment.processorcount) | | [MaxConnections](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxconnections) | The maximum number of concurrent connections to accept. Use `-1` for infinite. Use `null` to use the registry's machine-wide setting. | `null`
(unlimited) | - | [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.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 [RequestSizeLimitAttribute](/dotnet/api/microsoft.aspnetcore.mvc.requestsizelimitattribute) attribute on an action method. For example, `[RequestSizeLimit(100000000)]`.

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.

| 30000000 bytes
(~28.6 MB) | + | [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxrequestbodysize) | See the MaxRequestBodySize section. | 30000000 bytes
(~28.6 MB) | | [RequestQueueLimit](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.requestqueuelimit) | The maximum number of requests that can be queued. | 1000 | | [ThrowWriteExceptions](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.throwwriteexceptions) | Indicate if response body writes that fail due to client disconnects should throw exceptions or complete normally. | `false`
(complete normally) | | [Timeouts](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts) | Expose the HTTP.sys [TimeoutManager](/dotnet/api/microsoft.aspnetcore.server.httpsys.timeoutmanager) configuration, which may also be configured in the registry. Follow the API links to learn more about each setting, including default values:
  • [Timeouts.DrainEntityBody](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.drainentitybody) – Time allowed for the HTTP Server API to drain the entity body on a Keep-Alive connection.
  • [Timeouts.EntityBody](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.entitybody) – Time allowed for the request entity body to arrive.
  • [Timeouts.HeaderWait](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.headerwait) – Time allowed for the HTTP Server API to parse the request header.
  • [Timeouts.IdleConnection](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.idleconnection) – Time allowed for an idle connection.
  • [Timeouts.MinSendBytesPerSecond](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.minsendbytespersecond) – The minimum send rate for the response.
  • [Timeouts.RequestQueue](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.timeouts.requestqueue) – Time allowed for the request to remain in the request queue before the app picks it up.
| | | [UrlPrefixes](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.urlprefixes) | Specify the [UrlPrefixCollection](/dotnet/api/microsoft.aspnetcore.server.httpsys.urlprefixcollection) to register with HTTP.sys. The most useful is [UrlPrefixCollection.Add](/dotnet/api/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. | | -1. If the app should override [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxrequestbodysize) per-request, use the [IHttpMaxRequestBodySizeFeature](/dotnet/api/microsoft.aspnetcore.http.features.ihttpmaxrequestbodysizefeature): + + **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 [RequestSizeLimitAttribute](/dotnet/api/microsoft.aspnetcore.mvc.requestsizelimitattribute) 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 [MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysoptions.maxrequestbodysize) per-request, use the [IHttpMaxRequestBodySizeFeature](/dotnet/api/microsoft.aspnetcore.http.features.ihttpmaxrequestbodysizefeature): [!code-csharp[](httpsys/sample/Startup.cs?name=snippet1&highlight=6-7)] From ce226749c2ee287fb025f3569a3d2a4d33e8db8b Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 28 Feb 2018 21:23:52 -0600 Subject: [PATCH 3/4] React to feedback --- aspnetcore/fundamentals/servers/httpsys.md | 9 +++++---- aspnetcore/includes/make-x509-cert.md | 7 +++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aspnetcore/fundamentals/servers/httpsys.md b/aspnetcore/fundamentals/servers/httpsys.md index f0aec2634cac..fbcd65b1764b 100644 --- a/aspnetcore/fundamentals/servers/httpsys.md +++ b/aspnetcore/fundamentals/servers/httpsys.md @@ -20,7 +20,8 @@ By [Tom Dykstra](https://github.com/tdykstra), [Chris Ross](https://github.com/T [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) and offers some features that Kestrel doesn't provide. -**Important!** HTTP.sys is incompatible with the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) and can't be used with IIS or IIS Express. +> [!IMPORTANT] +> HTTP.sys is incompatible with the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) and can't be used with IIS or IIS Express. HTTP.sys supports the following features: @@ -107,10 +108,10 @@ HTTP.sys is mature technology that protects against many types of attacks and pr ### Configure Windows Server -1. Install the .NET Core or ASP.NET 4.x framework if the app is a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd). +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 installer from [.NET Downloads](https://www.microsoft.com/net/download/windows). - * **ASP.NET 4.x** – If the app requires ASP.NET 4.x, see [.NET Framework: Installation guide](/dotnet/framework/install/) to find installation instructions. Install the required ASP.NET 4.x framework. The installer for the latest ASP.NET 4.x framework can be found at [.NET Downloads](https://www.microsoft.com/net/download/windows). + * **.NET Framework** – If the app requires .NET Framework, see [.NET Framework: Installation guide](/dotnet/framework/install/) to find installation instructions. Install the required .NET Framework. The installer for the latest .NET Framework can be found at [.NET Downloads](https://www.microsoft.com/net/download/windows). 1. Configure URLs and ports for the app. @@ -127,7 +128,7 @@ HTTP.sys is mature technology that protects against many types of attacks and pr 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 on `UseUrls`, `urls`, and `ASPNETCORE_URLS`, see [Hosting](xref:fundamentals/hosting). + 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 on `UseUrls`, `urls`, and `ASPNETCORE_URLS`, see [Hosting](xref:fundamentals/hosting). HTTP.sys uses the [HTTP Server API UrlPrefix string formats](https://msdn.microsoft.com/library/windows/desktop/aa364698.aspx). diff --git a/aspnetcore/includes/make-x509-cert.md b/aspnetcore/includes/make-x509-cert.md index 86354cf1b360..8cbc23f79846 100644 --- a/aspnetcore/includes/make-x509-cert.md +++ b/aspnetcore/includes/make-x509-cert.md @@ -1,7 +1,6 @@ -To create self-signed X.509 certificates on Windows, options include: +On macOS, Linux, and Windows, self-signed X.509 certificates can be created using [OpenSSL](https://www.openssl.org/). + +On Windows, additional options include: * [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps) * [SelfCert](https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net) -* [OpenSSL](https://www.openssl.org/) - -On macOS and Linux, self-signed certificates can be created using [OpenSSL](https://www.openssl.org/). From 1d34443fb22ab2096dc0bebe9ca6ee2e86c4050d Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Thu, 1 Mar 2018 17:25:28 -0600 Subject: [PATCH 4/4] React to feedback Update --- aspnetcore/includes/make-x509-cert.md | 7 +-- .../UpdateIISExpressSSLForChrome.ps1 | 63 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1 diff --git a/aspnetcore/includes/make-x509-cert.md b/aspnetcore/includes/make-x509-cert.md index 8cbc23f79846..f2e168a2caa9 100644 --- a/aspnetcore/includes/make-x509-cert.md +++ b/aspnetcore/includes/make-x509-cert.md @@ -1,6 +1,3 @@ -On macOS, Linux, and Windows, self-signed X.509 certificates can be created using [OpenSSL](https://www.openssl.org/). +On Windows, self-signed certificates can be created using the [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps). For an unsupported example, see [UpdateIISExpressSSLForChrome.ps1](https://github.com/aspnet/Docs/tree/master/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1). -On Windows, additional options include: - -* [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps) -* [SelfCert](https://www.pluralsight.com/blog/software-development/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net) +On macOS, Linux, and Windows, certificates can be created using [OpenSSL](https://www.openssl.org/). diff --git a/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1 b/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1 new file mode 100644 index 000000000000..756f4553bed3 --- /dev/null +++ b/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1 @@ -0,0 +1,63 @@ +# Create a new self-signed certificate for IIS Express. +# +# Provides a subjectAltName (SAN) to satisfy Chrome 58 or later. +# See https://bugs.chromium.org/p/chromium/issues/detail?id=308330 +# +# Run the script at an administrative PowerShell prompt. +# +# When prompted to trust a new certificate via a Windows dialog, +# select Yes. Otherwise, Visual Studio won't be able to determine +# the process ID when the web app is launched. +# +# THIS SCRIPT IS UNSUPPORTED BY MICROSOFT AND PROVIDED "AS IS" +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. + +$certificate = New-SelfSignedCertificate ` + -Subject localhost ` + -DnsName localhost ` + -KeyAlgorithm RSA ` + -KeyLength 2048 ` + -NotBefore (Get-Date) ` + -NotAfter (Get-Date).AddYears(5) ` + -CertStoreLocation "cert:CurrentUser\My" ` + -FriendlyName "IIS Express Development Certificate" ` + -HashAlgorithm SHA256 ` + -KeyUsage DigitalSignature, KeyEncipherment, DataEncipherment ` + -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1") +$certificatePath = 'Cert:\CurrentUser\My\' + ($certificate.ThumbPrint) + +# Export the certificate to a PFX (PKCS #12). +$pfxPassword = ConvertTo-SecureString ([Guid]::NewGuid().ToString()) -Force -AsPlainText +$pfxFilePath = [system.io.path]::GetTempFileName() +$cerFilePath = [system.io.path]::GetTempFileName() + +Export-PfxCertificate -Cert $certificatePath -FilePath $pfxFilePath -Password $pfxPassword +Export-Certificate -Cert $certificatePath -FilePath $cerFilePath + +# Now that the certificate has been exported, delete the cert. +Remove-Item $certificatePath + +# Add the certificate to the machine personal store, so netsh can bind. +Import-PfxCertificate -FilePath $pfxFilePath Cert:\LocalMachine\My -Password $pfxPassword -Exportable + +# Add the certificate to the user root store, so trust is enabled. +# When the prompt appears to trust a new certificate via a Windows dialog, +# select Yes. Otherwise, Visual Studio won't be able to determine the +# process ID when the web app is launched. +Import-Certificate -FilePath $cerFilePath -CertStoreLocation Cert:\CurrentUser\Root + +# Bind using netsh. The app ID is the IIS Express app ID. +for ($port = 44300; $port -lt 44400; $port++) +{ + $command = "http delete sslcert ipport=0.0.0.0:$port" + Write-Output $command + $command | netsh + + $command = "http add sslcert ipport=0.0.0.0:$port certhash="+$($certificate.Thumbprint)+" appid={214124cd-d05b-4309-9af9-9caa44b2b74a}" + Write-Output $command + $command | netsh +} + +# Clean up the temporary PFX. +Remove-Item $pfxFilePath +Remove-Item $cerFilePath