Мультисайт + короткая ссылка + защищенные загрузки + s3

Хм, похоже, на этой неделе я увлёкся охотой за ошибками.

У нас есть форум с включённой функцией secure_uploads; все загрузки хранятся на (официальном) AWS S3.

Проблема: ссылки с короткими URL работают некорректно — в адресе отсутствует часть uploads/{database_id}.

Похоже, проблема в коде внутри UploadsController::show_short:

if upload = Upload.find_by(sha1: sha1)
  return handle_secure_upload_request(upload, Discourse.store.get_path_for_upload(upload)) 
     if upload.secure? && SiteSetting.secure_media?

  if Discourse.store.internal?
    send_file_local_upload(upload)
  else
    redirect_to Discourse.store.url_for(upload, force_download: params[:dl] == "1")
  end
else
  render_404
end

Таким образом, если условие upload.secure? && SiteSetting.secure_media? истинно, запрос обрабатывается методом
handle_secure_upload_request(upload, Discourse.store.get_path_for_upload(upload)).

При этом Discourse.store.get_path_for_upload(upload) возвращает URL без части uploads/{database_id}:

original/3X/f/d/fd0b5775899541b9d42e67f8e0dd6bf587a179d3.png

Следовательно, handle_secure_upload_request возвращает подписанный URL, но в нём отсутствует часть пути, поскольку он начинается с /original:

https://redacted.s3.us-east-2.amazonaws.com/original/3X/f/d/fd0b5775899541b9d42e67f8e0dd6bf587a179d3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKI....

Если бы условие upload.secure? && SiteSetting.secure_media? было ложным (а оно не ложное), запрос обрабатывался бы методом Discourse.store.url_for(upload, force_download: params[:dl] == "1").

А этот метод как раз возвращает корректный URL:

https://redacted.s3.us-east-2.amazonaws.com/uploads/db3999/original/3X/f/d/fd0b5775899541b9d42e67f8e0dd6bf587a179d3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKI...

Получается, что существуют методы url_for и get_path_for_upload, которые работают по-разному, и, похоже, используется неправильный?

7 лайков

Спасибо за отчет, это должно быть довольно легко исправить: handle_secure_upload_request просто не учитывает мультисайт-подключения. Я займусь исправлением этого сегодня и сообщу, когда закончу.

8 лайков

Исправлено здесь:

9 лайков