멀티사이트 + short-url + secure_uploads + s3

음, 이번 주에 버그 사냥을 하고 있는 것 같습니다.

저희 포럼은 secure_uploads가 활성화되어 있으며, 모든 업로드는 (공식) AWS S3에 저장됩니다.

문제: short-url 링크가 올바르게 작동하지 않는 것 같습니다. 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?가 true이면 요청은 다음으로 처리됩니다:
handle_secure_upload_request(upload, Discourse.store.get_path_for_upload(upload))

이때 Discourse.store.get_path_for_upload(upload)uploads/{database_id} 부분이 없는 URL을 반환합니다:

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

그리고 결과적으로 handle_secure_upload_request는 서명된 URL을 반환하지만, /original로 시작하기 때문에 URL에 일부가 누락됩니다:

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?가 false였다면(하지만 실제로는 그렇지 않습니다) 요청은 다음으로 처리되었을 것입니다:
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_forget_path_for_upload이 존재하며, 잘못된 쪽이 사용되고 있는 것 같습니다.

7개의 좋아요

리포트 감사합니다. 이 문제는 비교적 쉽게 수정할 수 있습니다. handle_secure_upload_request 함수가 멀티사이트 연결을 고려하지 않고 있기 때문입니다. 오늘 수정 작업을 진행한 후 완료되면 다시 알려드리겠습니다.

8개의 좋아요

여기에서 수정되었습니다:

9개의 좋아요