Cadente
Esta página fue traducida automáticamente del inglés. Leer el original
Cadente es una implementación experimental gestionada de un listener HTTP/1.1 para Sisk. Sirve como reemplazo del System.Net.HttpListener predeterminado, ofreciendo mayor control y flexibilidad, especialmente en plataformas que no son Windows.
Visión general #
Por defecto, Sisk utiliza HttpListener (de System.Net) como su motor subyacente de servidor HTTP. Mientras que HttpListener es estable y de buen rendimiento en Windows (donde usa el controlador kernel‑mode HTTP.sys), su implementación en Linux y macOS es gestionada y históricamente ha tenido limitaciones, como la falta de soporte nativo de SSL (requiriendo un proxy inverso como Nginx) y características de rendimiento variables.
Cadente pretende resolver estos problemas proporcionando un servidor HTTP/1.1 totalmente gestionado escrito en C#. Sus objetivos principales son:
- Soporte nativo de SSL: Funciona en todas las plataformas sin necesidad de proxies externos ni configuraciones complejas.
- Consistencia multiplataforma: Comportamiento idéntico en Windows, Linux y macOS.
- Rendimiento: Diseñado como una alternativa de alto rendimiento al
HttpListenergestionado. - Independencia: Desacoplado de
System.Net.HttpListener, aislando a Sisk de posibles deprecaciones futuras o falta de mantenimiento de ese componente en .NET.
Advertencia
Estado experimental
Cadente se encuentra actualmente en una fase experimental (Beta). No se recomienda aún para entornos de producción críticos. La API y el comportamiento pueden cambiar.
Instalación #
Cadente está disponible como un paquete separado. Para usarlo con Sisk, necesitas el paquete Sisk.Cadente.CoreEngine.
dotnet add package Sisk.Cadente.CoreEngineSisk.Cadente y Sisk.Cadente.CoreEngine apuntan a .NET 9 y .NET 10. No pueden usarse en proyectos que apunten a .NET 8, aunque Sisk.HttpServer lo soporte.
Uso con Sisk #
Para usar Cadente como motor HTTP de tu aplicación Sisk, debes configurar el HttpServer para que utilice CadenteHttpServerEngine en lugar del motor predeterminado.
El CadenteHttpServerEngine adapta el HttpHost de Cadente a la abstracción HttpServerEngine requerida por 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();Cuando un host de escucha está configurado con SSL, HttpServer.ListeningPrefixes informa sus direcciones con el esquema https. Si un cliente envía HTTP plano a un puerto configurado con SSL, Cadente responde con una redirección 301 Moved Permanently a la dirección https del mismo host y ruta.
Configuración avanzada #
Puedes personalizar la instancia subyacente de HttpHost pasando una acción de configuración al constructor de CadenteHttpServerEngine. Esto es útil para ajustar tiempos de espera u otras configuraciones de bajo nivel.
using var engine = new CadenteHttpServerEngine(host =>
{
// Configurar tiempos de espera de lectura/escritura del cliente
host.TimeoutManager.ClientReadTimeout = TimeSpan.FromSeconds(30);
host.TimeoutManager.ClientWriteTimeout = TimeSpan.FromSeconds(30);
});Uso independiente #
Aunque está diseñado principalmente para Sisk, Cadente puede usarse como un servidor HTTP independiente (similar a 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!");
}
}Cuando el cuerpo de la respuesta es pequeño y ya está en memoria, WriteInlineContent y WriteInlineContentAsync escriben los encabezados y el cuerpo en una única operación. La respuesta debe contener un encabezado 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);Validación de solicitudes #
Cadente valida el encuadre de la solicitud antes de que llegue al manejador. Desde la versión 1.7, realiza lo siguiente:
- admite solicitudes en pipeline en conexiones keep-alive;
- rechaza métodos de solicitud que no sean tokens HTTP válidos y destinos de solicitud que contengan bytes fuera del rango ASCII visible (
%x21-7E); - rechaza solicitudes cuyo
Transfer-Encodingsea distinto de un único valorchunked, y solicitudes con encabezadosContent-Lengthconflictivos; - responde
431 Request Header Fields Too Largey cierra la conexión cuando la línea de solicitud y los encabezados superan los 8 KB.
Las solicitudes inválidas se responden con un error y la conexión se cierra, sin invocar al manejador.