diff --git a/lib/azure_blob/client.rb b/lib/azure_blob/client.rb index 5f0da60..fee52bb 100644 --- a/lib/azure_blob/client.rb +++ b/lib/azure_blob/client.rb @@ -49,7 +49,7 @@ def initialize(account_name:, access_key: nil, principal_id: nil, container:, ho # [+:block_size+] # Block size in bytes, can be used to force the method to split the upload in smaller chunk. Defaults to +AzureBlob::DEFAULT_BLOCK_SIZE+ and cannot be bigger than +AzureBlob::MAX_UPLOAD_SIZE+ def create_block_blob(key, content, options = {}) - if content.size > (options[:block_size] || DEFAULT_BLOCK_SIZE) + if content_size(content) > (options[:block_size] || DEFAULT_BLOCK_SIZE) put_blob_multiple(key, content, **options) else put_blob_single(key, content, **options) @@ -309,7 +309,7 @@ def append_blob_block(key, content, options = {}) uri.query = URI.encode_www_form(comp: "appendblock") headers = { - "Content-Length": content.size, + "Content-Length": content_size(content), "Content-Type": options[:content_type], "Content-MD5": options[:content_md5], }.merge(additional_headers(options)) @@ -333,7 +333,7 @@ def put_blob_block(key, index, content, options = {}) uri.query = URI.encode_www_form(comp: "block", blockid: block_id) headers = { - "Content-Length": content.size, + "Content-Length": content_size(content), "Content-Type": options[:content_type], "Content-MD5": options[:content_md5], }.merge(additional_headers(options)) @@ -361,7 +361,7 @@ def commit_blob_blocks(key, block_ids, options = {}) uri.query = URI.encode_www_form(comp: "blocklist") headers = { - "Content-Length": content.size, + "Content-Length": content_size(content), "Content-Type": options[:content_type], "x-ms-blob-content-md5": options[:content_md5], "x-ms-blob-content-disposition": options[:content_disposition], @@ -384,7 +384,7 @@ def generate_block_id(index) def put_blob_multiple(key, content, options = {}) content = StringIO.new(content) if content.is_a? String block_size = options[:block_size] || DEFAULT_BLOCK_SIZE - block_count = (content.size.to_f / block_size).ceil + block_count = (content_size(content).to_f / block_size).ceil block_ids = block_count.times.map do |i| put_blob_block(key, i, content.read(block_size)) end @@ -398,7 +398,7 @@ def put_blob_single(key, content, options = {}) headers = { "x-ms-blob-type": "BlockBlob", - "Content-Length": content.size, + "Content-Length": content_size(content), "Content-Type": options[:content_type], "x-ms-blob-content-md5": options[:content_md5], "x-ms-blob-content-disposition": options[:content_disposition], @@ -407,6 +407,14 @@ def put_blob_single(key, content, options = {}) Http.new(uri, headers, signer:, **options.slice(:metadata, :tags)).put(content.read) end + def content_size(content) + if content.respond_to?(:bytesize) + content.bytesize + else + content.size + end + end + def host @host ||= "https://#{account_name}.blob.#{CLOUD_REGIONS_SUFFIX[cloud_regions]}" end diff --git a/test/client/test_client.rb b/test/client/test_client.rb index 73e88d3..bd7824e 100644 --- a/test/client/test_client.rb +++ b/test/client/test_client.rb @@ -247,7 +247,7 @@ def test_get_blob_properties blob = client.get_blob_properties(key) assert blob.present? - assert_equal content.size, blob.size + assert_equal content.bytesize, blob.size end def test_get_blob_properties_404 @@ -475,4 +475,25 @@ def test_create_append_blob_additional_headers dummy.expect :delete_blob, nil, [ key ] @client = dummy end + + def test_append_blob_block_content_size + content = "Ň" + http_mock = Minitest::Mock.new + http_mock.expect :put, true, [ content ] + + stubbed_new = lambda do |uri, headers = {}, signer: nil, **kwargs| + assert_equal "2", headers[:"Content-Length"] + http_mock + end + + AzureBlob::Http.stub :new, stubbed_new do + custom_client = AzureBlob::Client.new(account_name: "foo", access_key: "bar", container: "cont") + custom_client.append_blob_block(key, content) + end + + http_mock.verify + dummy = Minitest::Mock.new + dummy.expect :delete_blob, nil, [ key ] + @client = dummy + end end