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, 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 habilitar o suporte a HTTP/3 no Salvo, você precisa ativar o recurso quinn no arquivo Cargo.toml:

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

Cenários de uso do HTTP/3

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

  • Aplicativos em dispositivos móveis e redes instáveis
  • Aplicações em tempo real que exigem baixa latência
  • Cenários com múltiplos downloads paralelos de arquivos pequenos
  • Aplicações que necessitam de migração de conexão (como alternar entre WiFi e rede celular sem interrupção)

Código de exemplo

Aqui está 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 "Hello World"
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

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

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

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

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

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

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

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

Análise do código-chave

Configuração TLS

// Configura 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 exige TLS 1.3 para criptografia, é necessário configurar certificado e chave TLS. No Salvo, usamos RustlsConfig para essa configuração.

Combinando listeners

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

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

Este trecho é central para o tratamento do HTTP/3 no Salvo. Primeiro cria um listener TCP com TLS (para HTTP/1.1 e HTTP/2), depois um listener QUIC (para HTTP/3). O método join combina ambos, permitindo ao servidor lidar com requisições em diferentes protocolos.

Executando o exemplo

Para executar este exemplo, você precisará de um certificado TLS e chave privada válidos. Em ambiente de desenvolvimento, pode-se usar certificados autoassinados. O código completo está disponível no repositório GitHub do Salvo.

Observe que muitos clientes ainda não possuem suporte completo ao HTTP/3, por isso é importante que o servidor suporte tanto HTTP/3 quanto HTTPS.

Observações importantes

  1. HTTP/3 requer TLS 1.3, portanto é obrigatório configurar certificado e chave válidos.
  2. Clientes precisam ter suporte a HTTP/3 para utilizar este recurso, caso contrário ocorrerá fallback para HTTP/1.1 ou HTTP/2.
  3. Em produção, utilize certificados emitidos por autoridades certificadoras (CA), não autoassinados.