Cadente
このページは英語から自動翻訳されています。 原文を読む
Cadente は Sisk 用の実験的なマネージド HTTP/1.1 リスナー実装です。デフォルトの System.Net.HttpListener の代替として機能し、特に非 Windows プラットフォームで、より高い制御性と柔軟性を提供します。
概要 #
デフォルトでは、Sisk は基盤となる HTTP サーバーエンジンとして HttpListener(System.Net から)を使用します。HttpListener は Windows 上ではカーネルモードの HTTP.sys ドライバーを利用し、安定かつ高性能ですが、Linux や macOS での実装はマネージドであり、歴史的にネイティブ SSL サポートがない(Nginx などのリバースプロキシが必要)や、パフォーマンス特性が一定でないといった制限がありました。
Cadente はこれらの問題を解決するために、C# で書かれた完全マネージドの HTTP/1.1 サーバーを提供します。その主な目標は次のとおりです:
- ネイティブ SSL サポート: 外部プロキシや複雑な設定を必要とせず、すべてのプラットフォームで動作します。
- クロスプラットフォームの一貫性: Windows、Linux、macOS で同一の動作を保証します。
- パフォーマンス: マネージド
HttpListenerの高性能な代替として設計されています。 - 独立性:
System.Net.HttpListenerから分離され、.NET における将来的な非推奨化やメンテナンス停止の影響から Sisk を保護します。
警告
実験的ステータス
Cadente は現在実験段階(ベータ)にあります。重要な本番環境での使用はまだ推奨されません。API や動作は変更される可能性があります。
インストール #
Cadente は別パッケージとして提供されています。Sisk で使用するには Sisk.Cadente.CoreEngine パッケージが必要です。
dotnet add package Sisk.Cadente.CoreEngineSisk.Cadente と Sisk.Cadente.CoreEngine は .NET 9 および .NET 10 を対象としています。Sisk.HttpServer が .NET 8 をサポートしているにもかかわらず、.NET 8 を対象としたプロジェクトでは使用できません。
Sisk での使用 #
Cadente を Sisk アプリケーションの HTTP エンジンとして使用するには、デフォルトエンジンの代わりに CadenteHttpServerEngine を使用するように HttpServer を構成する必要があります。
CadenteHttpServerEngine は Cadente の HttpHost を Sisk が必要とする HttpServerEngine 抽象に適合させます。
using Sisk.Core.Http;
using Sisk.Cadente.CoreEngine;
using var host = HttpServer.CreateBuilder()
.UseEngine<CadenteHttpServerEngine>()
.UseSsl(certificate: CertificateHelper.CreateTrustedDevelopmentCertificate("localhost"))
.Build();
await host.StartAsync();リスニングホストが SSL で構成されている場合、HttpServer.ListeningPrefixes は https スキームのアドレスを報告します。クライアントが SSL 構成されたポートにプレーン HTTP を送信した場合、Cadente は同じホストとパスの https アドレスへ 301 Moved Permanently リダイレクトで応答します。
高度な構成 #
CadenteHttpServerEngine コンストラクタにセットアップアクションを渡すことで、基盤となる HttpHost インスタンスをカスタマイズできます。タイムアウトやその他の低レベル設定を構成する際に便利です。
using var engine = new CadenteHttpServerEngine(host =>
{
// クライアントの読み取り/書き込みタイムアウトを設定
host.TimeoutManager.ClientReadTimeout = TimeSpan.FromSeconds(30);
host.TimeoutManager.ClientWriteTimeout = TimeSpan.FromSeconds(30);
});スタンドアロン使用 #
主に Sisk 用に設計されていますが、Cadente はスタンドアロンの HTTP サーバーとしても使用できます(HttpListener に似ています)。
using Sisk.Cadente;
var host = new HttpHost(15000)
{
Handler = new MyHostHandler()
};
host.Start();
Thread.Sleep(-1);
class MyHostHandler : HttpHostHandler
{
public override async Task OnContextCreatedAsync(HttpHost host, HttpHostContext context)
{
context.Response.StatusCode = 200;
using var stream = await context.Response.GetResponseStreamAsync(chunked: true);
using var writer = new StreamWriter(stream);
await writer.WriteLineAsync("Hello, world!");
}
}レスポンスボディが小さくメモリ上にある場合、WriteInlineContent と WriteInlineContentAsync はヘッダーとボディを一度の操作で書き込みます。レスポンスには Content-Length ヘッダーが必要です:
byte[] body = "Hello, world!"u8.ToArray();
context.Response.StatusCode = 200;
context.Response.Headers.Set(new HttpHeader("Content-Length", body.Length.ToString()));
await context.Response.WriteInlineContentAsync(body);リクエストの検証 #
Cadente はハンドラに到達する前にリクエストのフレーミングを検証します。バージョン 1.7 以降、以下を行います:
- キープアライブ接続上でパイプライン化されたリクエストをサポートします;
- 有効な HTTP トークンでないリクエストメソッドや、表示可能な ASCII 範囲(
%x21-7E)外のバイトを含むリクエストターゲットを拒否します; Transfer-Encodingが単一のchunked以外の場合や、矛盾するContent-Lengthヘッダーがあるリクエストを拒否します;- リクエストラインとヘッダーが 8 KB を超えると
431 Request Header Fields Too Largeで応答し、接続を閉じます。
無効なリクエストにはエラーで応答し、ハンドラは呼び出されずに接続が閉じられます。