diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/services/projects/lfs_pointers/lfs_download_service.rb | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) | |
download | gitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz |
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'app/services/projects/lfs_pointers/lfs_download_service.rb')
-rw-r--r-- | app/services/projects/lfs_pointers/lfs_download_service.rb | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/app/services/projects/lfs_pointers/lfs_download_service.rb b/app/services/projects/lfs_pointers/lfs_download_service.rb index 52c73bcff03..d6e5b825e13 100644 --- a/app/services/projects/lfs_pointers/lfs_download_service.rb +++ b/app/services/projects/lfs_pointers/lfs_download_service.rb @@ -6,6 +6,9 @@ module Projects class LfsDownloadService < BaseService SizeError = Class.new(StandardError) OidError = Class.new(StandardError) + ResponseError = Class.new(StandardError) + + LARGE_FILE_SIZE = 1.megabytes attr_reader :lfs_download_object delegate :oid, :size, :credentials, :sanitized_url, to: :lfs_download_object, prefix: :lfs @@ -19,6 +22,7 @@ module Projects def execute return unless project&.lfs_enabled? && lfs_download_object return error("LFS file with oid #{lfs_oid} has invalid attributes") unless lfs_download_object.valid? + return link_existing_lfs_object! if Feature.enabled?(:lfs_link_existing_object, project, default_enabled: true) && lfs_size > LARGE_FILE_SIZE && lfs_object wrap_download_errors do download_lfs_file! @@ -29,7 +33,7 @@ module Projects def wrap_download_errors(&block) yield - rescue SizeError, OidError, StandardError => e + rescue SizeError, OidError, ResponseError, StandardError => e error("LFS file with oid #{lfs_oid} could't be downloaded from #{lfs_sanitized_url}: #{e.message}") end @@ -56,15 +60,13 @@ module Projects def download_and_save_file!(file) digester = Digest::SHA256.new - response = Gitlab::HTTP.get(lfs_sanitized_url, download_headers) do |fragment| + fetch_file do |fragment| digester << fragment file.write(fragment) raise_size_error! if file.size > lfs_size end - raise StandardError, "Received error code #{response.code}" unless response.success? - raise_size_error! if file.size != lfs_size raise_oid_error! if digester.hexdigest != lfs_oid end @@ -78,6 +80,12 @@ module Projects end end + def fetch_file(&block) + response = Gitlab::HTTP.get(lfs_sanitized_url, download_headers, &block) + + raise ResponseError, "Received error code #{response.code}" unless response.success? + end + def with_tmp_file create_tmp_storage_dir @@ -123,6 +131,29 @@ module Projects super end + + def lfs_object + @lfs_object ||= LfsObject.find_by_oid(lfs_oid) + end + + def link_existing_lfs_object! + existing_file = lfs_object.file.open + buffer_size = 0 + result = fetch_file do |fragment| + unless fragment == existing_file.read(fragment.size) + break error("LFS file with oid #{lfs_oid} cannot be linked with an existing LFS object") + end + + buffer_size += fragment.size + break success if buffer_size > LARGE_FILE_SIZE + end + + project.lfs_objects << lfs_object + + result + ensure + existing_file&.close + end end end end |