Suporte a HTTP/3

O Salvo oferece suporte a HTTP/3, que pode ser ativado através do recurso quinn. O HTTP/3 é baseado no protocolo QUIC e proporciona menor latência e melhor desempenho em comparação com os tradicionais HTTP/1.1 e HTTP/2, especialmente em ambientes de rede instáveis.

Ativando o Suporte a HTTP/3

Para ativar o suporte a HTTP/3 no Salvo, é necessário habilitar o recurso quinn no seu arquivo Cargo.toml:

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

Casos de Uso do HTTP/3

O HTTP/3 é particularmente adequado para os seguintes cenários:

  • Aplicativos em dispositivos móveis e em ambientes de rede instáveis
  • Aplicações em tempo real que exigem baixa latência
  • Cenários que envolvem download paralelo de vários arquivos pequenos
  • Aplicações que necessitam de migração de conexão (por exemplo, alternância perfeita entre WiFi e redes celulares sem interrupção da conexão)

Código de Exemplo

A seguir, um exemplo simples de servidor HTTP/3 que suporta tanto HTTP/3 (QUIC) quanto HTTPS (TCP):

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

// Função handler que responde com "Hello World"
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

#[tokio::main]
async fn main() {
    // Inicializa o sistema de logging
    tracing_subscriber::fmt().init();

    // Carrega certificado TLS e chave privada de arquivos PEM incorporados
    let cert = include_bytes!("../certs/cert.pem").to_vec();
    let key = include_bytes!("../certs/key.pem").to_vec();

    // Cria um roteador e adiciona um endpoint
    let router = Router::new().get(hello);

    // Configura as definições TLS usando Rustls
    let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

    // Cria um listener TCP criptografado com TLS na porta 8698
    let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

    // Cria um listener QUIC e o combina com o listener TCP
    let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
        .join(listener)
        .bind()
        .await;

    // Inicia o servidor com suporte a HTTP/3 (QUIC) e HTTPS (TCP)
    Server::new(acceptor).serve(router).await;
}

Análise do Código Principal

Configuração TLS

// Configura as definições TLS usando Rustls
let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

Como o HTTP/3 é baseado no protocolo QUIC, que requer TLS 1.3 para criptografia, é necessário configurar certificados e chaves TLS. No Salvo, utilizamos RustlsConfig para configurar o TLS.

Combinação de Listeners

// Cria um listener TCP criptografado com TLS
let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

// Cria um listener QUIC e o combina com o listener TCP
let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
    .join(listener)
    .bind()
    .await;

Este código é a parte central do tratamento de HTTP/3 no Salvo. Primeiro, ele cria um listener TCP com TLS habilitado (para HTTP/1.1 e HTTP/2), depois cria um listener QUIC (para HTTP/3). O método join combina esses dois listeners, permitindo que o servidor processe solicitações de diferentes protocolos simultaneamente.

Executando o Exemplo

Para executar este exemplo, são necessários certificados TLS e chaves privadas válidos. Em ambiente de desenvolvimento, podem ser usados certificados autoassinados. O código completo do exemplo pode ser encontrado no repositório GitHub do Salvo.

Observe que, como muitos clientes ainda não suportam totalmente o HTTP/3, é essencial que este servidor suporte tanto HTTP/3 quanto HTTPS.

Considerações

  1. O HTTP/3 requer suporte a TLS 1.3, portanto, certificados e chaves válidos devem ser configurados.
  2. Os clientes devem suportar o protocolo HTTP/3 para utilizar este recurso; caso contrário, eles reverterão para HTTP/1.1 ou HTTP/2.
  3. Em ambientes de produção, devem ser usados certificados emitidos por uma Autoridade Certificadora (CA) confiável, em vez de certificados autoassinados.