Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。
Warning
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
作成者: Tom Dykstra、Chris Ross
HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。
Important
HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。
HTTP.sys は、次の機能をサポートします。
- Windows 認証
- ポート共有
- SNI を使用する HTTPS
- HTTP/2 over TLS (Windows 10 以降)
- HTTP/3 over TLS (Windows 11 以降)
- 直接ファイル伝送
- 応答のキャッシュ
- WebSocket (Windows 8 以降)
- カスタマイズ可能なセキュリティ記述子
- 自動メモリ プールの削除
サポートされている Windows バージョン:
- Windows 7 以降
- Windows Server 2008 R2 以降
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
HTTP.sys を使用するタイミング
HTTP.sys は、次のような展開に適しています。
IIS を使用せず、インターネットに直接サーバーを公開する必要がある。
内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。
HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。
HTTP/2 のサポート
HTTP/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2016/Windows 10 以降
- アプリケーション レイヤー プロトコル ネゴシエーション (ALPN) 接続
- TLS 1.2 以降の接続
Http/2 接続が確立されると、HttpRequest.Protocol が HTTP/2 を報告します。
HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。
HTTP/3 のサポート
HTTP/3 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2022/Windows 11 以降。
-
httpsURL バインドが使用されている。 - EnableHttp3 レジストリ キーが設定されている。
以前のバージョンの Windows 11 ビルドでは、Windows Insider ビルドの使用が必要になる場合があります。
HTTP/3 は、alt-svc ヘッダーを介して HTTP/1.1 または HTTP/2 からのアップグレードとして検出されます。 これは、最初の要求では HTTP/3 に切り替える前に、通常 HTTP/1.1 または HTTP/2 が使用されることを意味します。 Http.Sys によって alt-svc ヘッダーは自動的に追加されないため、アプリケーションで追加する必要があります。 次のコードは、alt-svc 応答ヘッダーを追加するミドルウェアの例を示しています。
app.Use((context, next) =>
{
context.Response.Headers.AltSvc = "h3=\":443\"";
return next(context);
});
上記のコードを要求パイプラインの早い段階に配置します。
Http.Sys では、HTTP/3 が使用可能であることをクライアントに通知するために、応答ヘッダーではなく AltSvc HTTP/2 プロトコル メッセージの送信もサポートされています。 EnableAltSvc レジストリ キーに関するページを参照してください。 これには、IP アドレスではなくホスト名を使用する netsh sslcert バインドが必要です。
Kerberos を使用したカーネル モード認証
HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。
カーネル モード応答バッファリングのサポート
一部のシナリオでは、待機時間の長い少量の書き込みが大量に発生すると、HTTP.sys のパフォーマンスに大きな影響を与える場合があります。 この影響は、Pipe に HTTP.sys バッファーが実装されていないことが原因です。 これらのシナリオでパフォーマンスを向上させるため、HTTP.sys では応答バッファリングがサポートされています。
HttpSysOptions.EnableKernelResponseBuffering を true に設定して、バッファリングを有効にします。
応答バッファリングは、同期 I/O を実行するアプリで、または非同期 I/O で未処理の書き込みを一度に 1 つしか実行しないアプリで有効にする必要があります。 これらのシナリオでは、応答バッファリングにより、待機時間の長い接続に対してスループットが大幅に向上する場合があります。
非同期 I/O を使用し、未処理の書き込みを一度に複数実行する場合があるアプリでは、このフラグを使用しないでください。 このフラグを有効にすると、HTTP.Sys により CPU とメモリの使用率が高くなる場合があります。
HTTP.sys の使用方法
HTTP.sys を使用するように ASP.NET Core アプリを構成する
ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(options =>
{
options.AllowSynchronousIO = false;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30_000_000;
options.UrlPrefixes.Add("http://localhost:5005");
});
builder.Services.AddRazorPages();
var app = builder.Build();
HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。
HTTP.sys オプションの詳細については、「HttpSysOptions」を参照してください。
セキュリティ記述子をカスタマイズする
HTTP.sys の 要求キュー は、受信 HTTP 要求を処理する準備ができるまで一時的に格納するカーネル レベルの構造です。 の HttpSysOptions プロパティを使用して、要求キューへのアクセスを管理します。 HTTP.sys サーバーを構成するときに、 GenericSecurityDescriptor インスタンスに設定します。
セキュリティ記述子をカスタマイズすることで、要求キューへの特定のユーザーまたはグループのアクセスを許可または拒否できます。 これは、オペレーティング システム レベルで HTTP.sys 要求処理を制限または委任するシナリオで役立ちます。
たとえば、次のコードでは、認証されたすべてのユーザーが許可されますが、ゲストは拒否されます。
using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.AspNetCore.Server.HttpSys;
// Create a new security descriptor
var securityDescriptor = new CommonSecurityDescriptor(isContainer: false, isDS: false, sddlForm: string.Empty);
// Create a discretionary access control list (DACL)
var dacl = new DiscretionaryAcl(isContainer: false, isDS: false, capacity: 2);
dacl.AddAccess(
AccessControlType.Allow,
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
-1,
InheritanceFlags.None,
PropagationFlags.None
);
dacl.AddAccess(
AccessControlType.Deny,
new SecurityIdentifier(WellKnownSidType.BuiltinGuestsSid, null),
-1,
InheritanceFlags.None,
PropagationFlags.None
);
// Assign the DACL to the security descriptor
securityDescriptor.DiscretionaryAcl = dacl;
// Configure HTTP.sys options
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseHttpSys(options =>
{
options.RequestQueueSecurityDescriptor = securityDescriptor;
});
RequestQueueSecurityDescriptor プロパティは、新しい要求キューを作成する場合にのみ適用されます。 このプロパティは、既存の要求キューには影響しません。
MaxRequestBodySize
要求本文の最大許容サイズ (バイト単位) です。
null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。
1 つの IActionResult に対する ASP.NET Core MVC アプリの制限をオーバーライドする方法として、アクション メソッドに対して RequestSizeLimitAttribute 属性を使用することをお勧めします。
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
アプリが要求の読み取りを開始した後に、アプリが要求に対する制限を構成しようとすると、例外がスローされます。
IsReadOnly プロパティを使用して、MaxRequestBodySize プロパティが読み取り専用状態にあるかどうか、つまり制限を構成するには遅すぎるかどうかを示すことができます。
要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。
app.Use((context, next) =>
{
context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var server = context.RequestServices
.GetRequiredService<IServer>();
var serverAddressesFeature = server.Features
.GetRequiredFeature<IServerAddressesFeature>();
var addresses = string.Join(", ", serverAddressesFeature.Addresses);
var loggerFactory = context.RequestServices
.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
logger.LogInformation("Addresses: {addresses}", addresses);
return next(context);
});
Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。
Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーンショットに示すように、選択したプロファイルを手動で変更します。
Windows Server を構成する
アプリに対して開くポートを決めたら、Windows ファイアウォールか New-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
必要に応じて、X.509 証明書を取得してインストールします。
Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。
アプリが フレームワークに依存する展開である場合は、.NET、.NET Framework、またはその両方をインストールします (アプリが .NET Framework を対象とする .NET アプリの場合)。
- .NET: アプリに .NET が必要な場合は、.NET ダウンロードから .NET ランタイム インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
- .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは 、.NET ダウンロード ページから入手できます。
アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。
アプリに URL とポートを構成します。
既定では、ASP.NET Core は
http://localhost:5000にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。- UseUrls
-
urlsコマンド ライン引数 -
ASPNETCORE_URLS環境変数 - UrlPrefixes
次のコード例は、サーバーのローカル IP アドレス UrlPrefixes を使ってポート 443 上で
10.0.0.4を使う方法を示しています。var builder = WebApplication.CreateBuilder(args); builder.WebHost.UseHttpSys(options => { options.UrlPrefixes.Add("https://10.0.0.4:443"); }); builder.Services.AddRazorPages(); var app = builder.Build();UrlPrefixesの利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。UrlPrefixesの設定はUseUrls/urls/ASPNETCORE_URLSの設定をオーバーライドします。 したがって、UseUrls、urls、およびASPNETCORE_URLS環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。HTTP.sys は、URL プレフィックスで次の 2 種類のワイルドカードを認識します:
-
*は弱いバインディング であり、フォールバック バインディングとも呼ばれます。 URL プレフィックスがhttp://*:5000で、他の何かがポート 5000 にバインドされている場合、このバインディングは使用されません。 -
+は強力なバインディングです。 URL プレフィックスがhttp://+:5000の場合、このバインディングは他のポート 5000 バインドの前に使用されます。
詳細については、「UrlPrefix 文字列」を参照してください。
Warning
最上位のワイルドカードのバインド (
http://*:80/とhttp://+:80) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である*.comとは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。多くの場合、アプリとコンテナーには、リッスンするためのポート (ポート 80 など) のみが与えられます。ホストやパスなどの追加の制約は課せられません。 HTTP_PORTS と HTTPS_PORTS は、Kestrel および HTTP.sys サーバー用にリッスン ポートを指定するための構成キーです。 これらのキーは、
DOTNET_またはASPNETCORE_プレフィックスで定義された環境変数として指定することも、appsettings.jsonなどの他の構成入力を介して直接指定することもできます。 それぞれは、次の例に示すように、ポート値をセミコロンで区切ってリストしたものです。ASPNETCORE_HTTP_PORTS=80;8080 ASPNETCORE_HTTPS_PORTS=443;8081前述の例は、次の構成の省略形であり、スキーム (HTTP または HTTPS) と任意のホストまたは IP が指定されています。
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/HTTP_PORTS および HTTPS_PORTS 構成キーは優先度が低く、コードで直接指定された URL または値によってオーバーライドされます。 証明書は引き続き、HTTPS 用のサーバー固有のメカニズムを介して個別に構成する必要があります。
これらの構成キーは、最上位のワイルドカード バインドと同等です。 これらは開発およびコンテナーのシナリオには便利ですが、他のサービスもホストする可能性があるコンピューター上で実行する場合は、ワイルドカードを避けてください。
サーバーで URL プレフィックスを事前登録します。
HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。
netsh.exe ツールを使用して、アプリ用に URL を登録します。
netsh http add urlacl url=<URL> user=<USER>-
<URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 " -
<USER>:ユーザーまたはユーザー グループの名前を指定します。
次の例では、サーバーのローカル IP アドレスは
10.0.0.4です。netsh http add urlacl url=https://10.0.0.4:443/ user=UsersURL が登録されると、ツールから
URL reservation successfully addedという応答があります。登録済みの URL を削除するには、
delete urlaclコマンドを使用します。netsh http delete urlacl url=<URL>-
サーバーで X.509 証明書を登録します。
netsh.exe ツールを使用して、アプリ用の証明書を登録します。
netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"-
<IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。 -
<PORT>:バインド用のポートを指定します。 -
<THUMBPRINT>:X.509 証明書の拇印です。 -
<GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。
参照用に、この GUID をパッケージ タグとしてアプリに格納します。
- Visual Studio での操作: [][]
- ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
- [パッケージ] タブを選択します。
- 作成した GUID を [タグ] フィールドに入力します。
- Visual Studio を使用しない場合:
アプリのプロジェクト ファイルを開きます。
作成した GUID を指定した
<PackageTags>プロパティを、新規または既存の<PropertyGroup>に追加します。<PropertyGroup> <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags> </PropertyGroup>
次に例を示します。
- サーバーのローカル IP アドレスは
10.0.0.4です。 - オンラインのランダム GUID ジェネレーターによって、
appidの値が提供されます。
netsh http add sslcert ipport=10.0.0.4:443 certhash=b66ee04419d4ee37464ab8785ff02449980eae10 appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"証明書が登録されると、ツールから
SSL Certificate successfully addedという応答があります。証明書の登録を削除するには、
delete sslcertコマンドを使用します。netsh http delete sslcert ipport=<IP>:<PORT>以下は、netsh.exe のリファレンス ドキュメントです。
- Netsh Commands for Hypertext Transfer Protocol (HTTP) (ハイパーテキスト転送プロトコル (HTTP) 用の Netsh コマンド)
- UrlPrefix 文字列
-
アプリを実行します。
1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。
サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス
104.214.79.47でインターネットからアクセスされます。この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。
プロキシ サーバーとロード バランサーのシナリオ
インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。
IHttpSysRequestTimingFeature を使用して詳細なタイミング情報を取得する
IHttpSysRequestTimingFeature では、要求の詳細なタイミング情報が提供されます。
- タイムスタンプは、QueryPerformanceCounter を使用して取得されます。
- タイムスタンプの頻度は、QueryPerformanceFrequency を使用して取得できます。
- タイミングのインデックスを HttpSysRequestTimingType にキャストして、タイミングが何を表しているのかを把握できます。
- 現在の要求でタイミングを利用できない場合、値は 0 になることがあります。
- Windows 10 バージョン 2004、Windows Server 2022 以降が必要です。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var timestamps = feature.Timestamps;
for (var i = 0; i < timestamps.Length; i++)
{
var timestamp = timestamps[i];
var timingType = (HttpSysRequestTimingType)i;
logger.LogInformation("Timestamp {timingType}: {timestamp}",
timingType, timestamp);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
IHttpSysRequestTimingFeature.TryGetTimestamp では、指定されたタイミングの種類のタイムスタンプを取得します。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var timingType = HttpSysRequestTimingType.RequestRoutingEnd;
if (feature.TryGetTimestamp(timingType, out var timestamp))
{
logger.LogInformation("Timestamp {timingType}: {timestamp}",
timingType, timestamp);
}
else
{
logger.LogInformation("Timestamp {timingType}: not available for the "
+ "current request", timingType);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
[IHttpSysRequestTimingFeature.TryGetElapsedTime](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime は、指定された 2 つのタイミング間の経過時間を生成します。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;
if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
{
logger.LogInformation(
"Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
startingTimingType,
endingTimingType,
elapsed);
}
else
{
logger.LogInformation(
"Elapsed time {startingTimingType} to {endingTimingType}:"
+ " not available for the current request.",
startingTimingType,
endingTimingType);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
gRPC をサポートする高度な HTTP/2 機能
HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。
HTTP.sys で gRPC を実行するための要件:
- Windows 11 ビルド 22000 またはそれ以降、Windows Server 2022 ビルド 20348 またはそれ以降が必要です。
- TLS 1.2 またはそれ以降の接続。
Trailers
HTTP トレーラーは HTTP ヘッダーに似ていますが、応答本文の送信後に送信される点が異なります。 IIS と HTTP.sys の場合は、HTTP/2 応答トレーラーのみがサポートされています。
if (httpContext.Response.SupportsTrailers())
{
httpContext.Response.DeclareTrailer("trailername");
// Write body
httpContext.Response.WriteAsync("Hello world");
httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}
上記のコード例では次のようになっています。
-
SupportsTrailersによって、応答におけるトレーラーが確実にサポートされます。 -
DeclareTrailerによって、指定したトレーラー名がTrailer応答ヘッダーに追加されます。 応答のトレーラーを宣言することは省略可能ですが、推奨されています。DeclareTrailerを呼び出す場合、それは、応答ヘッダーを送信する前に行う必要があります。 -
AppendTrailerによって、トレーラーが追加されます。
Reset
リセットを使用すると、指定されたエラー コードを使用してサーバーに HTTP/2 要求をリセットさせることができます。 リセット要求は中止されたと見なされます。
var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);
上記のコード例の Reset により、INTERNAL_ERROR エラー コードが指定されています。 HTTP/2 エラー コードの詳細については、HTTP/2 仕様の「エラーコード」セクションを参照してください。
Tracing
HTTP.sys からトレースを取得する方法については、「HTTP.sys 管理のシナリオ」を参照してください。
メモリ プールからの自動削除
Kestrel、IIS、および HTTP.sys によって使用されるメモリ プールは、アプリケーションがアイドル状態または負荷が低い場合に、メモリ ブロックを自動的に削除します。 この機能は自動的に実行され、手動で有効または構成する必要はありません。
10 より前のバージョンの .NET では、プールによって割り当てられたメモリは、使用されていない場合でも予約されたままになります。 この自動削除機能は、全体的なメモリ使用量を削減し、さまざまなワークロードでアプリケーションの応答性を維持するのに役立ちます。
メモリプールの指標を使用する
ASP.NET Core サーバーの実装で使用される既定のメモリ プールには、メモリ使用量パターンの監視と分析に使用できるメトリックが含まれています。 メトリックは、 "Microsoft.AspNetCore.MemoryPool"という名前の下にあります。
メトリックとその使用方法については、「 ASP.NET コア メトリック」を参照してください。
メモリ プールの管理
不要なメモリ ブロックを削除してメモリ プールを効率的に使用するだけでなく、ASP.NET Core には組み込みの IMemoryPoolFactory と実装が用意されています。 依存関係の挿入により、アプリケーションで実装を使用できるようになります。
次のコード例は、組み込みのメモリ プール ファクトリ実装を使用してメモリ プールを作成する単純なバックグラウンド サービスを示しています。 これらのプールは、自動削除機能の利点があります。
public class MyBackgroundService : BackgroundService
{
private readonly MemoryPool<byte> _memoryPool;
public MyBackgroundService(IMemoryPoolFactory<byte> factory)
{
_memoryPool = factory.Create();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await Task.Delay(20, stoppingToken);
// do work that needs memory
// consider checking _memoryPool.MaxBufferSize
var rented = _memoryPool.Rent(100);
rented.Dispose();
}
catch (OperationCanceledException)
{
return;
}
}
}
}
カスタム メモリ プール ファクトリを使用するには、次の例のように、 IMemoryPoolFactory を実装するクラスを作成し、依存関係の挿入に登録します。 この方法で作成されたメモリ プールは、自動削除機能の恩恵も受けられます。
services.AddSingleton<IMemoryPoolFactory<byte>,
CustomMemoryPoolFactory>();
public class CustomMemoryPoolFactory : IMemoryPoolFactory<byte>
{
public MemoryPool<byte> Create()
{
// Return a custom MemoryPool implementation
// or the default, as is shown here.
return MemoryPool<byte>.Shared;
}
}
メモリ プールを使用している場合は、プールの MaxBufferSizeに注意してください。
その他のリソース
HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。
Important
HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。
HTTP.sys は、次の機能をサポートします。
- Windows 認証
- ポート共有
- SNI を使用する HTTPS
- HTTP/2 over TLS (Windows 10 以降)
- 直接ファイル伝送
- 応答のキャッシュ
- WebSocket (Windows 8 以降)
サポートされている Windows バージョン:
- Windows 7 以降
- Windows Server 2008 R2 以降
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
HTTP.sys を使用するタイミング
HTTP.sys は、次のような展開に適しています。
IIS を使用せず、インターネットに直接サーバーを公開する必要がある。
内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。
HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。
HTTP/2 のサポート
HTTP/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2016/Windows 10 以降
- アプリケーション レイヤー プロトコル ネゴシエーション (ALPN) 接続
- TLS 1.2 以降の接続
Http/2 接続が確立されると、HttpRequest.Protocol が HTTP/2 を報告します。
HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。
HTTP/3 のサポート
HTTP/3 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2022/Windows 11 以降。
-
httpsURL バインドが使用されている。 - EnableHttp3 レジストリ キーが設定されている。
以前のバージョンの Windows 11 ビルドでは、Windows Insider ビルドの使用が必要になる場合があります。
HTTP/3 は、alt-svc ヘッダーを介して HTTP/1.1 または HTTP/2 からのアップグレードとして検出されます。 これは、最初の要求では HTTP/3 に切り替える前に、通常 HTTP/1.1 または HTTP/2 が使用されることを意味します。 Http.Sys によって alt-svc ヘッダーは自動的に追加されないため、アプリケーションで追加する必要があります。 次のコードは、alt-svc 応答ヘッダーを追加するミドルウェアの例を示しています。
app.Use((context, next) =>
{
context.Response.Headers.AltSvc = "h3=\":443\"";
return next(context);
});
上記のコードを要求パイプラインの早い段階に配置します。
Http.Sys では、HTTP/3 が使用可能であることをクライアントに通知するために、応答ヘッダーではなく AltSvc HTTP/2 プロトコル メッセージの送信もサポートされています。 EnableAltSvc レジストリ キーに関するページを参照してください。 これには、IP アドレスではなくホスト名を使用する netsh sslcert バインドが必要です。
Kerberos を使用したカーネル モード認証
HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。
HTTP.sys の使用方法
HTTP.sys を使用するように ASP.NET Core アプリを構成する
ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = false;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
options.UrlPrefixes.Add("http://localhost:5005");
});
webBuilder.UseStartup<Startup>();
});
HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。
HTTP.sys オプションの詳細については、「HttpSysOptions」を参照してください。
MaxRequestBodySize
要求本文の最大許容サイズ (バイト単位) です。
null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。
1 つの IActionResult に対する ASP.NET Core MVC アプリの制限をオーバーライドする方法として、アクション メソッドに対して RequestSizeLimitAttribute 属性を使用することをお勧めします。
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
アプリが要求の読み取りを開始した後に、アプリが要求に対する制限を構成しようとすると、例外がスローされます。
IsReadOnly プロパティを使用して、MaxRequestBodySize プロパティが読み取り専用状態にあるかどうか、つまり制限を構成するには遅すぎるかどうかを示すことができます。
要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
ILogger<Startup> logger, IServer server)
{
app.Use(async (context, next) =>
{
context.Features.Get<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
var addresses = string.Join(", ", serverAddressesFeature?.Addresses);
logger.LogInformation("Addresses: {Addresses}", addresses);
await next.Invoke();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。
Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーンショットに示すように、選択したプロファイルを手動で変更します。
Windows Server を構成する
アプリに対して開くポートを決めたら、Windows ファイアウォールか New-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
必要に応じて、X.509 証明書を取得してインストールします。
Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。
アプリが フレームワークに依存する展開である場合は、.NET、.NET Framework、またはその両方をインストールします (アプリが .NET Framework を対象とする .NET アプリの場合)。
- .NET: アプリに .NET が必要な場合は、.NET ダウンロードから .NET ランタイム インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
- .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは 、.NET ダウンロード ページから入手できます。
アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。
アプリに URL とポートを構成します。
既定では、ASP.NET Core は
http://localhost:5000にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。- UseUrls
-
urlsコマンド ライン引数 -
ASPNETCORE_URLS環境変数 - UrlPrefixes
次のコード例は、サーバーのローカル IP アドレス UrlPrefixes を使ってポート 443 上で
10.0.0.4を使う方法を示しています。public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseHttpSys(options => { options.UrlPrefixes.Add("https://10.0.0.4:443"); }); webBuilder.UseStartup<Startup>(); });UrlPrefixesの利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。UrlPrefixesの設定はUseUrls/urls/ASPNETCORE_URLSの設定をオーバーライドします。 したがって、UseUrls、urls、およびASPNETCORE_URLS環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。HTTP.sys では、HTTP サーバー API の UrlPrefix 文字列形式が使用されます。
Warning
最上位のワイルドカードのバインド (
http://*:80/とhttp://+:80) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である*.comとは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。サーバーで URL プレフィックスを事前登録します。
HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。
netsh.exe ツールを使用して、アプリ用に URL を登録します。
netsh http add urlacl url=<URL> user=<USER>-
<URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 " -
<USER>:ユーザーまたはユーザー グループの名前を指定します。
次の例では、サーバーのローカル IP アドレスは
10.0.0.4です。netsh http add urlacl url=https://10.0.0.4:443/ user=UsersURL が登録されると、ツールから
URL reservation successfully addedという応答があります。登録済みの URL を削除するには、
delete urlaclコマンドを使用します。netsh http delete urlacl url=<URL>-
サーバーで X.509 証明書を登録します。
netsh.exe ツールを使用して、アプリ用の証明書を登録します。
netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"-
<IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。 -
<PORT>:バインド用のポートを指定します。 -
<THUMBPRINT>:X.509 証明書の拇印です。 -
<GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。
参照用に、この GUID をパッケージ タグとしてアプリに格納します。
- Visual Studio での操作: [][]
- ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
- [パッケージ] タブを選択します。
- 作成した GUID を [タグ] フィールドに入力します。
- Visual Studio を使用しない場合:
アプリのプロジェクト ファイルを開きます。
作成した GUID を指定した
<PackageTags>プロパティを、新規または既存の<PropertyGroup>に追加します。<PropertyGroup> <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags> </PropertyGroup>
次に例を示します。
- サーバーのローカル IP アドレスは
10.0.0.4です。 - オンラインのランダム GUID ジェネレーターによって、
appidの値が提供されます。
netsh http add sslcert ipport=10.0.0.4:443 certhash=b66ee04419d4ee37464ab8785ff02449980eae10 appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"証明書が登録されると、ツールから
SSL Certificate successfully addedという応答があります。証明書の登録を削除するには、
delete sslcertコマンドを使用します。netsh http delete sslcert ipport=<IP>:<PORT>以下は、netsh.exe のリファレンス ドキュメントです。
- Netsh Commands for Hypertext Transfer Protocol (HTTP) (ハイパーテキスト転送プロトコル (HTTP) 用の Netsh コマンド)
- UrlPrefix 文字列
-
アプリを実行します。
1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。
サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス
104.214.79.47でインターネットからアクセスされます。この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。
プロキシ サーバーとロード バランサーのシナリオ
インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。
gRPC をサポートする高度な HTTP/2 機能
HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。
HTTP.sys で gRPC を実行するための要件:
- Windows 11 ビルド 22000 またはそれ以降、Windows Server 2022 ビルド 20348 またはそれ以降が必要です。
- TLS 1.2 またはそれ以降の接続。
Trailers
HTTP トレーラーは HTTP ヘッダーに似ていますが、応答本文の送信後に送信される点が異なります。 IIS と HTTP.sys の場合は、HTTP/2 応答トレーラーのみがサポートされています。
if (httpContext.Response.SupportsTrailers())
{
httpContext.Response.DeclareTrailer("trailername");
// Write body
httpContext.Response.WriteAsync("Hello world");
httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}
上記のコード例では次のようになっています。
-
SupportsTrailersによって、応答におけるトレーラーが確実にサポートされます。 -
DeclareTrailerによって、指定したトレーラー名がTrailer応答ヘッダーに追加されます。 応答のトレーラーを宣言することは省略可能ですが、推奨されています。DeclareTrailerを呼び出す場合、それは、応答ヘッダーを送信する前に行う必要があります。 -
AppendTrailerによって、トレーラーが追加されます。
Reset
リセットを使用すると、指定されたエラー コードを使用してサーバーに HTTP/2 要求をリセットさせることができます。 リセット要求は中止されたと見なされます。
var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);
上記のコード例の Reset により、INTERNAL_ERROR エラー コードが指定されています。 HTTP/2 エラー コードの詳細については、HTTP/2 仕様の「エラーコード」セクションを参照してください。
その他のリソース
HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。
Important
HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。
HTTP.sys は、次の機能をサポートします。
- Windows 認証
- ポート共有
- SNI を使用する HTTPS
- HTTP/2 over TLS (Windows 10 以降)
- 直接ファイル伝送
- 応答のキャッシュ
- WebSocket (Windows 8 以降)
サポートされている Windows バージョン:
- Windows 7 以降
- Windows Server 2008 R2 以降
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
HTTP.sys を使用するタイミング
HTTP.sys は、次のような展開に適しています。
IIS を使用せず、インターネットに直接サーバーを公開する必要がある。
内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。
HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。
HTTP/2 のサポート
Http/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2016/Windows 10 以降
- アプリケーション レイヤー プロトコル ネゴシエーション (ALPN) 接続
- TLS 1.2 以降の接続
Http/2 接続が確立されると、HttpRequest.Protocol が HTTP/2 を報告します。
HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。
Kerberos を使用したカーネル モード認証
HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。
HTTP.sys の使用方法
HTTP.sys を使用するように ASP.NET Core アプリを構成する
ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = false;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
options.UrlPrefixes.Add("http://localhost:5005");
});
webBuilder.UseStartup<Startup>();
});
HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。
HTTP.sys オプション
| Property | Description | Default |
|---|---|---|
| AllowSynchronousIO |
HttpContext.Request.Body および HttpContext.Response.Body に対して、入力/出力の同期を許可するかどうかを制御します。 |
false |
| Authentication.AllowAnonymous | 匿名要求を許可します。 | true |
| Authentication.Schemes | 許可される認証方式を指定します。 リスナーを破棄する前ならいつでも変更できます。 値は AuthenticationSchemes 列挙型 (Basic、Kerberos、Negotiate、None、および NTLM) によって指定します。 |
None |
| EnableResponseCaching | 対象となるヘッダーを持つ応答に対して、カーネル モードのキャッシュを試行します。
Set-Cookie、Vary、または Pragma ヘッダーを含む応答は対象外です。 応答は、Cache-Control である public ヘッダーと shared-max-age または max-age の値のいずれかを含むか、または Expires ヘッダーを含む必要があります。 |
true |
| Http503Verbosity | 調整の条件によって要求を拒否する場合の HTTP.sys の動作。 |
Http503VerbosityLevel。 基本的な |
| MaxAccepts | 同時受け入れの最大数です。 | 5 × 環境。 プロセッサ数 |
| MaxConnections | 受け入れるコンカレント接続の最大数です。 無限にするには、-1 を使用します。 コンピューター全体のレジストリ設定を使用するには、null を使用します。 |
null(machine-wide setting) |
| MaxRequestBodySize | 「MaxRequestBodySize」セクションを参照してください。 | 30000000 バイト (最大 28.6 MB) |
| RequestQueueLimit | キューに置くことができる要求の最大数。 | 1000 |
RequestQueueMode |
これは、サーバーで要求キューの作成と構成を行う必要があるかどうか、または既存のキューにアタッチする必要があるかを示します。 既存のキューにアタッチする場合、既存の構成オプションのほとんどは適用されません。 |
RequestQueueMode.Create |
RequestQueueName |
HTTP.sys 要求キューの名前。 |
null (匿名キュー) |
| ThrowWriteExceptions | 応答本文の書き込みがクライアントの接続の切断によって失敗した場合、例外をスローするか、または正常に完了するかどうかを指定します。 | false(正常に完了) |
| Timeouts | HTTP.sys TimeoutManager 構成を公開します。これはレジストリでも構成できます。 各設定に関する既定値などの詳細については、API のリンクを参照してください。
|
|
| UrlPrefixes | HTTP.sys に登録する UrlPrefixCollection を指定します。 最も便利なのは UrlPrefixCollection.Add です。これを使用して、コレクションにプレフィックスを追加できます。 これらは、リスナーを破棄する前ならいつでも変更できます。 |
MaxRequestBodySize
要求本文の最大許容サイズ (バイト単位) です。
null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。
1 つの IActionResult に対する ASP.NET Core MVC アプリの制限をオーバーライドする方法として、アクション メソッドに対して RequestSizeLimitAttribute 属性を使用することをお勧めします。
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
アプリが要求の読み取りを開始した後に、アプリが要求に対する制限を構成しようとすると、例外がスローされます。
IsReadOnly プロパティを使用して、MaxRequestBodySize プロパティが読み取り専用状態にあるかどうか、つまり制限を構成するには遅すぎるかどうかを示すことができます。
要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
ILogger<Startup> logger, IServer server)
{
app.Use(async (context, next) =>
{
context.Features.Get<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
var addresses = string.Join(", ", serverAddressesFeature?.Addresses);
logger.LogInformation("Addresses: {Addresses}", addresses);
await next.Invoke();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。
Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーン ショットに示すように、選択したプロファイルを手動で変更します。
Windows Server を構成する
アプリに対して開くポートを決めたら、Windows ファイアウォールか New-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
必要に応じて、X.509 証明書を取得してインストールします。
Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。
アプリが フレームワークに依存する展開である場合は、.NET、.NET Framework、またはその両方をインストールします (アプリが .NET Framework を対象とする .NET アプリの場合)。
- .NET: アプリに .NET が必要な場合は、.NET ダウンロードから .NET ランタイム インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
- .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは 、.NET ダウンロード ページから入手できます。
アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。
アプリに URL とポートを構成します。
既定では、ASP.NET Core は
http://localhost:5000にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。- UseUrls
-
urlsコマンド ライン引数 -
ASPNETCORE_URLS環境変数 - UrlPrefixes
次のコード例は、サーバーのローカル IP アドレス UrlPrefixes を使ってポート 443 上で
10.0.0.4を使う方法を示しています。public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseHttpSys(options => { options.UrlPrefixes.Add("https://10.0.0.4:443"); }); webBuilder.UseStartup<Startup>(); });UrlPrefixesの利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。UrlPrefixesの設定はUseUrls/urls/ASPNETCORE_URLSの設定をオーバーライドします。 したがって、UseUrls、urls、およびASPNETCORE_URLS環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。HTTP.sys では、HTTP サーバー API の UrlPrefix 文字列形式が使用されます。
Warning
最上位のワイルドカードのバインド (
http://*:80/とhttp://+:80) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である*.comとは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。サーバーで URL プレフィックスを事前登録します。
HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。
netsh.exe ツールを使用して、アプリ用に URL を登録します。
netsh http add urlacl url=<URL> user=<USER>-
<URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 " -
<USER>:ユーザーまたはユーザー グループの名前を指定します。
次の例では、サーバーのローカル IP アドレスは
10.0.0.4です。netsh http add urlacl url=https://10.0.0.4:443/ user=UsersURL が登録されると、ツールから
URL reservation successfully addedという応答があります。登録済みの URL を削除するには、
delete urlaclコマンドを使用します。netsh http delete urlacl url=<URL>-
サーバーで X.509 証明書を登録します。
netsh.exe ツールを使用して、アプリ用の証明書を登録します。
netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"-
<IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。 -
<PORT>:バインド用のポートを指定します。 -
<THUMBPRINT>:X.509 証明書の拇印です。 -
<GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。
参照用に、この GUID をパッケージ タグとしてアプリに格納します。
- Visual Studio での操作: [][]
- ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
- [パッケージ] タブを選択します。
- 作成した GUID を [タグ] フィールドに入力します。
- Visual Studio を使用しない場合:
アプリのプロジェクト ファイルを開きます。
作成した GUID を指定した
<PackageTags>プロパティを、新規または既存の<PropertyGroup>に追加します。<PropertyGroup> <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags> </PropertyGroup>
次に例を示します。
- サーバーのローカル IP アドレスは
10.0.0.4です。 - オンラインのランダム GUID ジェネレーターによって、
appidの値が提供されます。
netsh http add sslcert ipport=10.0.0.4:443 certhash=b66ee04419d4ee37464ab8785ff02449980eae10 appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"証明書が登録されると、ツールから
SSL Certificate successfully addedという応答があります。証明書の登録を削除するには、
delete sslcertコマンドを使用します。netsh http delete sslcert ipport=<IP>:<PORT>以下は、netsh.exe のリファレンス ドキュメントです。
- Netsh Commands for Hypertext Transfer Protocol (HTTP) (ハイパーテキスト転送プロトコル (HTTP) 用の Netsh コマンド)
- UrlPrefix 文字列
-
アプリを実行します。
1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。
サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス
104.214.79.47でインターネットからアクセスされます。この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。
プロキシ サーバーとロード バランサーのシナリオ
インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。
gRPC をサポートする高度な HTTP/2 機能
HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。
HTTP.sys で gRPC を実行するための要件:
- Windows 10、OS Build 19041.508 以降
- TLS 1.2 以降の接続
Trailers
HTTP トレーラーは HTTP ヘッダーに似ていますが、応答本文の送信後に送信される点が異なります。 IIS と HTTP.sys の場合は、HTTP/2 応答トレーラーのみがサポートされています。
if (httpContext.Response.SupportsTrailers())
{
httpContext.Response.DeclareTrailer("trailername");
// Write body
httpContext.Response.WriteAsync("Hello world");
httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}
上記のコード例では次のようになっています。
-
SupportsTrailersによって、応答におけるトレーラーが確実にサポートされます。 -
DeclareTrailerによって、指定したトレーラー名がTrailer応答ヘッダーに追加されます。 応答のトレーラーを宣言することは省略可能ですが、推奨されています。DeclareTrailerを呼び出す場合、それは、応答ヘッダーを送信する前に行う必要があります。 -
AppendTrailerによって、トレーラーが追加されます。
Reset
リセットを使用すると、指定されたエラー コードを使用してサーバーに HTTP/2 要求をリセットさせることができます。 リセット要求は中止されたと見なされます。
var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);
上記のコード例の Reset により、INTERNAL_ERROR エラー コードが指定されています。 HTTP/2 エラー コードの詳細については、HTTP/2 仕様の「エラーコード」セクションを参照してください。
その他のリソース
HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。
Important
HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。
HTTP.sys は、次の機能をサポートします。
- Windows 認証
- ポート共有
- SNI を使用する HTTPS
- HTTP/2 over TLS (Windows 10 以降)
- HTTP/3 over TLS (Windows 11 以降)
- 直接ファイル伝送
- 応答のキャッシュ
- WebSocket (Windows 8 以降)
- カスタマイズ可能なセキュリティ記述子
サポートされている Windows バージョン:
- Windows 7 以降
- Windows Server 2008 R2 以降
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
HTTP.sys を使用するタイミング
HTTP.sys は、次のような展開に適しています。
IIS を使用せず、インターネットに直接サーバーを公開する必要がある。
内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。
HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。
HTTP/2 のサポート
HTTP/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2016/Windows 10 以降
- アプリケーション レイヤー プロトコル ネゴシエーション (ALPN) 接続
- TLS 1.2 以降の接続
Http/2 接続が確立されると、HttpRequest.Protocol が HTTP/2 を報告します。
HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。
HTTP/3 のサポート
HTTP/3 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。
- Windows Server 2022/Windows 11 以降。
-
httpsURL バインドが使用されている。 - EnableHttp3 レジストリ キーが設定されている。
以前のバージョンの Windows 11 ビルドでは、Windows Insider ビルドの使用が必要になる場合があります。
HTTP/3 は、alt-svc ヘッダーを介して HTTP/1.1 または HTTP/2 からのアップグレードとして検出されます。 これは、最初の要求では HTTP/3 に切り替える前に、通常 HTTP/1.1 または HTTP/2 が使用されることを意味します。 Http.Sys によって alt-svc ヘッダーは自動的に追加されないため、アプリケーションで追加する必要があります。 次のコードは、alt-svc 応答ヘッダーを追加するミドルウェアの例を示しています。
app.Use((context, next) =>
{
context.Response.Headers.AltSvc = "h3=\":443\"";
return next(context);
});
上記のコードを要求パイプラインの早い段階に配置します。
Http.Sys では、HTTP/3 が使用可能であることをクライアントに通知するために、応答ヘッダーではなく AltSvc HTTP/2 プロトコル メッセージの送信もサポートされています。 EnableAltSvc レジストリ キーに関するページを参照してください。 これには、IP アドレスではなくホスト名を使用する netsh sslcert バインドが必要です。
Kerberos を使用したカーネル モード認証
HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。
カーネル モード応答バッファリングのサポート
一部のシナリオでは、待機時間の長い少量の書き込みが大量に発生すると、HTTP.sys のパフォーマンスに大きな影響を与える場合があります。 この影響は、Pipe に HTTP.sys バッファーが実装されていないことが原因です。 これらのシナリオでパフォーマンスを向上させるため、HTTP.sys では応答バッファリングがサポートされています。
HttpSysOptions.EnableKernelResponseBuffering を true に設定して、バッファリングを有効にします。
応答バッファリングは、同期 I/O を実行するアプリで、または非同期 I/O で未処理の書き込みを一度に 1 つしか実行しないアプリで有効にする必要があります。 これらのシナリオでは、応答バッファリングにより、待機時間の長い接続に対してスループットが大幅に向上する場合があります。
非同期 I/O を使用し、未処理の書き込みを一度に複数実行する場合があるアプリでは、このフラグを使用しないでください。 このフラグを有効にすると、HTTP.Sys により CPU とメモリの使用率が高くなる場合があります。
HTTP.sys の使用方法
HTTP.sys を使用するように ASP.NET Core アプリを構成する
ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(options =>
{
options.AllowSynchronousIO = false;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30_000_000;
options.UrlPrefixes.Add("http://localhost:5005");
});
builder.Services.AddRazorPages();
var app = builder.Build();
HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。
HTTP.sys オプションの詳細については、「HttpSysOptions」を参照してください。
MaxRequestBodySize
要求本文の最大許容サイズ (バイト単位) です。
null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。
1 つの IActionResult に対する ASP.NET Core MVC アプリの制限をオーバーライドする方法として、アクション メソッドに対して RequestSizeLimitAttribute 属性を使用することをお勧めします。
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
アプリが要求の読み取りを開始した後に、アプリが要求に対する制限を構成しようとすると、例外がスローされます。
IsReadOnly プロパティを使用して、MaxRequestBodySize プロパティが読み取り専用状態にあるかどうか、つまり制限を構成するには遅すぎるかどうかを示すことができます。
要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。
app.Use((context, next) =>
{
context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var server = context.RequestServices
.GetRequiredService<IServer>();
var serverAddressesFeature = server.Features
.GetRequiredFeature<IServerAddressesFeature>();
var addresses = string.Join(", ", serverAddressesFeature.Addresses);
var loggerFactory = context.RequestServices
.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
logger.LogInformation("Addresses: {addresses}", addresses);
return next(context);
});
Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。
Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーンショットに示すように、選択したプロファイルを手動で変更します。
Windows Server を構成する
アプリに対して開くポートを決めたら、Windows ファイアウォールか New-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。
必要に応じて、X.509 証明書を取得してインストールします。
Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。
アプリが フレームワークに依存する展開である場合は、.NET、.NET Framework、またはその両方をインストールします (アプリが .NET Framework を対象とする .NET アプリの場合)。
- .NET: アプリに .NET が必要な場合は、.NET ダウンロードから .NET ランタイム インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
- .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは 、.NET ダウンロード ページから入手できます。
アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。
アプリに URL とポートを構成します。
既定では、ASP.NET Core は
http://localhost:5000にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。- UseUrls
-
urlsコマンド ライン引数 -
ASPNETCORE_URLS環境変数 - UrlPrefixes
次のコード例は、サーバーのローカル IP アドレス UrlPrefixes を使ってポート 443 上で
10.0.0.4を使う方法を示しています。var builder = WebApplication.CreateBuilder(args); builder.WebHost.UseHttpSys(options => { options.UrlPrefixes.Add("https://10.0.0.4:443"); }); builder.Services.AddRazorPages(); var app = builder.Build();UrlPrefixesの利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。UrlPrefixesの設定はUseUrls/urls/ASPNETCORE_URLSの設定をオーバーライドします。 したがって、UseUrls、urls、およびASPNETCORE_URLS環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。HTTP.sys は、URL プレフィックスで次の 2 種類のワイルドカードを認識します:
-
*は弱いバインディング であり、フォールバック バインディングとも呼ばれます。 URL プレフィックスがhttp://*:5000で、他の何かがポート 5000 にバインドされている場合、このバインディングは使用されません。 -
+は強力なバインディングです。 URL プレフィックスがhttp://+:5000の場合、このバインディングは他のポート 5000 バインドの前に使用されます。
詳細については、「UrlPrefix 文字列」を参照してください。
Warning
最上位のワイルドカードのバインド (
http://*:80/とhttp://+:80) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である*.comとは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。多くの場合、アプリとコンテナーには、リッスンするためのポート (ポート 80 など) のみが与えられます。ホストやパスなどの追加の制約は課せられません。 HTTP_PORTS と HTTPS_PORTS は、Kestrel および HTTP.sys サーバー用にリッスン ポートを指定するための構成キーです。 これらのキーは、
DOTNET_またはASPNETCORE_プレフィックスで定義された環境変数として指定することも、appsettings.jsonなどの他の構成入力を介して直接指定することもできます。 それぞれは、次の例に示すように、ポート値をセミコロンで区切ってリストしたものです。ASPNETCORE_HTTP_PORTS=80;8080 ASPNETCORE_HTTPS_PORTS=443;8081前述の例は、次の構成の省略形であり、スキーム (HTTP または HTTPS) と任意のホストまたは IP が指定されています。
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/HTTP_PORTS および HTTPS_PORTS 構成キーは優先度が低く、コードで直接指定された URL または値によってオーバーライドされます。 証明書は引き続き、HTTPS 用のサーバー固有のメカニズムを介して個別に構成する必要があります。
これらの構成キーは、最上位のワイルドカード バインドと同等です。 これらは開発およびコンテナーのシナリオには便利ですが、他のサービスもホストする可能性があるコンピューター上で実行する場合は、ワイルドカードを避けてください。
サーバーで URL プレフィックスを事前登録します。
HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。
netsh.exe ツールを使用して、アプリ用に URL を登録します。
netsh http add urlacl url=<URL> user=<USER>-
<URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 " -
<USER>:ユーザーまたはユーザー グループの名前を指定します。
次の例では、サーバーのローカル IP アドレスは
10.0.0.4です。netsh http add urlacl url=https://10.0.0.4:443/ user=UsersURL が登録されると、ツールから
URL reservation successfully addedという応答があります。登録済みの URL を削除するには、
delete urlaclコマンドを使用します。netsh http delete urlacl url=<URL>-
サーバーで X.509 証明書を登録します。
netsh.exe ツールを使用して、アプリ用の証明書を登録します。
netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"-
<IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。 -
<PORT>:バインド用のポートを指定します。 -
<THUMBPRINT>:X.509 証明書の拇印です。 -
<GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。
参照用に、この GUID をパッケージ タグとしてアプリに格納します。
- Visual Studio での操作: [][]
- ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
- [パッケージ] タブを選択します。
- 作成した GUID を [タグ] フィールドに入力します。
- Visual Studio を使用しない場合:
アプリのプロジェクト ファイルを開きます。
作成した GUID を指定した
<PackageTags>プロパティを、新規または既存の<PropertyGroup>に追加します。<PropertyGroup> <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags> </PropertyGroup>
次に例を示します。
- サーバーのローカル IP アドレスは
10.0.0.4です。 - オンラインのランダム GUID ジェネレーターによって、
appidの値が提供されます。
netsh http add sslcert ipport=10.0.0.4:443 certhash=b66ee04419d4ee37464ab8785ff02449980eae10 appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"証明書が登録されると、ツールから
SSL Certificate successfully addedという応答があります。証明書の登録を削除するには、
delete sslcertコマンドを使用します。netsh http delete sslcert ipport=<IP>:<PORT>以下は、netsh.exe のリファレンス ドキュメントです。
- Netsh Commands for Hypertext Transfer Protocol (HTTP) (ハイパーテキスト転送プロトコル (HTTP) 用の Netsh コマンド)
- UrlPrefix 文字列
-
アプリを実行します。
1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。
サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス
104.214.79.47でインターネットからアクセスされます。この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。
プロキシ サーバーとロード バランサーのシナリオ
インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。
IHttpSysRequestTimingFeature を使用して詳細なタイミング情報を取得する
IHttpSysRequestTimingFeature では、要求の詳細なタイミング情報が提供されます。
- タイムスタンプは、QueryPerformanceCounter を使用して取得されます。
- タイムスタンプの頻度は、QueryPerformanceFrequency を使用して取得できます。
- タイミングのインデックスを HttpSysRequestTimingType にキャストして、タイミングが何を表しているのかを把握できます。
- 現在の要求でタイミングを利用できない場合、値は 0 になることがあります。
- Windows 10 バージョン 2004、Windows Server 2022 以降が必要です。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var timestamps = feature.Timestamps;
for (var i = 0; i < timestamps.Length; i++)
{
var timestamp = timestamps[i];
var timingType = (HttpSysRequestTimingType)i;
logger.LogInformation("Timestamp {timingType}: {timestamp}",
timingType, timestamp);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
IHttpSysRequestTimingFeature.TryGetTimestamp では、指定されたタイミングの種類のタイムスタンプを取得します。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var timingType = HttpSysRequestTimingType.RequestRoutingEnd;
if (feature.TryGetTimestamp(timingType, out var timestamp))
{
logger.LogInformation("Timestamp {timingType}: {timestamp}",
timingType, timestamp);
}
else
{
logger.LogInformation("Timestamp {timingType}: not available for the "
+ "current request", timingType);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
[IHttpSysRequestTimingFeature.TryGetElapsedTime](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime は、指定された 2 つのタイミング間の経過時間を生成します。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;
if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
{
logger.LogInformation(
"Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
startingTimingType,
endingTimingType,
elapsed);
}
else
{
logger.LogInformation(
"Elapsed time {startingTimingType} to {endingTimingType}:"
+ " not available for the current request.",
startingTimingType,
endingTimingType);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
gRPC をサポートする高度な HTTP/2 機能
HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。
HTTP.sys で gRPC を実行するための要件:
- Windows 11 ビルド 22000 またはそれ以降、Windows Server 2022 ビルド 20348 またはそれ以降が必要です。
- TLS 1.2 またはそれ以降の接続。
Trailers
HTTP トレーラーは HTTP ヘッダーに似ていますが、応答本文の送信後に送信される点が異なります。 IIS と HTTP.sys の場合は、HTTP/2 応答トレーラーのみがサポートされています。
if (httpContext.Response.SupportsTrailers())
{
httpContext.Response.DeclareTrailer("trailername");
// Write body
httpContext.Response.WriteAsync("Hello world");
httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}
上記のコード例では次のようになっています。
-
SupportsTrailersによって、応答におけるトレーラーが確実にサポートされます。 -
DeclareTrailerによって、指定したトレーラー名がTrailer応答ヘッダーに追加されます。 応答のトレーラーを宣言することは省略可能ですが、推奨されています。DeclareTrailerを呼び出す場合、それは、応答ヘッダーを送信する前に行う必要があります。 -
AppendTrailerによって、トレーラーが追加されます。
Reset
リセットを使用すると、指定されたエラー コードを使用してサーバーに HTTP/2 要求をリセットさせることができます。 リセット要求は中止されたと見なされます。
var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);
上記のコード例の Reset により、INTERNAL_ERROR エラー コードが指定されています。 HTTP/2 エラー コードの詳細については、HTTP/2 仕様の「エラーコード」セクションを参照してください。
Tracing
HTTP.sys からトレースを取得する方法については、「HTTP.sys 管理のシナリオ」を参照してください。
その他のリソース
ASP.NET Core