Пользовательские эмодзи, загруженные из S3/R2, обходят маршрутизацию CDN

Обзор

При использовании S3 или Cloudflare R2 для загрузки файлов вместе с пользовательским URL-адресом CDN, загрузка пользовательских эмодзи не учитывает конфигурацию CDN и пытается загружаться напрямую с URL-адреса исходного хранилища (бакета).

Суть проблемы

Когда администратор загружает пользовательский эмодзи, система загрузки создает запись upload и сохраняет в базе данных сырой URL-адрес хранилища (например, //my-bucket.s3.amazonaws.com/... или //my-bucket.r2.cloudflarestorage.com/...) — это стандартное поведение Discourse.

Однако, когда app/models/emoji.rb формирует кэш эмодзи для /site.json, он передает upload.url напрямую в объект emoji:

e.url = emoji.upload&.url

Поскольку помощник для CDN (CDN helper) игнорируется, фронтенд получает сырой URL-адрес хранилища. В зависимости от строгости политик доступа к хранилищу это приводит к неработающим изображениям или вынуждает Discourse проксировать эмодзи через внутренний avatar_proxy.

Решение

Я создал PR, который оборачивает присваивание URL-адресов в Discourse.store.cdn_url(), что позволяет загрузчику пользовательских эмодзи работать так же, как и стандартные изображения в постах и аватары.

Временное решение

Пока ожидается рассмотрение и слияние PR, я создал легковесный компонент темы, который заменяет сырой URL-адрес хранилища на правильный URL-адрес CDN непосредственно перед рендерингом пользовательского эмодзи в DOM (работает как для постов, так и для чата).

Если на вашем сайте наблюдается эта ошибка, вы можете установить этот компонент и настроить строки S3 в настройках администратора темы, чтобы исправить неработающие пользовательские эмодзи:

Примечание: если вы уже загрузили пользовательские эмодзи, которые сейчас не отображаются, выполнение команды discourse remap "//my-raw-bucket-url.com" "https://my-cdn.com" в контейнере исправит старые записи в базе данных, а компонент темы исправит все новые загруженные эмодзи до тех пор, пока исправление не будет включено в ядро Discourse.

3 лайка

Тестирование набора эмодзи по умолчанию

:smiley:

Тестирование пользовательского эмодзи

:falco:

Да, возможно, это проблема, специфичная только для Cloudflare R2. У меня на инстансе они ломаются. Кажется, ломаются только те, которые были загружены недавно.

Без исправления компонента темы мне приходится каждый раз запускать ремэппинг при загрузке нового. Возможно, PR требует доработки — я не очень хорошо разбираюсь в коде эмодзи.

1 лайк

Discourse использует двухуровневую конфигурацию CDN: один для статических файлов (assets), а другой — для проксирования самого приложения.

Стандартные эмодзи обслуживаются через один CDN, пользовательские — через другой, но в правильно настроенной конфигурации с двумя CDN оба уровня защищены.

Я уже подробно рассматривал этот вопрос в первой связанной теме здесь:

На вашем сайте настроены и работают оба CDN?

2 лайка

хм, мне нужно будет проверить — я не знал об этом. спасибо!

редактирование:

я написал раздел для Cloudflare R2, так что можно предположить, что я настроил его правильно? что я мог упустить?

просто подтверждаю, что я установил и протестировал ветку PR после недавних изменений, и это исправляет проблему.