Soporte para HTTP/3

Salvo ofrece soporte para HTTP/3, el cual puede habilitarse mediante la funcionalidad quinn. HTTP/3 está basado en el protocolo QUIC y proporciona menor latencia y mejor rendimiento en comparación con HTTP/1.1 y HTTP/2 tradicionales, especialmente en entornos de red inestables.

Habilitar el soporte para HTTP/3

Para habilitar el soporte de HTTP/3 en Salvo, es necesario activar la funcionalidad quinn en el archivo Cargo.toml:

salvo = { workspace = true, features = ["quinn"] }

Casos de uso de HTTP/3

HTTP/3 es especialmente adecuado para los siguientes escenarios:

  • Aplicaciones en dispositivos móviles y entornos de red inestables
  • Aplicaciones en tiempo real que requieren baja latencia
  • Escenarios que involucran descargas paralelas de numerosos archivos pequeños
  • Aplicaciones que necesitan migración de conexión (por ejemplo, cambio sin interrupciones de WiFi a redes celulares)

Código de ejemplo

A continuación se muestra un ejemplo simple de servidor HTTP/3 que soporta tanto HTTP/3 (QUIC) como HTTPS (TCP):

use salvo::conn::rustls::{Keycert, RustlsConfig};
use salvo::prelude::*;

// Función manejadora que responde con "Hello World"
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

#[tokio::main]
async fn main() {
    // Inicializar el sistema de registro
    tracing_subscriber::fmt().init();

    // Cargar certificado TLS y clave privada desde archivos PEM embebidos
    let cert = include_bytes!("../certs/cert.pem").to_vec();
    let key = include_bytes!("../certs/key.pem").to_vec();

    // Crear un enrutador y agregar un endpoint
    let router = Router::new().get(hello);

    // Configurar ajustes TLS usando Rustls
    let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

    // Crear un oyente TCP cifrado con TLS en el puerto 8698
    let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

    // Crear un oyente QUIC y combinarlo con el oyente TCP
    let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
        .join(listener)
        .bind()
        .await;

    // Iniciar el servidor que soporta tanto HTTP/3 (QUIC) como HTTPS (TCP)
    Server::new(acceptor).serve(router).await;
}

Análisis del código clave

Configuración TLS

// Configurar ajustes TLS usando Rustls
let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

Dado que HTTP/3 se basa en el protocolo QUIC, que requiere TLS 1.3 para cifrado, es necesario configurar certificados y claves TLS. En Salvo, utilizamos RustlsConfig para configurar TLS.

Combinación de oyentes

// Crear un oyente TCP cifrado con TLS
let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

// Crear un oyente QUIC y combinarlo con el oyente TCP
let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
    .join(listener)
    .bind()
    .await;

Este código es la parte central del manejo de HTTP/3 en Salvo. Primero crea un oyente TCP habilitado para TLS (para HTTP/1.1 y HTTP/2), luego crea un oyente QUIC (para HTTP/3). El método join combina estos dos oyentes, permitiendo que el servidor maneje solicitudes de diferentes protocolos simultáneamente.

Ejecutar el ejemplo

Para ejecutar este ejemplo, se necesitan certificados TLS y claves privadas válidas. En un entorno de desarrollo, se pueden utilizar certificados autofirmados. El código completo del ejemplo se puede encontrar en el repositorio GitHub de Salvo.

Tenga en cuenta que, dado que muchos clientes aún no soportan completamente HTTP/3, es esencial que este servidor soporte tanto HTTP/3 como HTTPS.

Consideraciones

  1. HTTP/3 requiere soporte para TLS 1.3, por lo que deben configurarse certificados y claves válidos.
  2. Los clientes deben soportar el protocolo HTTP/3 para utilizar esta funcionalidad; de lo contrario, recurrirán a HTTP/1.1 o HTTP/2.
  3. En entornos de producción, deben utilizarse certificados emitidos por una Autoridad de Certificación (CA) confiable en lugar de certificados autofirmados.