"
ASP.NET (snapshot 2017) Microsoft documentation and samples

HTTP.sys web server implementation in ASP.NET Core

By Tom Dykstra and Chris Ross

[!NOTE] This topic applies only to ASP.NET Core 2.0 and later. In earlier versions of ASP.NET Core, HTTP.sys is named (xref:)WebListener.

HTTP.sys is a web server for ASP.NET Core that runs only on Windows. It’s built on the Http.Sys kernel mode driver. HTTP.sys is an alternative to Kestrel that offers some features that Kestel doesn’t. HTTP.sys can’t be used with IIS or IIS Express, as it isn’t compatible with the ASP.NET Core Module.

HTTP.sys supports the following features:

Supported Windows versions:

View or download sample code ((xref:)how to download)

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
HTTP.sys communicates directly with the Internet

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
HTTP.sys communicates directly with your internal network

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

There are also Http.Sys registry settings.

Configure your ASP.NET Core application to use HTTP.sys

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-csharpMain]

   1:  using Microsoft.AspNetCore;
   2:  using Microsoft.AspNetCore.Hosting;
   3:  using Microsoft.AspNetCore.Server.HttpSys;
   4:  using System;
   5:   
   6:  // The default listening address is http://localhost:5000 if none is specified.
   7:   
   8:  namespace HttpSysDemo
   9:  {
  10:      /// <summary>
  11:      /// Executing the "dotnet run" command in the application folder will run this app.
  12:      /// </summary>
  13:      public class Program
  14:      {
  15:          #region snippet_Main
  16:          public static void Main(string[] args)
  17:          {
  18:              Console.WriteLine("Running demo with HTTP.sys.");
  19:   
  20:              BuildWebHost(args).Run();
  21:          }
  22:   
  23:          public static IWebHost BuildWebHost(string[] args) =>
  24:              WebHost.CreateDefaultBuilder(args)
  25:                  .UseStartup<Startup>()
  26:                  #region snippet_Options
  27:                  .UseHttpSys(options =>
  28:                  {
  29:                      options.Authentication.Schemes = AuthenticationSchemes.None;
  30:                      options.Authentication.AllowAnonymous = true;
  31:                      options.MaxConnections = 100;
  32:                      options.MaxRequestBodySize = 30000000;
  33:                      options.UrlPrefixes.Add("http://localhost:5000");
  34:                  })
  35:                  #endregion
  36:                  .Build();
  37:          #endregion
  38:      }
  39:  }

The maximum number of connections is unlimited (null) by default.

Maximum request body size

The default maximum request body size is 30,000,000 bytes, which is approximately 28.6MB.

The recommended way to override the limit in an ASP.NET Core MVC app is to use the RequestSizeLimit attribute on an action method:

Here’s an example that shows how to configure the constraint for the entire application, every request:

[!code-csharpMain]

   1:  using Microsoft.AspNetCore;
   2:  using Microsoft.AspNetCore.Hosting;
   3:  using Microsoft.AspNetCore.Server.HttpSys;
   4:  using System;
   5:   
   6:  // The default listening address is http://localhost:5000 if none is specified.
   7:   
   8:  namespace HttpSysDemo
   9:  {
  10:      /// <summary>
  11:      /// Executing the "dotnet run" command in the application folder will run this app.
  12:      /// </summary>
  13:      public class Program
  14:      {
  15:          #region snippet_Main
  16:          public static void Main(string[] args)
  17:          {
  18:              Console.WriteLine("Running demo with HTTP.sys.");
  19:   
  20:              BuildWebHost(args).Run();
  21:          }
  22:   
  23:          public static IWebHost BuildWebHost(string[] args) =>
  24:              WebHost.CreateDefaultBuilder(args)
  25:                  .UseStartup<Startup>()
  26:                  #region snippet_Options
  27:                  .UseHttpSys(options =>
  28:                  {
  29:                      options.Authentication.Schemes = AuthenticationSchemes.None;
  30:                      options.Authentication.AllowAnonymous = true;
  31:                      options.MaxConnections = 100;
  32:                      options.MaxRequestBodySize = 30000000;
  33:                      options.UrlPrefixes.Add("http://localhost:5000");
  34:                  })
  35:                  #endregion
  36:                  .Build();
  37:          #endregion
  38:      }
  39:  }

You can override the setting on a specific request in Startup.cs:

[!code-csharpMain]

   1:  using Microsoft.AspNetCore.Builder;
   2:  using Microsoft.AspNetCore.Hosting;
   3:  using Microsoft.AspNetCore.Hosting.Server.Features;
   4:  using Microsoft.AspNetCore.Http;
   5:  using Microsoft.AspNetCore.Http.Extensions;
   6:  using Microsoft.AspNetCore.Http.Features;
   7:  using Microsoft.Extensions.Logging;
   8:   
   9:  namespace HttpSysDemo
  10:  {
  11:      public class Startup
  12:      {
  13:          #region snippet_Configure
  14:          public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
  15:          {
  16:              var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();
  17:   
  18:              app.UseStaticFiles();
  19:   
  20:              app.Run(async (context) =>
  21:              {
  22:                  context.Features.Get<IHttpMaxRequestBodySizeFeature>()
  23:                      .MaxRequestBodySize = 10 * 1024;
  24:   
  25:                  context.Response.ContentType = "text/html";
  26:                  await context.Response.WriteAsync("<p>Hosted by HTTP.sys</p>");
  27:   
  28:                  if (serverAddressesFeature != null)
  29:                  {
  30:                      await context.Response.WriteAsync($"<p>Listening on the following addresses: {string.Join(", ", serverAddressesFeature.Addresses)}</p>");
  31:                  }
  32:   
  33:                  await context.Response.WriteAsync($"<p>Request URL: {context.Request.GetDisplayUrl()}</p>");
  34:              });
  35:          }
  36:  #endregion
  37:      }
  38:  }

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.

For information about other HTTP.sys options, see HttpSysOptions.

Configure URLs and ports to listen on

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. The following code example uses UrlPrefixes.

[!code-csharpMain]

   1:  using Microsoft.AspNetCore;
   2:  using Microsoft.AspNetCore.Hosting;
   3:  using Microsoft.AspNetCore.Server.HttpSys;
   4:  using System;
   5:   
   6:  // The default listening address is http://localhost:5000 if none is specified.
   7:   
   8:  namespace HttpSysDemo
   9:  {
  10:      /// <summary>
  11:      /// Executing the "dotnet run" command in the application folder will run this app.
  12:      /// </summary>
  13:      public class Program
  14:      {
  15:          #region snippet_Main
  16:          public static void Main(string[] args)
  17:          {
  18:              Console.WriteLine("Running demo with HTTP.sys.");
  19:   
  20:              BuildWebHost(args).Run();
  21:          }
  22:   
  23:          public static IWebHost BuildWebHost(string[] args) =>
  24:              WebHost.CreateDefaultBuilder(args)
  25:                  .UseStartup<Startup>()
  26:                  #region snippet_Options
  27:                  .UseHttpSys(options =>
  28:                  {
  29:                      options.Authentication.Schemes = AuthenticationSchemes.None;
  30:                      options.Authentication.AllowAnonymous = true;
  31:                      options.MaxConnections = 100;
  32:                      options.MaxRequestBodySize = 30000000;
  33:                      options.UrlPrefixes.Add("http://localhost:5000");
  34:                  })
  35:                  #endregion
  36:                  .Build();
  37:          #endregion
  38:      }
  39:  }

An advantage of UrlPrefixes is that you get an error message immediately if you try to add a prefix that is formatted wrong. An advantage of UseUrls (shared with urls and ASPNETCORE_URLS) is that you can more easily switch between Kestrel and HTTP.sys.

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 (xref:)Hosting.

HTTP.sys uses the HTTP Server API UrlPrefix string formats.

[!NOTE] Make sure that you specify the same prefix strings in UseUrls or UrlPrefixes that you preregister on the server.

Don’t use IIS

Make sure your application 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 application, manually change the selected profile, as shown in the following screen shot.

Select console app profile
Select console app profile

Preregister URL prefixes and configure SSL

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 is netsh.exe.

With netsh.exe you can reserve URL prefixes and assign SSL certificates. The tool requires administrative privileges.

The following example shows the minimum needed to reserve URL prefixes for ports 80 and 443:

netsh http add urlacl url=http://+:80/ user=Users
netsh http add urlacl url=https://+:443/ user=Users

The following example shows how to assign an SSL certificate:

netsh http add sslcert ipport=0.0.0.0:443 certhash=MyCertHash_Here appid={00000000-0000-0000-0000-000000000000}"

Here is the reference documentation for netsh.exe:

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.

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.

[!INCLUDEHow to make an SSL cert]

Next steps

For more information, see the following resources:



Comments ( )
Link to this page: //www.vb-net.com/AspNet-DocAndSamples-2017/aspnetcore/fundamentals/servers/httpsys.htm
< THANKS ME>