diff --git a/CHANGELOG.md b/CHANGELOG.md index ace0aee..a2a833f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## [Unreleased] +- Add support for copying blobs across containers (#24) + ## [0.5.7.1] 2025-04-22 - Fixed a bug when reusing the account name in the container name. #22 diff --git a/lib/azure_blob/client.rb b/lib/azure_blob/client.rb index d3b705a..61be8bc 100644 --- a/lib/azure_blob/client.rb +++ b/lib/azure_blob/client.rb @@ -77,16 +77,22 @@ def get_blob(key, options = {}) Http.new(uri, headers, signer:).get end - # Copy a blob + # Copy a blob between containers or within the same container # # Calls to {Copy Blob From URL}[https://learn.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url] # - # Takes a key (path) and a source_key (path). + # Parameters: + # - key: destination blob path + # - source_key: source blob path + # - options: additional options + # - source_client: AzureBlob::Client instance for the source container (optional) + # If not provided, copies from within the same container # def copy_blob(key, source_key, options = {}) + source_client = options.delete(:source_client) || self uri = generate_uri("#{container}/#{key}") - source_uri = signed_uri(source_key, permissions: "r", expiry: Time.at(Time.now.to_i + 300).utc.iso8601) + source_uri = source_client.signed_uri(source_key, permissions: "r", expiry: Time.at(Time.now.to_i + 300).utc.iso8601) headers = { "x-ms-copy-source": source_uri.to_s, diff --git a/test/client/test_client.rb b/test/client/test_client.rb index 71307c3..9fac222 100644 --- a/test/client/test_client.rb +++ b/test/client/test_client.rb @@ -12,6 +12,7 @@ def setup @account_name = ENV["AZURE_ACCOUNT_NAME"] @access_key = ENV["AZURE_ACCESS_KEY"] @container = ENV["AZURE_PRIVATE_CONTAINER"] + @public_container = ENV["AZURE_PUBLIC_CONTAINER"] @principal_id = ENV["AZURE_PRINCIPAL_ID"] @host = ENV["STORAGE_BLOB_HOST"] @client = AzureBlob::Client.new( @@ -409,4 +410,26 @@ def test_get_blob_tags assert_equal({ "tag1" => "value 1", "tag 2" => "value 2" }, tags) end + + def test_copy_between_containers + destination_client = AzureBlob::Client.new( + account_name: @account_name, + access_key: @access_key, + container: @public_container, + principal_id: @principal_id, + host: @host, + ) + client.create_block_blob(key, content) + assert_equal content, client.get_blob(key) + + destination_client.copy_blob(key, key, source_client: client) + + + assert_equal content, destination_client.get_blob(key) + + begin + destination_client.delete_blob(key) + rescue AzureBlob::Http::FileNotFoundError + end + end end