debian-mirror-gitlab/lib/gitlab/ci/artifacts/decompressed_artifact_size_validator.rb
2023-06-09 12:34:30 +05:30

61 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Ci
module Artifacts
class DecompressedArtifactSizeValidator
DEFAULT_MAX_BYTES = 4.gigabytes.freeze
FILE_FORMAT_VALIDATORS = {
gzip: ::Gitlab::Ci::DecompressedGzipSizeValidator
}.freeze
FileDecompressionError = Class.new(StandardError)
def initialize(file:, file_format:, max_bytes: DEFAULT_MAX_BYTES)
@file = file
@file_path = file&.path
@file_format = file_format
@max_bytes = max_bytes
end
def validate!
validator_class = FILE_FORMAT_VALIDATORS[file_format.to_sym]
return if file_path.nil?
return if validator_class.nil?
if file.respond_to?(:object_store) && file.object_store == ObjectStorage::Store::REMOTE
return if valid_on_storage?(validator_class)
elsif validator_class.new(archive_path: file_path, max_bytes: max_bytes).valid?
return
end
raise(FileDecompressionError, 'File decompression error')
end
private
attr_reader :file_path, :file, :file_format, :max_bytes
def valid_on_storage?(validator_class)
temp_filename = "#{SecureRandom.uuid}.gz"
is_valid = false
Tempfile.open(temp_filename, '/tmp') do |tempfile|
tempfile.binmode
::Faraday.get(file.url) do |req|
req.options.on_data = proc { |chunk, _| tempfile.write(chunk) }
end
is_valid = validator_class.new(archive_path: tempfile.path, max_bytes: max_bytes).valid?
tempfile.unlink
end
is_valid
end
end
end
end
end