summaryrefslogtreecommitdiff
path: root/app/services
diff options
context:
space:
mode:
Diffstat (limited to 'app/services')
-rw-r--r--app/services/packages/npm/create_package_service.rb18
1 files changed, 16 insertions, 2 deletions
diff --git a/app/services/packages/npm/create_package_service.rb b/app/services/packages/npm/create_package_service.rb
index 655616c3a28..76a7f3bdc72 100644
--- a/app/services/packages/npm/create_package_service.rb
+++ b/app/services/packages/npm/create_package_service.rb
@@ -70,10 +70,24 @@ module Packages
end
end
+ # TODO (technical debt): Extract the package size calculation to its own component and unit test it separately.
+ def calculated_package_file_size
+ strong_memoize(:calculated_package_file_size) do
+ # This calculation is based on:
+ # 1. 4 chars in a Base64 encoded string are 3 bytes in the original string. Meaning 1 char is 0.75 bytes.
+ # 2. The encoded string may have 1 or 2 extra '=' chars used for padding. Each padding char means 1 byte less in the original string.
+ # Reference:
+ # - https://blog.aaronlenoir.com/2017/11/10/get-original-length-from-base-64-string/
+ # - https://en.wikipedia.org/wiki/Base64#Decoding_Base64_with_padding
+ encoded_data = attachment['data']
+ ((encoded_data.length * 0.75 ) - encoded_data[-2..].count('=')).to_i
+ end
+ end
+
def file_params
{
file: CarrierWaveStringFile.new(Base64.decode64(attachment['data'])),
- size: attachment['length'],
+ size: calculated_package_file_size,
file_sha1: version_data[:dist][:shasum],
file_name: package_file_name,
build: params[:build]
@@ -86,7 +100,7 @@ module Packages
end
def file_size_exceeded?
- project.actual_limits.exceeded?(:npm_max_file_size, attachment['length'].to_i)
+ project.actual_limits.exceeded?(:npm_max_file_size, calculated_package_file_size)
end
end
end