Новая эра загрузки файлов в Discourse

За последние несколько месяцев вы могли заметить множество коммитов, связанных с загрузкой файлов в ядре Discourse. Это было частью общих усилий по замене использования jQuery file upload в нашей кодовой базе, что, в свою очередь, является частью ещё более масштабной задачи по отказу от использования самого jQuery. jQuery file upload — очень старый проект, который присутствовал в ядре Discourse почти с самого начала. Я думаю, что использовал его на протяжении всей своей карьеры и в других проектах. Но пришло время отправить «Старого Надёжного» на покой:

Мы заменили jQuery file upload (а вскоре также заменим ещё одну библиотеку — resumable.js) на библиотеку под названием Uppy. Это гораздо более современная библиотека для загрузки, которая легко расширяется с помощью плагинов и способна обрабатывать все различные сценарии, которые мы ей предъявляем. Важно то, что это позволяет нам выполнять прямую многокомпонентную загрузку в S3 прямо с клиента Discourse, вместо того чтобы передавать большие файлы через наш API.

Композер теперь использует Uppy для всех загрузок, и во многих других местах приложения (загрузка аватара, загрузка фона профиля и т. д.) также применяется эта библиотека. Последние оставшиеся элементы будут удалены в ближайшие несколько недель. Для большинства пользователей это изменение должно остаться практически незаметным, но авторам плагинов и тематических компонентов потребуется внести некоторые изменения.

API плагинов

Препроцессоры

Все препроцессоры загрузки теперь должны быть написаны как плагины Uppy. Эти плагины довольно просты в написании и используют простой рабочий процесс на основе промисов. Препроцессор загрузки может изменить файл или добавить к нему метаданные перед тем, как Uppy загрузит его в S3 или в эндпоинт /uploads.json. В ядре уже есть несколько препроцессоров, которые вы можете использовать в качестве примера при написании собственных:

Препроцессоры загрузки для композера регистрируются через api.addComposerUploadPreProcessor с использованием API плагинов:

Обработчики загрузки

Обработчики загрузки не пишутся как плагины Uppy; они работают как и прежде, с незначительным изменением. Теперь, когда файл соответствует расширению, зарегистрированному для обработчика загрузки, все соответствующие файлы будут переданы сразу. Ранее в обработчик загрузки передавался только один файл за раз, а теперь передаётся массив:

Файлы, обработанные обработчиком загрузки, не будут дополнительно обрабатываться в конвейере загрузки Uppy. Препроцессоры выполняются до вызова обработчиков загрузки.

Прямая многокомпонентная загрузка в S3

Ранее я упоминал, что использование Uppy также позволяет нам выполнять прямую многокомпонентную загрузку в S3 прямо из интерфейса. Чтобы включить эту функцию, необходимо установить параметр сайта enable_direct_s3_uploads в значение true.

Если вы используете хостинг от нас, соответствующие права доступа S3 уже применены к вашему бакету. Однако, если вы размещаете систему самостоятельно, для работы этой функции необходимо настроить несколько прав доступа и правил CORS в вашем бакете.

Для настройки правил CORS достаточно выполнить задачу rake s3:ensure_cors_rules с помощью команды rake s3:ensure_cors_rules. Она добавит следующие правила в ваш бакет, при условии, что у вас включены права S3:GetBucketCors и S3:PutBucketCors для ключа доступа и секретного ключа, которые вы настроили для учётных данных S3 на вашем экземпляре Discourse.

{
  "AllowedHeaders": [
    "Authorization",
    "Content-Disposition",
    "Content-Type"
  ],
  "AllowedMethods": [
    "GET",
    "HEAD",
    "PUT"
  ],
  "AllowedOrigins": [
    "*"
  ],
  "ExposeHeaders": [
    "ETag"
  ],
  "MaxAgeSeconds": 3000
}

Что касается прав доступа, вам необходимо включить следующие права для ключа доступа и секретного ключа, которые вы настроили для учётных данных S3 на вашем экземпляре Discourse.

{
    "Sid": "YourSid",
    "Effect": "Allow",
    "Action": [
        "s3:PutObjectVersionAcl",
        "s3:PutObjectAcl",
        "s3:PutObject",
        "s3:GetObjectAcl",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:CreateMultipartUpload",
        "s3:CompleteMultipartUpload",
        "s3:AbortMultipartUpload"
    ],
    "Resource": [
        "YOUR_RESOURCE"
    ]
}

Этот процесс занял несколько долгих месяцев, и мы ещё не закончили! Я опубликую сообщение в этой теме, когда мы окончательно удалим jQuery file upload и resumable.js из ядра Discourse. Если у вас есть вопросы по тому, что я написал здесь, дайте мне знать!

49 лайков

5 сообщений были перенесены в новую тему: Uppy не работает в Firefox 68

itsgoneitsdone

С помощью этих двух коммитов jQuery file uploader и resumable.js больше не входят в ядро Discourse:

Я сделал всё возможное, чтобы удалить все упоминания об этом и наш старый UploadMixin во всех известных нам плагинах, но возможно, я упустил некоторые или не знаю о них. Не волнуйтесь, процесс миграции прост. В 99% случаев можно просто использовать наш новый UppyUploadMixin как прямую замену с минимальными изменениями. Для примера посмотрите здесь:

Для остальных 1% можно создать экземпляр Uppy и напрямую подключить обработчики событий. Для примера посмотрите здесь:

Я также описал изменения в плагинах в первом сообщении этой темы. До нашего следующего релиза ещё несколько недель, поэтому, если у кого-то возникнут проблемы, пожалуйста, сообщите о них здесь. Это было захватывающее путешествие! :roller_coaster:

14 лайков

Кстати, документация по API теперь обновлена с новыми конечными точками загрузки. Перейдите по адресу Discourse API Docs, чтобы посмотреть.

(ссылка @mattdm, это может вас заинтересовать)

6 лайков

После включения прямой загрузки в S3 мы получаем сообщения от пользователей из Китая о невозможности загрузки изображений — процесс застревает на 0% и завершается по тайм-ауту.

Первое предположение могло бы заключаться в том, что S3 заблокирован в Китае, но мы точно знаем, что это не так — по крайней мере, не полностью: наши пользователи из Китая без проблем просматривают изображения, хранящиеся в S3 (в нашем случае бакет находится в регионе eu-central-1). Однако, по какой-то причине, загрузка не работает.

Отладка этого без доступа из-за за пределами GFW затруднительна, но некоторые пользователи из Китая отметили, что, возможно, существенное различие заключается в том, что изображения загружаются с использованием двойного стека, тогда как загрузка использует обычный (только IPv4) конечную точку (bucket-name.s3.dualstack.eu-central-1.amazonaws.com против bucket-name.s3.eu-central-1.amazonaws.com). По результатам некоторых тестов мы видим, что это действительно так, но не уверены, является ли это ожидаемым поведением или обязательным требованием для загрузки.

Ещё более показательным, возможно, является то, что некоторые пользователи сообщили, что добавление IP-адреса, полученного из имени хоста с двойным стеком, в свой файл hosts (для имени хоста без двойного стека), полностью решает проблему, и они смогли выполнить загрузку, просто внеся это изменение.

Не уверены, есть ли в команде Discourse кто-то, кто находится в Китае и может помочь с более глубокой отладкой этой проблемы?

4 лайка

Сообщение было перенесено в новую тему: Ошибка при настройке S3: действия не существуют