From 61bc0bccf674169d6823c02c56e1f17c89604fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Haj=C4=8Diar?= Date: Fri, 30 May 2025 10:16:53 +0200 Subject: [PATCH 1/2] Use bytesize to get content size --- lib/azure_blob/client.rb | 16 ++++++++++------ test/client/test_client.rb | 23 ++++++++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/azure_blob/client.rb b/lib/azure_blob/client.rb index 5f0da60..40588b5 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,10 @@ def put_blob_single(key, content, options = {}) Http.new(uri, headers, signer:, **options.slice(:metadata, :tags)).put(content.read) end + def content_size(content) + content.bytesize + 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 From 5c55f19dcd7905321c3ed7e11310ebd87f03a6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Haj=C4=8Diar?= Date: Sat, 31 May 2025 10:41:36 +0200 Subject: [PATCH 2/2] Fallback to size if we can't use bytesize --- lib/azure_blob/client.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/azure_blob/client.rb b/lib/azure_blob/client.rb index 40588b5..fee52bb 100644 --- a/lib/azure_blob/client.rb +++ b/lib/azure_blob/client.rb @@ -408,7 +408,11 @@ def put_blob_single(key, content, options = {}) end def content_size(content) - content.bytesize + if content.respond_to?(:bytesize) + content.bytesize + else + content.size + end end def host