FEATURE: Use path from existing URL of uploads and optimized images (#13177)

Discourse shouldn't dynamically calculate the path of uploads and optimized images after a file has been stored on disk or S3. Otherwise it might calculate the wrong path if the SHA1 or extension stored in the database doesn't match the actual file path.
This commit is contained in:
Gerhard Schlager
2021-05-27 17:42:25 +02:00
committed by GitHub
parent bcbb5b4dae
commit 157f10db4c
11 changed files with 189 additions and 56 deletions

View File

@ -3,13 +3,17 @@
module FileStore
class BaseStore
UPLOAD_PATH_REGEX = %r|/(original/\d+X/.*)|
OPTIMIZED_IMAGE_PATH_REGEX = %r|/(optimized/\d+X/.*)|
def store_upload(file, upload, content_type = nil)
upload.url = nil
path = get_path_for_upload(upload)
store_file(file, path)
end
def store_optimized_image(file, optimized_image, content_type = nil, secure: false)
optimized_image.url = nil
path = get_path_for_optimized_image(optimized_image)
store_file(file, path)
end
@ -116,6 +120,12 @@ module FileStore
end
def get_path_for_upload(upload)
# try to extract the path from the URL instead of calculating it,
# because the calculated path might differ from the actual path
if upload.url.present? && (path = upload.url[UPLOAD_PATH_REGEX, 1])
return prefix_path(path)
end
extension =
if upload.extension
".#{upload.extension}"
@ -128,6 +138,12 @@ module FileStore
end
def get_path_for_optimized_image(optimized_image)
# try to extract the path from the URL instead of calculating it,
# because the calculated path might differ from the actual path
if optimized_image.url.present? && (path = optimized_image.url[OPTIMIZED_IMAGE_PATH_REGEX, 1])
return prefix_path(path)
end
upload = optimized_image.upload
version = optimized_image.version || 1
extension = "_#{version}_#{optimized_image.width}x#{optimized_image.height}#{optimized_image.extension}"
@ -178,6 +194,9 @@ module FileStore
depths.max
end
def prefix_path(path)
path
end
end
end

View File

@ -66,7 +66,7 @@ module FileStore
end
def get_path_for(type, upload_id, sha, extension)
File.join("/", upload_path, super(type, upload_id, sha, extension))
prefix_path(super(type, upload_id, sha, extension))
end
def copy_file(file, path)
@ -134,5 +134,8 @@ module FileStore
puts "#{count} of #{model.count} #{model.name.underscore.pluralize} are missing" if count > 0
end
def prefix_path(path)
File.join("/", upload_path, path)
end
end
end

View File

@ -22,6 +22,7 @@ module FileStore
end
def store_upload(file, upload, content_type = nil)
upload.url = nil
path = get_path_for_upload(upload)
url, upload.etag = store_file(
file,
@ -35,6 +36,7 @@ module FileStore
end
def store_optimized_image(file, optimized_image, content_type = nil, secure: false)
optimized_image.url = nil
path = get_path_for_optimized_image(optimized_image)
url, optimized_image.etag = store_file(file, path, content_type: content_type, private_acl: secure)
url