Cadente
Эта страница переведена с английского автоматически. Читать оригинал
Cadente — экспериментальная управляемая реализация HTTP/1.1‑слушателя для Sisk. Она заменяет стандартный System.Net.HttpListener, предоставляя больший контроль и гибкость, особенно на платформах, отличных от Windows.
Обзор #
По умолчанию Sisk использует HttpListener (из System.Net) в качестве базового HTTP‑движка. Хотя HttpListener стабилен и производителен в Windows (где он работает через драйвер ядра HTTP.sys), его реализация в Linux и macOS управляемая и исторически имела ограничения, такие как отсутствие нативной поддержки SSL (требуется обратный прокси, например Nginx) и различия в производительности.
Cadente стремится решить эти проблемы, предоставляя полностью управляемый HTTP/1.1‑сервер, написанный на C#. Его ключевые цели:
- Нативная поддержка SSL: Работает на всех платформах без внешних прокси и сложных настроек.
- Кроссплатформенная согласованность: Идентичное поведение в Windows, Linux и macOS.
- Производительность: Спроектирован как высокопроизводительная альтернатива управляемому
HttpListener. - Независимость: Отделён от
System.Net.HttpListener, защищая Sisk от возможных будущих устареваний или прекращения поддержки этого компонента в .NET.
Предупреждение
Экспериментальный статус
Cadente находится в экспериментальной (Beta) стадии. Пока не рекомендуется для критически важных продакшн‑окружений. API и поведение могут измениться.
Установка #
Cadente доступен как отдельный пакет. Чтобы использовать его с Sisk, необходимо установить пакет Sisk.Cadente.CoreEngine.
dotnet add package Sisk.Cadente.CoreEngineSisk.Cadente и Sisk.Cadente.CoreEngine нацелены на .NET 9 и .NET 10. Их нельзя использовать в проектах, таргетирующих .NET 8, хотя Sisk.HttpServer поддерживает эту версию.
Использование с Sisk #
Чтобы задействовать Cadente в качестве HTTP‑движка вашего приложения Sisk, необходимо сконфигурировать HttpServer для использования CadenteHttpServerEngine вместо движка по умолчанию.
CadenteHttpServerEngine адаптирует HttpHost из Cadente к абстракции HttpServerEngine, требуемой Sisk.
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. Если клиент отправит обычный HTTP на порт, сконфигурированный для SSL, Cadente ответит редиректом 301 Moved Permanently на https‑адрес того же хоста и пути.
Расширенная конфигурация #
Можно настроить базовый объект HttpHost, передав действие настройки в конструктор CadenteHttpServerEngine. Это удобно для задания тайм‑аутов и других низкоуровневых параметров.
using var engine = new CadenteHttpServerEngine(host =>
{
// Настройка тайм‑аутов чтения/записи клиента
host.TimeoutManager.ClientReadTimeout = TimeSpan.FromSeconds(30);
host.TimeoutManager.ClientWriteTimeout = TimeSpan.FromSeconds(30);
});Автономное использование #
Хотя Cadente в первую очередь предназначен для Sisk, его можно использовать как самостоятельный 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, он:
- поддерживает конвейеризацию запросов на соединениях keep‑alive;
- отклоняет методы запросов, не являющиеся валидными HTTP‑токенами, и цели запросов, содержащие байты за пределами видимого диапазона ASCII (
%x21-7E); - отклоняет запросы, у которых
Transfer-Encodingотличается от единственного значенияchunked, а также запросы с конфликтующими заголовкамиContent-Length; - отвечает
431 Request Header Fields Too Largeи закрывает соединение, если строка запроса и заголовки превышают 8 KB.
Невалидные запросы получают ошибку, соединение закрывается, и обработчик не вызывается.