음, 이번 주에 버그 사냥을 하고 있는 것 같습니다.
저희 포럼은 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_for와 get_path_for_upload이 존재하며, 잘못된 쪽이 사용되고 있는 것 같습니다.