Como distribuir Signed HTTP Exchanges (SXG) usando nginx

Como receber e disponibilizar arquivos SXG usando 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 do conteúdo original. Os navegadores da Web compatíveis com SXG exibem esses arquivos como se tivessem sido fornecidos pelos criadores do conteúdo original. Isso permite que você implemente o pré-carregamento entre sites sem violar a privacidade. Este guia mostra como distribuir SXG 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" do artigo Trocas de HTTP assinadas pela origem para informações mais atualizadas.

Acessar arquivos SXG

Especifique no cabeçalho da 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ê colocou seus arquivos SXG em /var/www/sxg.

Exibir 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 acessa seu servidor, o endereço do editor de conteúdo original aparece na barra.

Fazer uma pré-busca de sub-recursos

A maioria das páginas da Web é composta por vários sub-recursos, como CSS, JavaScript, fontes e imagens. Não é possível mudar o conteúdo das SXG sem a chave privada do criador. Isso causa problemas quando o navegador tenta resolver sub-recursos.

Por exemplo, suponha que o index.html.sxg de https://website.test/index.html tenha um link para https://website.test/app.js. Quando o navegador do usuário receber o arquivo SXG de https://distributor.test/example.com/index.html.sxg, ele encontrará 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 pode ser feito na fase de pré-carregamento para preservar a privacidade. Se o recurso tiver sido 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 exibir app.js.sxg do próprio serviço e tentar modificar https://website.test/app.js para ser a versão desse sub-recurso do distribuidor (como https://distributor.test/website.test/app.js.sxg), isso causará uma incompatibilidade de assinatura e tornará a SXG inválida.

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

Para resolver esse problema, há um recurso experimental de pré-busca de sub-recursos das SXG no Chrome agora. Ele pode ser ativado em: about://flags/#enable-sxg-subresource-prefetching. Para usar a pré-busca de recursos secundários, as seguintes condições precisam ser atendidas:

  • O editor precisa incorporar uma entrada de cabeçalho de resposta nas 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 sub-recurso que pode ser substituído pelo hash de integridade específico das SXG.
  • O distribuidor precisa anexar um cabeçalho de resposta ao exibir as 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 sub-recurso.

âncora

O primeiro é relativamente fácil, porque o nginx-sxg-module pode calcular hashes de integridade e incorporá-los em cabeçalhos de links de respostas upstream. Mas o segundo é mais difícil porque o distribuidor de conteúdo precisa estar ciente dos sub-recursos especificados nas SXG.

Se não houver outros sub-recursos além de https://website.test/app.js, tudo o que você precisa anexar à 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 sub-recursos. Além disso, o distribuidor precisa anexar o cabeçalho adequado do link âncora ao exibir um arquivo SXG. No momento, não há uma maneira fácil de resolver esse problema, então fique de olho nas atualizações.

Enviar feedback

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