Como distribuir Signed HTTP Exchanges (SXG) usando nginx

Como receber e servir arquivos SXG usando o nginx e os desafios do pré-carregamento de subrecursos.

Hiroki Kumazaki
Hiroki Kumazaki

Como distribuidor de Signed HTTP Exchanges (SXG), você pode enviar arquivos SXG em nome dos criadores de conteúdo originais. Os navegadores da Web que oferecem suporte a SXG vão exibir esses arquivos como se tivessem sido enviados pelos criadores de conteúdo originais. Isso permite implementar o pré-carregamento entre sites sem violar a privacidade. Neste guia, mostramos como distribuir SXGs corretamente.

Suporte a vários navegadores

No momento, o Chrome é o único navegador compatível com SXG. Consulte a seção "Consenso e padronização" de Trocas HTTP assinadas pela origem para informações mais atualizadas.

Acessar arquivos SXG

Especifique no cabeçalho de solicitação Accept que você quer que o servidor retorne um arquivo SXG com a solicitação:

Accept: application/signed-exchange;v=b3,*/*;q=0.8

Este guia pressupõe que você coloque seus arquivos SXG em /var/www/sxg.

Servir um arquivo SXG simples

Anexe os cabeçalhos a seguir para distribuir um único arquivo SXG:

Content-Type: application/signed-exchange;v=v3
X-Content-Type-Options: nosniff

Configurar nginx:

http {
    ...
    types {
        application/signed-exchange;v=b3  sxg;
    }
    add_header X-Content-Type-Options nosniff;

    location / {
        more_set_headers "Content-Type: application/signed-exchange;v=b3";
        alias /var/www/sxg/;
        try_files $uri.sxg $uri =404;
        autoindex off;
    }
    ...

Carregue a nova configuração em nginx:

sudo systemctl restart nginx.service

nginx vai começar a veicular arquivos SXG. Quando o Chrome acessar seu servidor, o endereço do editor do conteúdo original vai aparecer na barra.

Fazer pré-busca de sub-recursos

A maioria das páginas da Web consiste em vários subrecursos, como CSS, JavaScript, fontes e imagens. O conteúdo do SXG não pode ser alterado sem a chave privada do criador de conteúdo. Isso causa problemas quando o navegador tenta resolver subrecursos.

Por exemplo, suponha que index.html.sxg de https://website.test/index.html tenha um link para https://website.test/app.js. Quando o navegador de um usuário recebe o arquivo SXG de https://distributor.test/example.com/index.html.sxg, ele encontra o link para https://website.test/app.js. O navegador pode buscar https://website.test/app.js diretamente no acesso real, mas isso não deve ser feito na fase de pré-carregamento para preservar a privacidade. Se o recurso for buscado durante a fase de pré-carregamento, o criador de conteúdo (website.test) poderá detectar qual distribuidor de conteúdo (distributor.test) está solicitando o recurso.

O link para app.js em distributor.test/index.html.sxg aponta para website.test/app.js.

Se o distribuidor quiser veicular app.js.sxg do próprio serviço e tentar modificar https://website.test/app.js para ser a versão do distribuidor desse subrecurso (como https://distributor.test/website.test/app.js.sxg), isso vai causar uma incompatibilidade de assinatura e tornar o SXG inválido.

Uma tentativa de vincular a referência a app.js em distributor.test/index.html.sxg para distributor.test/app.js causa uma incompatibilidade de assinatura.

Para resolver esse problema, há um recurso experimental de pré-carregamento de subrecursos SXG no Chrome. Você pode ativar essa opção em: about://flags/#enable-sxg-subresource-prefetching. Para usar a pré-busca de subrecursos, as seguintes condições precisam ser atendidas:

  • O editor precisa incorporar uma entrada de cabeçalho de resposta no SXG, como link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk=". Isso especifica o subrecurso que pode ser substituído pelo hash de integridade específico do SXG.
  • O distribuidor precisa anexar um cabeçalho de resposta ao exibir o SXG, como link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js". Isso especifica o caminho de app.js e corresponde ao subrecurso.

âncora

A primeira é relativamente fácil, porque nginx-sxg-module pode calcular hashes de integridade e incorporá-los aos cabeçalhos de link das respostas upstream. Mas a segunda é mais difícil porque o distribuidor de conteúdo precisa estar ciente dos subrecursos especificados no SXG.

Se não houver outros subrecursos além de https://website.test/app.js, tudo o que você precisa anexar na configuração do Nginx é:

add_header link <https://distributor.test/website.test/app.js.sxg>;rel="alter...

No entanto, esses casos são raros, porque os sites típicos consistem em muitos subrecursos. Além disso, o distribuidor precisa anexar o cabeçalho de link de âncora adequado ao veicular um arquivo SXG. No momento, não há uma maneira fácil de resolver esse problema. Fique de olho nas atualizações.

Enviar feedback

Os engenheiros do Chromium querem saber sua opinião sobre a distribuição de SXG em webpackage-dev@chromium.org. Você também pode participar da discussão sobre as especificações ou relatar um bug para a equipe. Seu feedback vai ajudar muito no processo de padronização e também a resolver problemas de implementação. Valeu!