Como distribuir Signed HTTP Exchanges (SXG) usando nginx

Como receber e disponibilizar arquivos SXG usando o nginx e os desafios da pré-busca de sub-recursos.

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.

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.

Extrair 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.

Disponibilizar um arquivo SXG simples

Anexe os seguintes cabeçalhos 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 de conteúdo original será exibido 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. É possível ativar essa opção em: about://flags/#enable-sxg-subresource-prefetching. Para usar a pré-busca de sub-recursos, 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 o 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 deve anexar o cabeçalho do link âncora adequado ao exibir um arquivo SXG. Atualmente, não existe uma maneira fácil de resolver esse problema, portanto, fique atento às 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 à equipe. Seu feedback vai ajudar muito no processo de padronização e também a resolver problemas de implementação. Valeu!