Emojis personalizados carregados do S3/R2 contornam roteamento do CDN

Visão geral

Ao usar S3 ou Cloudflare R2 para uploads junto com uma URL de CDN personalizada, os uploads de emojis personalizados não respeitam a configuração do CDN e tentam carregar diretamente da URL bruta do bucket.

O problema

Quando um administrador faz upload de um emoji personalizado, o uploader cria um registro upload e salva a URL bruta do bucket no banco de dados (por exemplo, //my-bucket.s3.amazonaws.com/... ou //my-bucket.r2.cloudflarestorage.com/...) — este é o comportamento padrão do Discourse.

No entanto, quando app/models/emoji.rb gera o cache de emojis para /site.json, ele passa a upload.url diretamente para o objeto emoji:

e.url = emoji.upload&.url

Por pular o helper do CDN, o frontend recebe a URL bruta do bucket. Assim, dependendo de quão restritivas são as políticas de acesso do bucket, isso resulta em imagens quebradas ou força o Discourse a rotear os emojis através do avatar_proxy interno.

Solução

Abri um PR que envolve as atribuições de URL no Discourse.store.cdn_url(), o que faz com que o carregador de emojis personalizados esteja alinhado com a forma como as imagens de postagens padrão e os avatares são roteados.

Solução temporária

Enquanto aguardamos que o PR seja revisado e mesclado, criei um componente de tema leve que substitui a URL bruta do bucket pela URL correta do CDN logo antes que o emoji personalizado seja renderizado no DOM (funciona tanto para postagens quanto para chat).

Se você estiver enfrentando este bug no seu site, pode instalar este componente e configurar suas strings do S3 nas configurações do administrador do tema para corrigir qualquer emoji personalizado quebrado:

Nota: se você já fez upload de emojis personalizados que estão atualmente quebrados, executar discourse remap "//my-raw-bucket-url.com" "https://my-cdn.com" no container corrigirá os antigos no banco de dados, enquanto o componente de tema corrigirá qualquer um recém-upload até que a correção do PR seja mesclada no núcleo.

5 curtidas

Testando um emoji padrão

:smiley:

Testando um emoji personalizado

:falco:

2 curtidas

Pode ser que seja algo exclusivo do Cloudflare R2, então. Está falhando na minha instância. Parece que só falha com os novos que são enviados.

Sem a correção do componente do tema, tenho que executar o remapeamento toda vez que envio um novo. O PR pode precisar de alguns ajustes — não sou muito bom com o código dos emojis.

2 curtidas

O Discourse utiliza uma configuração com dois CDNs: um para ativos (assets) e outro atuando como proxy para a aplicação.

Os emojis padrão usam um CDN, enquanto os emojis personalizados usam o outro, mas ambos ficam protegidos por um CDN em um site corretamente configurado com essa configuração de dois CDNs.

Já detalhei isso no primeiro tópico relacionado aqui:

Seu site tem ambos os CDNs configurados e funcionando?

4 curtidas

ah, vou ter que dar uma olhada - eu não sabia disso. obrigado!

edit:

eu escrevi a seção para Cloudflare R2, então posso assumir que está configurado corretamente? o que eu poderia estar perdendo?

2 curtidas

1 curtida

só confirmando aqui que instalei e testei a branch do PR após as mudanças recentes nela e que ela corrige o problema.

1 curtida

Esta é a seção do guia da wiki que escrevi:

Você tem ambos configurados?

Este é um artefato da mudança do Meta da AWS de volta para Metal, estava faltando um novo cook, apenas reconstruí o HTML para corrigi-lo.

Seu site de teste tem ambas as variáveis de ambiente de CDN configuradas?

3 curtidas

Eu as tenho definidas, mas, por amor de Deus, eu tinha um erro de digitação na minha configuração do Cloudflare para o registro DNS específico do CDN que DISCOURSE_CDN_URL aponta, e eu nunca testei quando configurei porque meu site estava funcionando :laughing: que confusão total.

Pelo menos aprendi mais sobre criação de código de emoji fazendo aquele PR inútil…
:woman_facepalming:t2:

Obrigado, Falco!

3 curtidas

Ha, sem problemas!

É assim que eu mais aprendo, perseguindo “coelhos na toca” que nunca resultam em algo tangível. Mas o conhecimento adquirido nesses casos é dourado!

3 curtidas

nossa, que jornada essa foi. basicamente reconfigurei toda minha instância do Cloudfare R2 e do Discourse, e acho que esse bug é legítimo para o R2. quando corrigi meu registro de DNS do Cloudflare e reconstruí a instância para que DISCOURSE_CDN_URL realmente apontasse para ele, estragou um monte de outras coisas, como strings de tradução, e gerou vários erros no console, incluindo alguns erros de CORS. isso me levou por muitos caminhos equivocados hoje. então acho que usar DISCOURSE_CDN_URL parece ser incompatível com o Cloudflare R2. (isso foi muito estranho — quando configurei originalmente minha entrada de DNS, inseri incorretamente o registro de DNS cdn.mysite.com de forma que estava resolvendo como cdn.mysite.com.mysite.com). definir DISCOURSE_CDN_URL corretamente parece ser incompatível com o armazenamento de objetos do Cloudflare R2. pode haver outras coisas aqui que eu não estou entendendo completamente.

enfim, quando reconstruí com minha branch de PR, tudo foi corrigido porque envolve a atribuição em Discourse.store.cdn_url(), para que os uploads de emojis personalizados sigam a mesma lógica de roteamento e fallback do CDN S3 que os uploads de imagens padrão de posts.

reabri o PR e editei a descrição. mas acho que se a equipe do Discourse escolher não mesclar, tudo bem, porque o componente de tema corrige o problema no nível do cliente. observe que a correção do PR deve afetar apenas as configurações de armazenamento de objetos R2 para emojis personalizados e não outros serviços compatíveis com S3 como a AWS.

2 curtidas

Este PR foi mesclado e os emojis personalizados agora estão corrigidos ao usar o armazenamento de objetos Cloudflare R2 para uploads. Postei uma sugestão de atualização para a documentação relevante do R2 aqui: Configure an S3 compatible object storage provider for uploads

3 curtidas

O problema foi resolvido. Abra um novo relatório se isso acontecer novamente.