azure-storage-blob-2.0.0/0000755000177000017700000000000013754103060014254 5ustar avronavronazure-storage-blob-2.0.0/azure-storage-blob.gemspec0000644000177000017700000000525613754103060021335 0ustar avronavron######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: azure-storage-blob 2.0.0 ruby lib Gem::Specification.new do |s| s.name = "azure-storage-blob".freeze s.version = "2.0.0" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Microsoft Corporation".freeze] s.date = "2020-03-09" s.description = "Microsoft Azure Storage Blob Client Library for Ruby".freeze s.email = "ascl@microsoft.com".freeze s.files = ["./lib/azure/storage/blob.rb".freeze, "lib/azure/storage/blob/append.rb".freeze, "lib/azure/storage/blob/autoload.rb".freeze, "lib/azure/storage/blob/blob.rb".freeze, "lib/azure/storage/blob/blob_service.rb".freeze, "lib/azure/storage/blob/block.rb".freeze, "lib/azure/storage/blob/container.rb".freeze, "lib/azure/storage/blob/default.rb".freeze, "lib/azure/storage/blob/page.rb".freeze, "lib/azure/storage/blob/serialization.rb".freeze, "lib/azure/storage/blob/version.rb".freeze] s.homepage = "http://github.com/azure/azure-storage-ruby".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze) s.rubygems_version = "3.2.0.rc.1".freeze s.summary = "Official Ruby client library to consume Azure Storage Blob service".freeze if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_runtime_dependency(%q.freeze, ["~> 2.0"]) s.add_development_dependency(%q.freeze, ["~> 2.0"]) s.add_development_dependency(%q.freeze, ["~> 5"]) s.add_development_dependency(%q.freeze, ["~> 1"]) s.add_development_dependency(%q.freeze, ["~> 1.0"]) s.add_runtime_dependency(%q.freeze, ["~> 1.10.4"]) s.add_development_dependency(%q.freeze, ["~> 13.0"]) s.add_development_dependency(%q.freeze, ["~> 0.7"]) s.add_development_dependency(%q.freeze, ["~> 0.9", ">= 0.9.11"]) else s.add_dependency(%q.freeze, ["~> 2.0"]) s.add_dependency(%q.freeze, ["~> 2.0"]) s.add_dependency(%q.freeze, ["~> 5"]) s.add_dependency(%q.freeze, ["~> 1"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, ["~> 1.10.4"]) s.add_dependency(%q.freeze, ["~> 13.0"]) s.add_dependency(%q.freeze, ["~> 0.7"]) s.add_dependency(%q.freeze, ["~> 0.9", ">= 0.9.11"]) end end azure-storage-blob-2.0.0/lib/0000755000177000017700000000000013754103060015022 5ustar avronavronazure-storage-blob-2.0.0/lib/azure/0000755000177000017700000000000013754103060016150 5ustar avronavronazure-storage-blob-2.0.0/lib/azure/storage/0000755000177000017700000000000013754103060017614 5ustar avronavronazure-storage-blob-2.0.0/lib/azure/storage/blob.rb0000644000177000017700000000256113754103060021063 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "azure/storage/blob/autoload" azure-storage-blob-2.0.0/lib/azure/storage/blob/0000755000177000017700000000000013754103060020532 5ustar avronavronazure-storage-blob-2.0.0/lib/azure/storage/blob/default.rb0000644000177000017700000001354713754103060022515 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "rbconfig" module Azure::Storage::Blob module Default # Default REST service (STG) version number STG_VERSION = "2018-11-09" # The number of default concurrent requests for parallel operation. DEFAULT_PARALLEL_OPERATION_THREAD_COUNT = 1 # Constant representing a kilobyte (Non-SI version). KB = 1024 # Constant representing a megabyte (Non-SI version). MB = 1024 * 1024 # Constant representing a gigabyte (Non-SI version). GB = 1024 * 1024 * 1024 # Specifies HTTP. HTTP = "http" # Specifies HTTPS. HTTPS = "https" # Default HTTP port. DEFAULT_HTTP_PORT = 80 # Default HTTPS port. DEFAULT_HTTPS_PORT = 443 # Marker for atom metadata. XML_METADATA_MARKER = "$" # Marker for atom value. XML_VALUE_MARKER = "_" # Default value for Content-Type if request has body. CONTENT_TYPE_VALUE = "application/octet-stream" # Default User Agent header string USER_AGENT = "Azure-Storage/#{Azure::Storage::Blob::Version.to_uas}-#{Azure::Storage::Common::Version.to_uas} (Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}; #{Azure::Storage::Common::Default.os})".freeze end # Defines constants for use with blob operations. module BlobConstants # XML element for the latest. LATEST_ELEMENT = "Latest" # XML element for uncommitted blocks. UNCOMMITTED_ELEMENT = "Uncommitted" # XML element for a block list. BLOCK_LIST_ELEMENT = "BlockList" # XML element for committed blocks. COMMITTED_ELEMENT = "Committed" # The default write page size, in bytes, used by blob streams. DEFAULT_WRITE_PAGE_SIZE_IN_BYTES = 4 * 1024 * 1024 # The minimum write page size, in bytes, used by blob streams. MIN_WRITE_PAGE_SIZE_IN_BYTES = 2 * 1024 * 1024 # The default maximum size, in bytes, of a blob before it must be separated into blocks. DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES = 128 * 1024 * 1024 # The default write block size, in bytes, used by blob streams. DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES = 4 * 1024 * 1024 # The maximum size of a single block. MAX_BLOCK_SIZE = 100 * 1024 * 1024 # The maximum count of blocks for a block blob MAX_BLOCK_COUNT = 50000 # The maximum size of block blob MAX_BLOCK_BLOB_SIZE = 50000 * 100 * 1024 * 1024 # The maximum size of block blob MAX_APPEND_BLOB_SIZE = 1024 * 1024 * 1024 * 1024 # The maximum size, in bytes, of a blob before it must be separated into blocks. MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES = 256 * 1024 * 1024 # The maximum range get size when requesting for a contentMD5 MAX_RANGE_GET_SIZE_WITH_MD5 = 4 * 1024 * 1024 # The maximum page range size for a page update operation. MAX_UPDATE_PAGE_SIZE = 4 * 1024 * 1024 # The maximum buffer size for writing a stream buffer. MAX_QUEUED_WRITE_DISK_BUFFER_SIZE = 64 * 1024 * 1024 # Max size for single get page range. The max value should be 150MB # http://blogs.msdn.com/b/windowsazurestorage/archive/2012/03/26/getting-the-page-ranges-of-a-large-page-blob-in-segments.aspx MAX_SINGLE_GET_PAGE_RANGE_SIZE = 37 * 4 * 1024 * 1024 # The size of a page, in bytes, in a page blob. PAGE_SIZE = 512 # The maximum validity of user delegation SAS (7 days from the current time). MAX_USER_DELEGATION_KEY_SECONDS = 60 * 60 * 24 * 7 # Resource types. module ResourceTypes CONTAINER = "c" BLOB = "b" end # List blob types. module ListBlobTypes Blob = "b" Directory = "d" end # Put page write options module PageWriteOptions UPDATE = "update" CLEAR = "clear" end # Blob types module BlobTypes BLOCK = "BlockBlob" PAGE = "PageBlob" APPEND = "AppendBlob" end # Blob lease constants module LeaseOperation ACQUIRE = "acquire" RENEW = "renew" CHANGE = "change" RELEASE = "release" BREAK = "break" end end module BlobErrorCodeStrings INVALID_BLOCK_ID = "InvalidBlockId" BLOB_NOT_FOUND = "BlobNotFound" BLOB_ALREADY_EXISTS = "BlobAlreadyExists" CONTAINER_ALREADY_EXISTS = "ContainerAlreadyExists" CONTAINER_NOT_FOUND = "ContainerNotFound" INVALID_BLOB_OR_BLOCK = "InvalidBlobOrBlock" INVALID_BLOCK_LIST = "InvalidBlockList" MAX_BLOB_SIZE_CONDITION_NOT_MET = "MaxBlobSizeConditionNotMet" APPEND_POSITION_CONDITION_NOT_MET = "AppendPositionConditionNotMet" end end azure-storage-blob-2.0.0/lib/azure/storage/blob/serialization.rb0000644000177000017700000003442013754103060023737 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "base64" module Azure::Storage module Blob module Serialization include Azure::Storage::Common::Service::Serialization def self.container_enumeration_results_from_xml(xml) xml = slopify(xml) expect_node("EnumerationResults", xml) results = enumeration_results_from_xml(xml, Azure::Storage::Common::Service::EnumerationResults.new) return results unless (xml > "Containers").any? && ((xml > "Containers") > "Container").any? if xml.Containers.Container.count == 0 results.push(container_from_xml(xml.Containers.Container)) else xml.Containers.Container.each { |container_node| results.push(container_from_xml(container_node)) } end results end def self.key_info_to_xml(start, expiry) builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| xml.KeyInfo { xml.Start start.utc.iso8601 xml.Expiry expiry.utc.iso8601 } end builder.to_xml end def self.user_delegation_key_from_xml(xml) xml = slopify(xml) expect_node("UserDelegationKey", xml) Azure::Storage::Common::Service::UserDelegationKey.new do |user_delegation_key| user_delegation_key.signed_oid = xml.SignedOid.text if (xml > "SignedOid").any? user_delegation_key.signed_tid = xml.SignedTid.text if (xml > "SignedTid").any? user_delegation_key.signed_start = xml.SignedStart.text if (xml > "SignedStart").any? user_delegation_key.signed_expiry = xml.SignedExpiry.text if (xml > "SignedExpiry").any? user_delegation_key.signed_service = xml.SignedService.text if (xml > "SignedService").any? user_delegation_key.signed_version = xml.SignedVersion.text if (xml > "SignedVersion").any? user_delegation_key.value = xml.Value.text if (xml > "Value").any? end end def self.container_from_xml(xml) xml = slopify(xml) expect_node("Container", xml) Container::Container.new do |container| container.name = xml.Name.text if (xml > "Name").any? container.properties = container_properties_from_xml(xml.Properties) if (xml > "Properties").any? container.metadata = metadata_from_xml(xml.Metadata) if (xml > "Metadata").any? container.public_access_level = public_access_level_from_properties_xml(xml.Properties) if (xml > "Properties").any? end end def self.container_from_headers(headers) Container::Container.new do |container| container.properties = container_properties_from_headers(headers) container.public_access_level = public_access_level_from_headers(headers) container.metadata = metadata_from_headers(headers) end end def self.container_properties_from_xml(xml) xml = slopify(xml) expect_node("Properties", xml) props = {} props[:last_modified] = (xml > "Last-Modified").text if (xml > "Last-Modified").any? props[:etag] = xml.Etag.text if (xml > "Etag").any? props[:lease_status] = xml.LeaseStatus.text if (xml > "LeaseStatus").any? props[:lease_state] = xml.LeaseState.text if (xml > "LeaseState").any? props[:lease_duration] = xml.LeaseDuration.text if (xml > "LeaseDuration").any? props end def self.container_properties_from_headers(headers) props = {} props[:last_modified] = headers["Last-Modified"] props[:etag] = headers["Etag"] props[:lease_status] = headers["x-ms-lease-status"] props[:lease_state] = headers["x-ms-lease-state"] props[:lease_duration] = headers["x-ms-lease-duration"] props end def self.public_access_level_from_headers(headers) headers["x-ms-blob-public-access"] end def self.public_access_level_from_properties_xml(xml) (xml > "PublicAccess").any? ? xml.PublicAccess.text : nil end def self.blob_enumeration_results_from_xml(xml) xml = slopify(xml) expect_node("EnumerationResults", xml) results = enumeration_results_from_xml(xml, Azure::Storage::Common::Service::EnumerationResults.new) return results unless (xml > "Blobs").any? if ((xml > "Blobs") > "Blob").any? if xml.Blobs.Blob.count == 0 results.push(blob_from_xml(xml.Blobs.Blob)) else xml.Blobs.Blob.each { |blob_node| results.push(blob_from_xml(blob_node)) } end end if ((xml > "Blobs") > "BlobPrefix").any? if xml.Blobs.BlobPrefix.count == 0 results.push(blob_prefix_from_xml(xml.Blobs.BlobPrefix)) else xml.Blobs.BlobPrefix.each { |blob_prefix| results.push(blob_prefix_from_xml(blob_prefix)) } end end results end def self.blob_prefix_from_xml(xml) xml = slopify(xml) expect_node("BlobPrefix", xml) name = xml.Name.text if (xml > "Name").any? name end def self.blob_from_xml(xml) xml = slopify(xml) expect_node("Blob", xml) Blob.new do |blob| blob.name = xml.Name.text if (xml > "Name").any? blob.snapshot = xml.Snapshot.text if (xml > "Snapshot").any? blob.metadata = metadata_from_xml(xml.Metadata) if (xml > "Metadata").any? if (xml > "Properties").any? blob.properties = blob_properties_from_xml(xml.Properties) blob.encrypted = xml.Properties.ServerEncrypted.text == "true" if (xml.Properties > "ServerEncrypted").any? end end end def self.blob_from_headers(headers) Blob.new do |blob| blob.properties = blob_properties_from_headers(headers) blob.metadata = metadata_from_headers(headers) blob.encrypted = headers[Azure::Storage::Common::HeaderConstants::REQUEST_SERVER_ENCRYPTED] || headers[Azure::Storage::Common::HeaderConstants::SERVER_ENCRYPTED] blob.encrypted = blob.encrypted.to_s == "true" unless blob.encrypted.nil? end end def self.blob_properties_from_xml(xml) xml = slopify(xml) expect_node("Properties", xml) props = {} props[:last_modified] = (xml > "Last-Modified").text if (xml > "Last-Modified").any? props[:etag] = xml.Etag.text if (xml > "Etag").any? props[:lease_status] = xml.LeaseStatus.text if (xml > "LeaseStatus").any? props[:lease_state] = xml.LeaseState.text if (xml > "LeaseState").any? props[:lease_duration] = xml.LeaseDuration.text if (xml > "LeaseDuration").any? props[:content_length] = (xml > "Content-Length").text.to_i if (xml > "Content-Length").any? props[:content_type] = (xml > "Content-Type").text if (xml > "Content-Type").any? props[:content_encoding] = (xml > "Content-Encoding").text if (xml > "Content-Encoding").any? props[:content_language] = (xml > "Content-Language").text if (xml > "Content-Language").any? props[:content_md5] = (xml > "Content-MD5").text if (xml > "Content-MD5").any? props[:cache_control] = (xml > "Cache-Control").text if (xml > "Cache-Control").any? props[:sequence_number] = (xml > "x-ms-blob-sequence-number").text.to_i if (xml > "x-ms-blob-sequence-number").any? props[:blob_type] = xml.BlobType.text if (xml > "BlobType").any? props[:copy_id] = xml.CopyId.text if (xml > "CopyId").any? props[:copy_status] = xml.CopyStatus.text if (xml > "CopyStatus").any? props[:copy_source] = xml.CopySource.text if (xml > "CopySource").any? props[:copy_progress] = xml.CopyProgress.text if (xml > "CopyProgress").any? props[:copy_completion_time] = xml.CopyCompletionTime.text if (xml > "CopyCompletionTime").any? props[:copy_status_description] = xml.CopyStatusDescription.text if (xml > "CopyStatusDescription").any? props[:incremental_copy] = xml.IncrementalCopy.text == "true" if (xml > "IncrementalCopy").any? props end def self.blob_properties_from_headers(headers) props = {} props[:last_modified] = headers["Last-Modified"] props[:etag] = headers["Etag"] props[:lease_status] = headers["x-ms-lease-status"] props[:lease_state] = headers["x-ms-lease-state"] props[:lease_duration] = headers["x-ms-lease-duration"] props[:content_length] = headers["x-ms-blob-content-length"] || headers["Content-Length"] props[:content_length] = props[:content_length].to_i if props[:content_length] props[:content_type] = headers["x-ms-blob-content-type"] || headers["Content-Type"] props[:content_encoding] = headers["x-ms-blob-content-encoding"] || headers["Content-Encoding"] props[:content_language] = headers["x-ms-blob-content-language"] || headers["Content-Language"] props[:content_disposition] = headers["x-ms-blob-content-disposition"] || headers["Content-Disposition"] props[:content_md5] = headers["x-ms-blob-content-md5"] || headers["Content-MD5"] props[:range_md5] = headers["Content-MD5"] if headers["x-ms-blob-content-md5"] && headers["Content-MD5"] props[:cache_control] = headers["x-ms-blob-cache-control"] || headers["Cache-Control"] props[:sequence_number] = headers["x-ms-blob-sequence-number"].to_i if headers["x-ms-blob-sequence-number"] props[:blob_type] = headers["x-ms-blob-type"] props[:copy_id] = headers["x-ms-copy-id"] props[:copy_status] = headers["x-ms-copy-status"] props[:copy_source] = headers["x-ms-copy-source"] props[:copy_progress] = headers["x-ms-copy-progress"] props[:copy_completion_time] = headers["x-ms-copy-completion-time"] props[:copy_status_description] = headers["x-ms-copy-status-description"] props[:accept_ranges] = headers["Accept-Ranges"].to_i if headers["Accept-Ranges"] props[:append_offset] = headers["x-ms-blob-append-offset"].to_i if headers["x-ms-blob-append-offset"] props[:committed_count] = headers["x-ms-blob-committed-block-count"].to_i if headers["x-ms-blob-committed-block-count"] props[:incremental_copy] = headers["x-ms-incremental-copy"].to_s == "true" if headers["x-ms-incremental-copy"] props end def self.block_list_to_xml(block_list) builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| xml.BlockList { block_list.each { |block| encoded_id = Base64.strict_encode64(block[0]) case block[1] when :uncommitted xml.Uncommitted encoded_id when :committed xml.Committed encoded_id else xml.Latest encoded_id end } } end builder.to_xml end def self.block_list_from_xml(xml) xml = slopify(xml) expect_node("BlockList", xml) block_list = { committed: [], uncommitted: [] } if ((xml > "CommittedBlocks") > "Block").any? if xml.CommittedBlocks.Block.count == 0 add_block(:committed, xml.CommittedBlocks.Block, block_list) else xml.CommittedBlocks.Block.each { |block_node| add_block(:committed, block_node, block_list) } end end return block_list unless (xml > "UncommittedBlocks") if ((xml > "UncommittedBlocks") > "Block").any? if xml.UncommittedBlocks.Block.count == 0 add_block(:uncommitted, xml.UncommittedBlocks.Block, block_list) else xml.UncommittedBlocks.Block.each { |block_node| add_block(:uncommitted, block_node, block_list) } end end block_list end def self.add_block(type, block_node, block_list) block = Block.new do |b| b.name = Base64.strict_decode64(block_node.Name.text) if (block_node > "Name").any? b.size = block_node.Size.text.to_i if (block_node > "Size").any? b.type = type end block_list[type].push block end def self.page_list_from_xml(xml) xml = slopify(xml) expect_node("PageList", xml) page_list = [] return page_list unless (xml > "PageRange").any? if xml.PageRange.count == 0 page_list.push [xml.PageRange.Start.text.to_i, xml.PageRange.End.text.to_i] else xml.PageRange.each { |page_range| page_list.push [page_range.Start.text.to_i, page_range.End.text.to_i] } end page_list end end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/block.rb0000644000177000017700000010106213754103060022151 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "base64" module Azure::Storage module Blob # Represents a Block as part of a BlockList # The type should be one of :uncommitted, :committed or :latest class Block def initialize @type = :latest yield self if block_given? end attr_accessor :name attr_accessor :size attr_accessor :type end # Public: Creates a new block blob or updates the content of an existing block blob. # # Updating an existing block blob overwrites any existing metadata on the blob # Partial updates are not supported with create_block_blob the content of the # existing blob is overwritten with the content of the new blob. To perform a # partial update of the content of a block blob, use the create_block_list # method. # # Note that the default content type is application/octet-stream. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. The content of the blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport. # When this header is specified, the storage service checks the hash that has arrived with the one that was sent. # If the two hashes do not match, the operation will fail with error code 400 (Bad Request). # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used. # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'. # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob def create_block_blob(container, blob, content, options = {}) size = if content.respond_to? :size content.size elsif options[:content_length] options[:content_length] else raise ArgumentError, "Either optional parameter 'content_length' should be set or 'content' should implement 'size' method to get payload's size." end threshold = get_single_upload_threshold(options[:single_upload_threshold]) if size > threshold create_block_blob_multiple_put(container, blob, content, size, options) else create_block_blob_single_put(container, blob, content, options) end end # Public: Creates a new block to be committed as part of a block blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +block_id+ - String. The block id. Note: this should be the raw block id, not Base64 encoded. # * +content+ - IO or String. The content of the blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_md5+ - String. Content MD5 for the request contents. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an # active lease, specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd135726.aspx # # Returns response of the operation def put_blob_block(container, blob, block_id, content, options = {}) query = { "comp" => "block" } StorageService.with_query query, "blockid", Base64.strict_encode64(block_id) StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} StorageService.with_header headers, "Content-MD5", options[:content_md5] headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] response = call(:put, uri, content, headers, options) response.headers["Content-MD5"] end # Public: Commits existing blob blocks to a blob. # # This method writes a blob by specifying the list of block IDs that make up the # blob. In order to be written as part of a blob, a block must have been # successfully written to the server in a prior put_blob_block method. # # You can call Put Block List to update a blob by uploading only those blocks # that have changed, then committing the new and existing blocks together. # You can do this by specifying whether to commit a block from the committed # block list or from the uncommitted block list, or to commit the most recently # uploaded version of the block, whichever list it may belong to. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +block_list+ - Array. A ordered list of lists in the following format: # [ ["block_id1", :committed], ["block_id2", :uncommitted], ["block_id3"], ["block_id4", :committed]... ] # The first element of the inner list is the block_id, the second is optional # and can be either :committed or :uncommitted to indicate in which group of blocks # the id should be looked for. If it is omitted, the latest of either group will be used. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. Content MD5 for the request contents (not the blob contents!) # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an # active lease, specify the valid lease ID for this header. # # This operation also supports the use of conditional headers to commit the block list if a specified condition is met. # For more information, see https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx # # See http://msdn.microsoft.com/en-us/library/azure/dd179467.aspx # # Returns nil on success def commit_blob_blocks(container, blob, block_list, options = {}) query = { "comp" => "blocklist" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} unless options.empty? StorageService.with_header headers, "Content-MD5", options[:transactional_md5] StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type] StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding] StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language] StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5] StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control] StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition] StorageService.add_metadata_to_headers(options[:metadata], headers) add_blob_conditional_headers(options, headers) headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end headers["x-ms-blob-content-type"] = Default::CONTENT_TYPE_VALUE unless headers["x-ms-blob-content-type"] body = Serialization.block_list_to_xml(block_list) call(:put, uri, body, headers, options) nil end # Public: Retrieves the list of blocks that have been uploaded as part of a block blob. # # There are two block lists maintained for a blob: # 1) Committed Block List: The list of blocks that have been successfully # committed to a given blob with commitBlobBlocks. # 2) Uncommitted Block List: The list of blocks that have been uploaded for a # blob using Put Block (REST API), but that have not yet been committed. # These blocks are stored in Microsoft Azure in association with a blob, but do # not yet form part of the blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # If this header is specified and both of these conditions are not met, the request will fail # and the operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd179400.aspx # # Returns a list of Azure::Storage::Entity::Blob::Block instances def list_blob_blocks(container, blob, options = {}) options[:blocklist_type] = options[:blocklist_type] || :all query = { "comp" => "blocklist" } StorageService.with_query query, "snapshot", options[:snapshot] StorageService.with_query query, "blocklisttype", options[:blocklist_type].to_s if options[:blocklist_type] StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {} options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = blob_uri(container, blob, query, options) response = call(:get, uri, nil, headers, options) Serialization.block_list_from_xml(response.body) end # Public: Creates a new block blob or updates the content of an existing block blob. # # Updating an existing block blob overwrites any existing metadata on the blob # Partial updates are not supported with create_block_blob the content of the # existing blob is overwritten with the content of the new blob. To perform a # partial update of the content of a block blob, use the create_block_list # method. # # Note that the default content type is application/octet-stream. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. The content of the blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport. # When this header is specified, the storage service checks the hash that has arrived with the one that was sent. # If the two hashes do not match, the operation will fail with error code 400 (Bad Request). # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used. # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'. # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob alias create_block_blob_from_content create_block_blob # Protected: Creates a new block blob or updates the content of an existing block blob with single API call # # Updating an existing block blob overwrites any existing metadata on the blob # Partial updates are not supported with create_block_blob the content of the # existing blob is overwritten with the content of the new blob. To perform a # partial update of the content of a block blob, use the create_block_list # method. # # Note that the default content type is application/octet-stream. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. The content of the blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport. # When this header is specified, the storage service checks the hash that has arrived with the one that was sent. # If the two hashes do not match, the operation will fail with error code 400 (Bad Request). # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'. # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob protected def create_block_blob_single_put(container, blob, content, options = {}) query = {} StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} # set x-ms-blob-type to BlockBlob StorageService.with_header headers, "x-ms-blob-type", "BlockBlob" # set the rest of the optional headers StorageService.with_header headers, "Content-MD5", options[:transactional_md5] StorageService.with_header headers, "Content-Length", options[:content_length] StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding] StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language] StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5] StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control] StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition] StorageService.with_header headers, "x-ms-lease-id", options[:lease_id] StorageService.add_metadata_to_headers options[:metadata], headers add_blob_conditional_headers options, headers headers["x-ms-blob-content-type"] = get_or_apply_content_type(content, options[:content_type]) # call PutBlob response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result.metadata = options[:metadata] if options[:metadata] result end # Protected: Creates a new block blob or updates the content of an existing block blob with multiple upload # # Updating an existing block blob overwrites any existing metadata on the blob # Partial updates are not supported with create_block_blob the content of the # existing blob is overwritten with the content of the new blob. To perform a # partial update of the content of a block blob, use the create_block_list # method. # # Note that the default content type is application/octet-stream. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. The content of the blob. # * +size+ - Integer. The size of the content. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob protected def create_block_blob_multiple_put(container, blob, content, size, options = {}) content_type = get_or_apply_content_type(content, options[:content_type]) content = StringIO.new(content) if content.is_a? String block_size = get_block_size(size) # Get the number of blocks block_count = (Float(size) / Float(block_size)).ceil block_list = [] for block_id in 0...block_count id = block_id.to_s.rjust(6, "0") put_blob_block(container, blob, id, content.read(block_size), timeout: options[:timeout], lease_id: options[:lease_id]) block_list.push([id]) end # Commit the blocks put commit_options = {} commit_options[:content_type] = content_type commit_options[:content_encoding] = options[:content_encoding] if options[:content_encoding] commit_options[:content_language] = options[:content_language] if options[:content_language] commit_options[:content_md5] = options[:content_md5] if options[:content_md5] commit_options[:cache_control] = options[:cache_control] if options[:cache_control] commit_options[:content_disposition] = options[:content_disposition] if options[:content_disposition] commit_options[:metadata] = options[:metadata] if options[:metadata] commit_options[:timeout] = options[:timeout] if options[:timeout] commit_options[:request_id] = options[:request_id] if options[:request_id] commit_options[:lease_id] = options[:lease_id] if options[:lease_id] commit_blob_blocks(container, blob, block_list, commit_options) get_properties_options = {} get_properties_options[:lease_id] = options[:lease_id] if options[:lease_id] # Get the blob properties get_blob_properties(container, blob, get_properties_options) end # Protected: Gets the single upload threshold according to user's preference # # ==== Attributes # # * +container+ - String. The container name. # # Returns an Integer protected def get_single_upload_threshold(userThreshold) if userThreshold.nil? BlobConstants::DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES elsif userThreshold <= 0 raise ArgumentError, "Single Upload Threshold should be positive number" elsif userThreshold < BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES userThreshold else BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES end end protected def get_block_size(size) if size > BlobConstants::MAX_BLOCK_BLOB_SIZE raise ArgumentError, "Block blob size should be less than #{BlobConstants::MAX_BLOCK_BLOB_SIZE} bytes in size" elsif (size / BlobConstants::MAX_BLOCK_COUNT) < BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES else BlobConstants::MAX_BLOCK_SIZE end end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/blob_service.rb0000644000177000017700000012635513754103060023531 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "azure/storage/blob/page" require "azure/storage/blob/block" require "azure/storage/blob/append" require "azure/storage/blob/blob" module Azure::Storage include Azure::Storage::Common::Service StorageService = Azure::Storage::Common::Service::StorageService module Blob class BlobService < StorageService include Azure::Storage::Common::Core::Utility include Azure::Storage::Blob include Azure::Storage::Blob::Container class << self # Public: Creates an instance of [Azure::Storage::Blob::BlobService] # # ==== Attributes # # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator. # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost. # * +:storage_account_name+ - String. The name of the storage account. # * +:storage_access_key+ - Base64 String. The access key of the storage account. # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service. # * +:storage_blob_host+ - String. Specified Blob service endpoint or hostname # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Service, to # * +:default_endpoints_protocol+ - String. http or https # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints # * +:ca_file+ - String. File path of the CA file if having issue with SSL # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library # # The valid set of options include: # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce # * Anonymous Blob: only +:storage_blob_host+, if it is to only access blobs within a container # # Additional notes: # * Specified hosts can be set when use account name with access key or sas token # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts # * Storage emulator always use path style URI # * +:ca_file+ is independent. # # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship # # @return [Azure::Storage::Blob::BlobService] def create(options = {}, &block) service_options = { client: Azure::Storage::Common::Client::create(options, &block), api_version: Azure::Storage::Blob::Default::STG_VERSION } service_options[:user_agent_prefix] = options[:user_agent_prefix] if options[:user_agent_prefix] Azure::Storage::Blob::BlobService.new(service_options, &block) end # Public: Creates an instance of [Azure::Storage::Blob::BlobService] with Storage Emulator # # ==== Attributes # # * +proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost. # # @return [Azure::Storage::Blob::BlobService] def create_development(proxy_uri = nil, &block) service_options = { client: Azure::Storage::Common::Client::create_development(proxy_uri, &block), api_version: Azure::Storage::Blob::Default::STG_VERSION } Azure::Storage::Blob::BlobService.new(service_options, &block) end # Public: Creates an instance of [Azure::Storage::Blob::BlobService] from Environment Variables # # @return [Azure::Storage::Blob::BlobService] def create_from_env(&block) service_options = { client: Azure::Storage::Common::Client::create_from_env(&block), api_version: Azure::Storage::Blob::Default::STG_VERSION } Azure::Storage::Blob::BlobService.new(service_options, &block) end # Public: Creates an instance of [Azure::Storage::Blob::BlobService] from Environment Variables # # ==== Attributes # # * +connection_string+ - String. Please refer to https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/. # # @return [Azure::Storage::Blob::BlobService] def create_from_connection_string(connection_string, &block) service_options = { client: Azure::Storage::Common::Client::create_from_connection_string(connection_string, &block), api_version: Azure::Storage::Blob::Default::STG_VERSION } Azure::Storage::Blob::BlobService.new(service_options, &block) end end # Public: Initializes an instance of [Azure::Storage::Blob::BlobService] # # ==== Attributes # # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator. # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost. # * +:storage_connection_string+ - String. The storage connection string. # * +:storage_account_name+ - String. The name of the storage account. # * +:storage_access_key+ - Base64 String. The access key of the storage account. # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service. # * +:storage_blob_host+ - String. Specified Blob serivce endpoint or hostname # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Serivce, to # * +:default_endpoints_protocol+ - String. http or https # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints # * +:ca_file+ - String. File path of the CA file if having issue with SSL # * +:ssl_version+ - Symbol. The ssl version to be used, sample: :TLSv1_1, :TLSv1_2, for the details, see https://github.com/ruby/openssl/blob/master/lib/openssl/ssl.rb # * +:ssl_min_version+ - Symbol. The min ssl version supported, only supported in Ruby 2.5+ # * +:ssl_max_version+ - Symbol. The max ssl version supported, only supported in Ruby 2.5+ # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library # * +:client+ - Azure::Storage::Common::Client. The common client used to initalize the service. # # The valid set of options include: # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce # * Azure::Storage::Common::Client: The common client used to initalize the service. This client can be initalized and used repeatedly. # * Anonymous Blob: only +:storage_blob_host+, if it is to only access blobs within a container # # Additional notes: # * Specified hosts can be set when use account name with access key or sas token # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts # * Storage emulator always use path style URI # * +:ca_file+ is independent. # # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship def initialize(options = {}, &block) service_options = options.clone client_config = service_options[:client] ||= Azure::Storage::Common::Client::create(service_options, &block) @user_agent_prefix = service_options[:user_agent_prefix] if service_options[:user_agent_prefix] @api_version = service_options[:api_version] || Azure::Storage::Blob::Default::STG_VERSION signer = service_options[:signer] || client_config.signer || Azure::Storage::Common::Core::Auth::SharedKey.new(client_config.storage_account_name, client_config.storage_access_key) signer.api_ver = @api_version if signer.is_a? Azure::Storage::Common::Core::Auth::SharedAccessSignatureSigner super(signer, client_config.storage_account_name, service_options, &block) @storage_service_host[:primary] = client.storage_blob_host @storage_service_host[:secondary] = client.storage_blob_host true end def call(method, uri, body = nil, headers = {}, options = {}) content_type = get_or_apply_content_type(body, headers[Azure::Storage::Common::HeaderConstants::BLOB_CONTENT_TYPE]) headers[Azure::Storage::Common::HeaderConstants::BLOB_CONTENT_TYPE] = content_type if content_type headers["x-ms-version"] = @api_version ? @api_version : Default::STG_VERSION headers["User-Agent"] = @user_agent_prefix ? "#{@user_agent_prefix}; #{Default::USER_AGENT}" : Default::USER_AGENT response = super # Force the response.body to the content charset of specified in the header. # Content-Type is echo'd back for the blob and is used to store the encoding of the octet stream if !response.nil? && !response.body.nil? && response.headers["Content-Type"] charset = parse_charset_from_content_type(response.headers["Content-Type"]) response.body.force_encoding(charset) if charset && charset.length > 0 end response end # Public: Get a list of Containers from the server. # # ==== Attributes # # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:prefix+ - String. Filters the results to return only containers # whose name begins with the specified prefix. (optional) # # * +:marker+ - String. An identifier the specifies the portion of the # list to be returned. This value comes from the property # Azure::Storage::Common::EnumerationResults.continuation_token when there # are more containers available than were returned. The # marker value may then be used here to request the next set # of list items. (optional) # # * +:max_results+ - Integer. Specifies the maximum number of containers to return. # If max_results is not specified, or is a value greater than # 5,000, the server will return up to 5,000 items. If it is set # to a value less than or equal to zero, the server will return # status code 400 (Bad Request). (optional) # # * +:metadata+ - Boolean. Specifies whether or not to return the container metadata. # (optional, Default=false) # # * +:timeout+ - Integer. A timeout in seconds. # # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # # See: https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx # # NOTE: Metadata requested with the :metadata parameter must have been stored in # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob # service. Beginning with that version, all metadata names must adhere to the naming # conventions for C# identifiers. See: https://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx # # Any metadata with invalid names which were previously stored, will be returned with the # key "x-ms-invalid-name" in the metadata hash. This may contain multiple values and be an # Array (vs a String if it only contains a single value). # # Returns an Azure::Storage::Common::EnumerationResults # def list_containers(options = {}) query = {} if options StorageService.with_query query, "prefix", options[:prefix] StorageService.with_query query, "marker", options[:marker] StorageService.with_query query, "maxresults", options[:max_results].to_s if options[:max_results] StorageService.with_query query, "include", "metadata" if options[:metadata] == true StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] end options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = containers_uri(query, options) response = call(:get, uri, nil, {}, options) Serialization.container_enumeration_results_from_xml(response.body) end # Public: Obtain a user delegation key for the purpose of signing SAS tokens. # # ==== Attributes # # * +start+ - Time. The start time for the user delegation SAS. # * +expiry+ - Time. The expiry time of user delegation SAS. # # See: https://docs.microsoft.com/en-us/rest/api/storageservices/get-user-delegation-key # # NOTE: A token credential must be present on the service object for this request to succeed. # The start and expiry times must be within 7 days of the current time. # # Returns an Azure::Storage::Common::UserDelegationKey # def get_user_delegation_key(start, expiry) max_delegation_time = Time.now + BlobConstants::MAX_USER_DELEGATION_KEY_SECONDS raise ArgumentError, "Start time must be before #{max_delegation_time}" if start > max_delegation_time raise ArgumentError, "Expiry time must be before #{max_delegation_time}" if expiry > max_delegation_time raise ArgumentError, "Start time must be before expiry time" if start >= expiry body = Serialization.key_info_to_xml(start, expiry) response = call(:post, user_delegation_key_uri, body) Serialization.user_delegation_key_from_xml(response.body) end # Protected: Establishes an exclusive write lock on a container or a blob. The lock duration can be 15 to 60 seconds, or can be infinite. # To write to a locked container or blob, a client must provide a lease ID. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:duration+ - Integer. Default -1. Specifies the duration of the lease, in seconds, or negative one (-1) # for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. (optional) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request # to write, or to renew, change, or release the lease. # protected def acquire_lease(container, blob, options = {}) query = { "comp" => "lease" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] if blob uri = blob_uri(container, blob, query) else uri = container_uri(container, query) end duration = -1 duration = options[:duration] if options[:duration] headers = {} StorageService.with_header headers, "x-ms-lease-action", "acquire" StorageService.with_header headers, "x-ms-lease-duration", duration.to_s if duration StorageService.with_header headers, "x-ms-proposed-lease-id", options[:proposed_lease_id] StorageService.with_header headers, "Origin", options[:origin].to_s if options[:origin] add_blob_conditional_headers options, headers response = call(:put, uri, nil, headers, options) response.headers["x-ms-lease-id"] end # Protected: Renews the lease. The lease can be renewed if the lease ID specified on the request matches that # associated with the blob. Note that the lease may be renewed even if it has expired as long as the container or blob # has not been modified or leased again since the expiration of that lease. When you renew a lease, the # lease duration clock resets. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The lease id # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns the renewed lease id # protected def renew_lease(container, blob, lease, options = {}) query = { "comp" => "lease" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] if blob uri = blob_uri(container, blob, query) else uri = container_uri(container, query) end headers = {} StorageService.with_header headers, "x-ms-lease-action", "renew" StorageService.with_header headers, "x-ms-lease-id", lease StorageService.with_header headers, "Origin", options[:origin].to_s if options[:origin] add_blob_conditional_headers options, headers response = call(:put, uri, nil, headers, options) response.headers["x-ms-lease-id"] end # Protected: Change the ID of an existing lease. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The existing lease id. # * +proposed_lease+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional). # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request # to write, or to renew, change, or release the lease. # protected def change_lease(container, blob, lease, proposed_lease, options = {}) query = { "comp" => "lease" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] if blob uri = blob_uri(container, blob, query) else uri = container_uri(container, query) end headers = {} StorageService.with_header headers, "x-ms-lease-action", "change" StorageService.with_header headers, "x-ms-lease-id", lease StorageService.with_header headers, "x-ms-proposed-lease-id", proposed_lease StorageService.with_header headers, "Origin", options[:origin].to_s if options[:origin] add_blob_conditional_headers options, headers response = call(:put, uri, nil, headers, options) response.headers["x-ms-lease-id"] end # Protected: Releases the lease. The lease may be released if the lease ID specified on the request matches that # associated with the container or blob. Releasing the lease allows another client to immediately acquire the lease for # the container or blob as soon as the release is complete. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The lease id. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns nil on success # protected def release_lease(container, blob, lease, options = {}) query = { "comp" => "lease" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] if blob uri = blob_uri(container, blob, query) else uri = container_uri(container, query) end headers = {} StorageService.with_header headers, "x-ms-lease-action", "release" StorageService.with_header headers, "x-ms-lease-id", lease StorageService.with_header headers, "Origin", options[:origin].to_s if options[:origin] add_blob_conditional_headers options, headers call(:put, uri, nil, headers, options) nil end # Protected: Breaks the lease, if the container or blob has an active lease. Once a lease is broken, it cannot be renewed. Any # authorized request can break the lease; the request is not required to specify a matching lease ID. When a # lease is broken, the lease break period is allowed to elapse, during which time no lease operation except # break and release can be performed on the container or blob. When a lease is successfully broken, the response indicates # the interval in seconds until a new lease can be acquired. # # A lease that has been broken can also be released, in which case another client may immediately acquire the # lease on the container or blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:break_period+ - Integer. The proposed duration of seconds that the lease should continue before it is # broken, between 0 and 60 seconds. This break period is only used if it is shorter than # the time remaining on the lease. If longer, the time remaining on the lease is used. A # new lease will not be available before the break period has expired, but the lease may # be held for longer than the break period. # # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns an Integer of the remaining lease time. This value is the approximate time remaining in the lease # period, in seconds. This header is returned only for a successful request to break the lease. If the break # is immediate, 0 is returned. # protected def break_lease(container, blob, options = {}) query = { "comp" => "lease" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] if blob uri = blob_uri(container, blob, query) else uri = container_uri(container, query) end headers = {} StorageService.with_header headers, "x-ms-lease-action", "break" StorageService.with_header headers, "x-ms-lease-break-period", options[:break_period].to_s if options[:break_period] StorageService.with_header headers, "Origin", options[:origin].to_s if options[:origin] add_blob_conditional_headers options, headers response = call(:put, uri, nil, headers, options) response.headers["x-ms-lease-time"].to_i end # Protected: Generate the URI for the collection of containers. # # ==== Attributes # # * +query+ - A Hash of key => value query parameters. # # Returns a URI. # protected def containers_uri(query = {}, options = {}) query = { "comp" => "list" }.merge(query) generate_uri("", query, options) end # Protected: Generate the URI for the user delegation key. # # ==== Attributes # # * +query+ - A Hash of key => value query parameters. # # Returns a URI. # protected def user_delegation_key_uri(query = {}, options = {}) query = { :restype => "service", :comp => "userdelegationkey" }.merge(query) generate_uri("", query, options) end # Protected: Generate the URI for a specific container. # # ==== Attributes # # * +name+ - The container name. If this is a URI, we just return this. # * +query+ - A Hash of key => value query parameters. # # Returns a URI. # protected def container_uri(name, query = {}, options = {}) return name if name.kind_of? ::URI query = { "restype" => "container" }.merge(query) generate_uri(name, query, options) end # Protected: Generate the URI for a specific Blob. # # ==== Attributes # # * +container_name+ - String representing the name of the container. # * +blob_name+ - String representing the name of the blob. # * +query+ - A Hash of key => value query parameters. # # Returns a URI. # protected def blob_uri(container_name, blob_name, query = {}, options = {}) if container_name.nil? || container_name.empty? path = blob_name else path = ::File.join(container_name, blob_name) end options = { encode: true }.merge(options) generate_uri(path, query, options) end # Adds conditional header with required condition # # headers - A Hash of HTTP headers # options - A Hash of condition name/value pairs # protected def add_blob_conditional_headers(options, headers) return unless options # Common conditional headers for blobs: https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx StorageService.with_header headers, "If-Modified-Since", options[:if_modified_since] StorageService.with_header headers, "If-Unmodified-Since", options[:if_unmodified_since] StorageService.with_header headers, "If-Match", options[:if_match] StorageService.with_header headers, "If-None-Match", options[:if_none_match] # Conditional headers for copying blob StorageService.with_header headers, "If-Modified-Since", options[:dest_if_modified_since] StorageService.with_header headers, "If-Unmodified-Since", options[:dest_if_unmodified_since] StorageService.with_header headers, "If-Match", options[:dest_if_match] StorageService.with_header headers, "If-None-Match", options[:dest_if_none_match] StorageService.with_header headers, "x-ms-source-if-modified-since", options[:source_if_modified_since] StorageService.with_header headers, "x-ms-source-if-unmodified-since", options[:source_if_unmodified_since] StorageService.with_header headers, "x-ms-source-if-match", options[:source_if_match] StorageService.with_header headers, "x-ms-source-if-none-match", options[:source_if_none_match] # Conditional headers for page blob StorageService.with_header headers, "x-ms-if-sequence-number-le", options[:if_sequence_number_le] if options[:if_sequence_number_le] StorageService.with_header headers, "x-ms-if-sequence-number-lt", options[:if_sequence_number_lt] if options[:if_sequence_number_lt] StorageService.with_header headers, "x-ms-if-sequence-number-eq", options[:if_sequence_number_eq] if options[:if_sequence_number_eq] # Conditional headers for append blob StorageService.with_header headers, "x-ms-blob-condition-maxsize", options[:max_size] StorageService.with_header headers, "x-ms-blob-condition-appendpos", options[:append_position] end # Get the content type according to the blob content type header and request body. # # headers - The request body # content_type - The request content type protected def get_or_apply_content_type(body, content_type = nil) unless body.nil? if (body.is_a? String) && body.encoding.to_s != "ASCII_8BIT" && !body.empty? if content_type.nil? content_type = "text/plain; charset=#{body.encoding}" else # Force the request.body to the content encoding of specified in the header charset = parse_charset_from_content_type(content_type) body.force_encoding(charset) if charset end else # It is either that the body is not a string, or that the body's encoding is ASCII_8BIT, which is a binary # In this case, set the content type to be default content-type content_type = Default::CONTENT_TYPE_VALUE unless content_type end end content_type end end end end Azure::Storage::BlobService = Azure::Storage::Blob::BlobService azure-storage-blob-2.0.0/lib/azure/storage/blob/page.rb0000644000177000017700000011742113754103060022001 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- module Azure::Storage module Blob # Public: Creates a new page blob. Note that calling create_page_blob to create a page # blob only initializes the blob. To add content to a page blob, call put_blob_pages method. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +length+ - Integer. Specifies the maximum size for the page blob, up to 1 TB. # The page blob size must be aligned to a 512-byte boundary. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport. # When this header is specified, the storage service checks the hash that has arrived with the one that was sent. # If the two hashes do not match, the operation will fail with error code 400 (Bad Request). # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:sequence_number+ - Integer. The sequence number is a user-controlled value that you can use to track requests. # The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob def create_page_blob(container, blob, length, options = {}) query = {} StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} # set x-ms-blob-type to PageBlob StorageService.with_header headers, "x-ms-blob-type", "PageBlob" # ensure content-length is 0 and x-ms-blob-content-length is the blob length StorageService.with_header headers, "Content-Length", 0.to_s StorageService.with_header headers, "x-ms-blob-content-length", length.to_s # set x-ms-sequence-number from options (or default to 0) StorageService.with_header headers, "x-ms-sequence-number", (options[:sequence_number] || 0).to_s # set the rest of the optional headers StorageService.with_header headers, "Content-MD5", options[:transactional_md5] StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type] StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding] StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language] StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5] StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control] StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition] StorageService.add_metadata_to_headers options[:metadata], headers add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] headers["x-ms-blob-content-type"] = Default::CONTENT_TYPE_VALUE unless headers["x-ms-blob-content-type"] # call PutBlob with empty body response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result.metadata = options[:metadata] if options[:metadata] result end # Public: Creates a range of pages in a page blob. # # ==== Attributes # # * +container+ - String. Name of container # * +blob+ - String. Name of blob # * +start_range+ - Integer. Position of first byte of first page # * +end_range+ - Integer. Position of last byte of of last page # * +content+ - IO or String. Content to write. Length in bytes should equal end_range - start_range + 1 # * +options+ - Hash. A collection of options. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:transactional_md5+ - String. An MD5 hash of the page content. This hash is used to verify the integrity of the page during transport. # When this header is specified, the storage service checks the hash that has arrived with the one that was sent. # * +:if_sequence_number_le+ - Integer. If the blob's sequence number is less than or equal to the specified value, the request proceeds; # otherwise it fails with the SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_sequence_number_lt+ - Integer. If the blob's sequence number is less than the specified value, the request proceeds; # otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_sequence_number_eq+ - Integer. If the blob's sequence number is equal to the specified value, the request proceeds; # otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to write the page only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to write the page only if # the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to write the page only if # the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to write the page only if # the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/ee691975.aspx # # Returns Blob def put_blob_pages(container, blob, start_range, end_range, content, options = {}) query = { "comp" => "page" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} StorageService.with_header headers, "Content-MD5", options[:transactional_md5] StorageService.with_header headers, "x-ms-range", "bytes=#{start_range}-#{end_range}" StorageService.with_header headers, "x-ms-page-write", "update" # clear default content type StorageService.with_header headers, "Content-Type", "" headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] # set optional headers unless options.empty? add_blob_conditional_headers options, headers end response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result end # Public: Clears a range of pages from the blob. # # ==== Attributes # # * +container+ - String. Name of container. # * +blob+ - String. Name of blob. # * +start_range+ - Integer. Position of first byte of first page. # * +end_range+ - Integer. Position of last byte of of last page. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to clear the page only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to clear the page only if # the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to clear the page only if # the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to clear the page only if # the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/ee691975.aspx # # Returns Blob def clear_blob_pages(container, blob, start_range, end_range, options = {}) query = { "comp" => "page" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} StorageService.with_header headers, "x-ms-range", "bytes=#{start_range}-#{end_range}" StorageService.with_header headers, "x-ms-page-write", "clear" # clear default content type StorageService.with_header headers, "Content-Type", "" # set optional headers unless options.empty? add_blob_conditional_headers options, headers end response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result end # Public: Returns a list of active page ranges for a page blob. Active page ranges are # those that have been populated with data. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:start_range+ - Integer. Position of first byte of first page. (optional) # * +:end_range+ - Integer. Position of last byte of of last page. (optional) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to list the pages only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to list the pages only if # the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to list the pages only if # the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to list the pages only if # the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:previous_snapshot+ - String. An opaque DateTime value that specifies that the response will contain only pages that # were changed between target blob and previous snapshot. Changed pages include both updated and # cleared pages. The target blob may be a snapshot, as long as the snapshot specified by this # is the older of the two. # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # If this header is specified and both of these conditions are not met, the request will fail # and the Get Blob operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/ee691973.aspx # # Returns a list of page ranges in the format [ [start, end], [start, end], ... ] # # e.g. [ [0, 511], [512, 1024], ... ] # def list_page_blob_ranges(container, blob, options = {}) query = { "comp" => "pagelist" } query.update("snapshot" => options[:snapshot]) if options[:snapshot] query.update("prevsnapshot" => options[:previous_snapshot]) if options[:previous_snapshot] StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = blob_uri(container, blob, query, options) options[:start_range] = 0 if options[:end_range] && (not options[:start_range]) headers = {} StorageService.with_header headers, "x-ms-range", "bytes=#{options[:start_range]}-#{options[:end_range]}" if options[:start_range] add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] response = call(:get, uri, nil, headers, options) pagelist = Serialization.page_list_from_xml(response.body) pagelist end # Public: Resizes a page blob to the specified size. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +size+ - String. The blob size. Resizes a page blob to the specified size. # If the specified value is less than the current size of the blob, # then all pages above the specified value are cleared. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/ee691966.aspx # # Returns nil on success. def resize_page_blob(container, blob, size, options = {}) options = { content_length: size }.merge(options) set_blob_properties container, blob, options end # Public: Copies a snapshot of the source page blob to a destination page blob. The snapshot is copied such that only # the differential changes between the previously copied snapshot are transferred to the destination. The copied snapshots # are complete copies of the original snapshot and can be read or copied from as usual.The destination of an incremental copy # must either not exist, or must have been created with a previous incremental copy from the same source blob. Once created, # the destination blob is permanently associated with the source and may only be used for incremental copies. The Get Blob # Properties and List Blobs APIs indicate whether the blob is an incremental copy blob created in this way. Incremental # copy blobs may not be downloaded directly. The only supported operations are Get Blob Properties, Incremental Copy Blob, # and Delete Blob. The copied snapshots may be read and deleted as usual. # # ==== Attributes # # * +destination_container+ - String. The destination container name to copy to. # * +destination_blob+ - String. The destination blob name to copy to. # * +source_uri+ - String. Specifies the URI of the source page blob snapshot. # This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The # value should be URL-encoded as it would appear in a request URI. The source blob must # either be public or must be authenticated via a shared access signature. Here is an # example of a source blob URL: # https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot= # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:metadata+ - Hash. Custom metadata values to store with the copy. If this parameter is not # specified, the operation will copy the source blob metadata to the destination # blob. If this parameter is specified, the destination blob is created with the # specified metadata, and metadata is not copied from the source blob. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to copy the blob only if the # destination blob has been modified since the specified date/time. If the destination blob # has not been modified, the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to copy the blob only if the # destination blob has not been modified since the specified date/time. If the destination # blob has been modified, the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to copy the blob # only if the specified ETag value matches the ETag value for an existing destination blob. # If the ETag for the destination blob does not match the ETag specified for If-Match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value, or the wildcard character (*). Specify an ETag value for this # conditional header to copy the blob only if the specified ETag value does not match the # ETag value for the destination blob. Specify the wildcard character (*) to perform the # operation only if the destination blob does not exist. If the specified condition isn't met, # the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # If this header is specified and both of these conditions are not met, the request will fail # and the Snapshot Blob operation will fail with status code 412 (Precondition Failed). # # See https://docs.microsoft.com/en-us/rest/api/storageservices/incremental-copy-blob # # Returns a tuple of (copy_id, copy_status). # # * +copy_id+ - String. String identifier for this copy operation. Use with Get Blob Properties to check # the status of this copy operation, or pass to Abort Copy Blob to abort a pending copy. # * +copy_status+ - String. State of the copy operation. This is always pending to indicate that the copy has # started and is in progress. # def incremental_copy_blob(destination_container, destination_blob, source_uri, options = {}) # query parameters query = { Azure::Storage::Common::QueryStringConstants::COMP => Azure::Storage::Common::QueryStringConstants::INCREMENTAL_COPY } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] # URI uri = blob_uri(destination_container, destination_blob, query) # headers headers = {} StorageService.with_header headers, "x-ms-copy-source", source_uri unless options.empty? add_blob_conditional_headers options, headers StorageService.add_metadata_to_headers options[:metadata], headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end response = call(:put, uri, nil, headers, options) return response.headers["x-ms-copy-id"], response.headers["x-ms-copy-status"] end # Public: Sets a page blob's sequence number. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +action+ - Symbol. Indicates how the service should modify the sequence # number for the blob. Required if :sequence_number is used. This property # applies to page blobs only. # # Specify one of the following options for this property: # # * +:max+ - Sets the sequence number to be the higher of the value included with # the request and the value currently stored for the blob. # * +:update+ - Sets the sequence number to the value included with the request. # * +:increment+ - Increments the value of the sequence number by 1. If specifying this # option, do not include the sequence_number option; doing so will return # status code 400 (Bad Request). # # * +number+ - Integer. Sets the blob's sequence number. The sequence number is a # user-controlled property that you can use to track requests and manage concurrency # issues. Required if the 'action' parameter is set to :max or :update. # This property applies to page blobs only. # # Use this together with the 'action' parameter to update the blob's sequence # number, either to the specified value or to the higher of the values specified with # the request or currently stored with the blob. # # This header should not be specified if the 'action' parameter is set to :increment; # in this case the service automatically increments the sequence number by one. # # To set the sequence number to a value of your choosing, this property must be specified # together with the 'action' parameter # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/ee691966.aspx # # Returns nil on success. def set_sequence_number(container, blob, action, number, options = {}) options = { sequence_number_action: action, sequence_number: number }.merge(options) set_blob_properties container, blob, options end # Public: Creates a new page blob filled with given content. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +length+ - Integer. Specifies the maximum size for the page blob, up to 1 TB. # The page blob size must be aligned to a 512-byte boundary. # * +content+ - String or IO. The content to put in the page blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:sequence_number+ - Integer. The sequence number is a user-controlled value that you can use to track requests. # The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob def create_page_blob_from_content(container, blob, length, content, options = {}) options[:content_type] = get_or_apply_content_type(content, options[:content_type]) create_page_blob(container, blob, length, options) content = StringIO.new(content) if content.is_a? String upload_count = (Float(length) / Float(BlobConstants::DEFAULT_WRITE_PAGE_SIZE_IN_BYTES)).ceil for idx in 0...upload_count start_range = idx * BlobConstants::DEFAULT_WRITE_PAGE_SIZE_IN_BYTES end_range = start_range + BlobConstants::DEFAULT_WRITE_PAGE_SIZE_IN_BYTES - 1 end_range = (length - 1) if end_range > (length - 1) put_blob_pages(container, blob, start_range, end_range, content.read(BlobConstants::DEFAULT_WRITE_PAGE_SIZE_IN_BYTES), lease_id: options[:lease_id]) end get_properties_options = {} get_properties_options[:lease_id] = options[:lease_id] if options[:lease_id] # Get the blob properties get_blob_properties(container, blob, get_properties_options) end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/blob.rb0000644000177000017700000020112613754103060021777 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- module Azure::Storage module Blob include Azure::Storage::Common::Service class Blob def initialize @properties = {} @metadata = {} yield self if block_given? end attr_accessor :name attr_accessor :snapshot attr_accessor :properties attr_accessor :metadata attr_accessor :encrypted end # Public: Reads or downloads a blob from the system, including its metadata and properties. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:start_range+ - Integer. Position of first byte of first page. (optional) # * +:end_range+ - Integer. Position of last byte of of last page. (optional) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. (optional) # * +:get_content_md5+ - Boolean. Return the MD5 hash for the range. This option only valid if # start_range and end_range are specified. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to get the blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # If this header is specified and both of these conditions are not met, the request will fail # and the Get Blob operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd179440.aspx # # Returns a blob and the blob body def get_blob(container, blob, options = {}) query = {} StorageService.with_query query, "snapshot", options[:snapshot] StorageService.with_query query, "timeout", options[:timeout] if options[:timeout] options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = blob_uri(container, blob, query, options) headers = {} options[:start_range] = 0 if options[:end_range] && (not options[:start_range]) if options[:start_range] StorageService.with_header headers, "x-ms-range", "bytes=#{options[:start_range]}-#{options[:end_range]}" StorageService.with_header headers, "x-ms-range-get-content-md5", "true" if options[:get_content_md5] end add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] response = call(:get, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob unless result.name return result, response.body end # Public: Returns all properties and metadata on the blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to get the blob properties # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob properties # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob properties # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # # If this header is specified and both of these conditions are not met, the request will fail # and the Get Blob Properties operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd179394.aspx # # Returns the blob properties with a Blob instance def get_blob_properties(container, blob, options = {}) query = {} StorageService.with_query query, "snapshot", options[:snapshot] StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] headers = {} unless options.empty? add_blob_conditional_headers options, headers end headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = blob_uri(container, blob, query, options) response = call(:head, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result.snapshot = options[:snapshot] result end # Public: Sets system properties defined for a blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:content_length+ - Integer. Resizes a page blob to the specified size. If the specified # value is less than the current size of the blob, then all pages above # the specified value are cleared. This property cannot be used to change # the size of a block blob. Setting this property for a block blob returns # status code 400 (Bad Request). # * +:sequence_number_action+ - Symbol. This property indicates how the service should modify the sequence # number for the blob. Required if :sequence_number is used. This property # applies to page blobs only. # # Specify one of the following options for this property: # # * +:max+ - Sets the sequence number to be the higher of the value included with # the request and the value currently stored for the blob. # * +:update+ - Sets the sequence number to the value included with the request. # * +:increment+ - Increments the value of the sequence number by 1. If specifying this # option, do not include the sequence_number option; doing so will return # status code 400 (Bad Request). # # * +:sequence_number+ - Integer. This property sets the blob's sequence number. The sequence number is a # user-controlled property that you can use to track requests and manage concurrency # issues. Required if the :sequence_number_action option is set to :max or :update. # This property applies to page blobs only. # # Use this together with the :sequence_number_action to update the blob's sequence # number, either to the specified value or to the higher of the values specified with # the request or currently stored with the blob. # # This header should not be specified if :sequence_number_action is set to :increment; # in this case the service automatically increments the sequence number by one. # # To set the sequence number to a value of your choosing, this property must be specified # together with :sequence_number_action # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob properties # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active # lease, specify the valid lease ID for this header. # # Remarks: # # The semantics for updating a blob's properties are as follows: # # * A page blob's sequence number is updated only if the request meets either of the following conditions: # # * The :sequence_number_action property is set to :max or :update, and a value for :sequence_number is also set. # * The :sequence_number_action property is set to :increment, indicating that the service should increment # the sequence number by one. # # * The size of the page blob is modified only if a value for :content_length is specified. # # * If :sequence_number and/or :content_length are the only properties specified, then the other properties of the blob # will NOT be modified. # # * If any one or more of the following properties are set, then all of these properties are set together. If a value is # not provided for a given property when at least one of the properties listed below is set, then that property will be # cleared for the blob. # # * :cache_control # * :content_type # * :content_md5 # * :content_encoding # * :content_language # * :content_disposition # # See http://msdn.microsoft.com/en-us/library/azure/ee691966.aspx # # Returns nil on success. def set_blob_properties(container, blob, options = {}) query = { "comp" => "properties" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} unless options.empty? StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type] StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding] StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language] StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5] StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control] StorageService.with_header headers, "x-ms-blob-content-length", options[:content_length] if options[:content_length] StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition] if options[:sequence_number_action] StorageService.with_header headers, "x-ms-sequence-number-action", options[:sequence_number_action] if options[:sequence_number_action].to_s != "increment" && options[:sequence_number] StorageService.with_header headers, "x-ms-blob-sequence-number", options[:sequence_number] end end add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end call(:put, uri, nil, headers, options) nil end # Public: Returns metadata on the blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob metadata # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to get the blob metadata # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob metadata # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to get the blob metadata # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # # If this header is specified and both of these conditions are not met, the request will fail # and the Get Blob Metadata operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd179350.aspx # # Returns a Blob def get_blob_metadata(container, blob, options = {}) query = { "comp" => "metadata" } StorageService.with_query query, "snapshot", options[:snapshot] StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] headers = {} unless options.empty? add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = blob_uri(container, blob, query, options) response = call(:get, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result.snapshot = options[:snapshot] result end # Public: Sets metadata headers on the blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +metadata+ - Hash. The custom metadata. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob metadata # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to set the blob metadata # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob metadata # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to set the blob metadata # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active # lease, specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179414.aspx # # Returns nil on success. def set_blob_metadata(container, blob, metadata, options = {}) query = { "comp" => "metadata" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} StorageService.add_metadata_to_headers metadata, headers unless options.empty? add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end call(:put, uri, nil, headers, options) nil end # Public: Establishes an exclusive write lock on a blob. The lock duration can be 15 to 60 seconds, or can be infinite. # To write to a locked blob, a client must provide a lease ID. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:duration+ - Integer. Default -1. Specifies the duration of the lease, in seconds, or negative one (-1) # for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. (optional) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request # to write to the blob, or to renew, change, or release the lease. # def acquire_blob_lease(container, blob, options = {}) acquire_lease container, blob, options end # Public: Renews the lease. The lease can be renewed if the lease ID specified on the request matches that # associated with the blob. Note that the lease may be renewed even if it has expired as long as the blob # has not been modified or leased again since the expiration of that lease. When you renew a lease, the # lease duration clock resets. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The lease id # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns the renewed lease id def renew_blob_lease(container, blob, lease, options = {}) renew_lease container, blob, lease, options end # Public: Change the lease ID. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The existing lease id. # * +proposed_lease+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional). # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns the changed lease id def change_blob_lease(container, blob, lease, proposed_lease, options = {}) change_lease container, blob, lease, proposed_lease, options end # Public: Releases the lease. The lease may be released if the lease ID specified on the request matches that # associated with the blob. Releasing the lease allows another client to immediately acquire the lease for # the blob as soon as the release is complete. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +lease+ - String. The lease id. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns nil on success def release_blob_lease(container, blob, lease, options = {}) release_lease container, blob, lease, options end # Public: Breaks the lease, if the blob has an active lease. Once a lease is broken, it cannot be renewed. Any # authorized request can break the lease; the request is not required to specify a matching lease ID. When a # lease is broken, the lease break period is allowed to elapse, during which time no lease operation except # break and release can be performed on the blob. When a lease is successfully broken, the response indicates # the interval in seconds until a new lease can be acquired. # # A lease that has been broken can also be released, in which case another client may immediately acquire the # lease on the blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:break_period+ - Integer. The proposed duration of seconds that the lease should continue before it is # broken, between 0 and 60 seconds. This break period is only used if it is shorter than # the time remaining on the lease. If longer, the time remaining on the lease is used. A # new lease will not be available before the break period has expired, but the lease may # be held for longer than the break period. # # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to break the lease # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to break the lease # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns an Integer of the remaining lease time. This value is the approximate time remaining in the lease # period, in seconds. This header is returned only for a successful request to break the lease. If the break # is immediate, 0 is returned. def break_blob_lease(container, blob, options = {}) break_lease container, blob, options end # Public: Creates a snapshot of a blob. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:metadata+ - Hash. Custom metadata values to store with the blob snapshot. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create the blob snapshot # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create the blob snapshot # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the # following conditions are met: # - The blob's lease is currently active. # - The lease ID specified in the request matches that of the blob. # If this header is specified and both of these conditions are not met, the request will fail # and the Snapshot Blob operation will fail with status code 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/ee691971.aspx # # Returns the snapshot DateTime value def create_blob_snapshot(container, blob, options = {}) query = { "comp" => "snapshot" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} unless options.empty? StorageService.add_metadata_to_headers(options[:metadata], headers) add_blob_conditional_headers(options, headers) headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end response = call(:put, uri, nil, headers, options) response.headers["x-ms-snapshot"] end # Public: Copies a source blob or file to a destination blob. # # ==== Attributes # # * +destination_container+ - String. The destination container name to copy to. # * +destination_blob+ - String. The destination blob name to copy to. # * +source_uri+ - String. The source blob or file URI to copy from. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:source_snapshot+ - String. A snapshot id for the source blob # * +:metadata+ - Hash. Custom metadata values to store with the copy. If this parameter is not # specified, the operation will copy the source blob metadata to the destination # blob. If this parameter is specified, the destination blob is created with the # specified metadata, and metadata is not copied from the source blob. # * +:source_if_modified_since+ - String. A DateTime value. Specify this option to write the page only if the source blob # has been modified since the specified date/time. If the blob has not been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:source_if_unmodified_since+ - String. A DateTime value. Specify this option to write the page only if the source blob # has not been modified since the specified date/time. If the blob has been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:source_if_match+ - String. An ETag value. Specify an ETag value to write the page only if the source blob's # ETag value matches the value specified. If the values do not match, the Blob # service returns status code 412 (Precondition Failed). # * +:source_if_none_match+ - String. An ETag value. Specify an ETag value to write the page only if the source blob's # ETag value does not match the value specified. If the values are identical, the # Blob service returns status code 412 (Precondition Failed). # * +:dest_if_modified_since+ - String. A DateTime value. Specify this option to write the page only if the destination # blob has been modified since the specified date/time. If the blob has not been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:dest_if_unmodified_since+ - String. A DateTime value. Specify this option to write the page only if the destination # blob has not been modified since the specified date/time. If the blob has been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:dest_if_match+ - String. An ETag value. Specify an ETag value to write the page only if the destination # blob's ETag value matches the value specified. If the values do not match, the # Blob service returns status code 412 (Precondition Failed). # * +:dest_if_none_match+ - String. An ETag value. Specify an ETag value to write the page only if the destination # blob's ETag value does not match the value specified. If the values are # identical, the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the destination blob has an active lease. The lease ID specified for # this header must match the lease ID of the destination blob. If the request does not include # the lease ID or it is not valid, the operation fails with status code 412 (Precondition Failed). # If this header is specified and the destination blob does not currently have an active lease, # the operation will also fail with status code 412 (Precondition Failed). # In version 2012-02-12 and newer, this value must specify an active, infinite lease for a # leased blob. A finite-duration lease ID fails with 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd894037.aspx # # Returns a tuple of (copy_id, copy_status). # # * +copy_id+ - String identifier for this copy operation. Use with get_blob or get_blob_properties to check # the status of this copy operation, or pass to abort_copy_blob to abort a pending copy. # * +copy_status+ - String. The state of the copy operation, with these values: # "success" - The copy completed successfully. # "pending" - The copy is in progress. # def copy_blob_from_uri(destination_container, destination_blob, source_uri, options = {}) query = {} StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(destination_container, destination_blob, query) headers = {} StorageService.with_header headers, "x-ms-copy-source", source_uri unless options.empty? add_blob_conditional_headers options, headers StorageService.add_metadata_to_headers options[:metadata], headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] end response = call(:put, uri, nil, headers, options) return response.headers["x-ms-copy-id"], response.headers["x-ms-copy-status"] end # Public: Copies a source blob to a destination blob within the same storage account. # # ==== Attributes # # * +destination_container+ - String. The destination container name to copy to. # * +destination_blob+ - String. The destination blob name to copy to. # * +source_container+ - String. The source container name to copy from. # * +source_blob+ - String. The source blob name to copy from. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:source_snapshot+ - String. A snapshot id for the source blob # * +:metadata+ - Hash. Custom metadata values to store with the copy. If this parameter is not # specified, the operation will copy the source blob metadata to the destination # blob. If this parameter is specified, the destination blob is created with the # specified metadata, and metadata is not copied from the source blob. # * +:source_if_modified_since+ - String. A DateTime value. Specify this option to write the page only if the source blob # has been modified since the specified date/time. If the blob has not been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:source_if_unmodified_since+ - String. A DateTime value. Specify this option to write the page only if the source blob # has not been modified since the specified date/time. If the blob has been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:source_if_match+ - String. An ETag value. Specify an ETag value to write the page only if the source blob's # ETag value matches the value specified. If the values do not match, the Blob # service returns status code 412 (Precondition Failed). # * +:source_if_none_match+ - String. An ETag value. Specify an ETag value to write the page only if the source blob's # ETag value does not match the value specified. If the values are identical, the # Blob service returns status code 412 (Precondition Failed). # * +:dest_if_modified_since+ - String. A DateTime value. Specify this option to write the page only if the destination # blob has been modified since the specified date/time. If the blob has not been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:dest_if_unmodified_since+ - String. A DateTime value. Specify this option to write the page only if the destination # blob has not been modified since the specified date/time. If the blob has been # modified, the Blob service returns status code 412 (Precondition Failed). # * +:dest_if_match+ - String. An ETag value. Specify an ETag value to write the page only if the destination # blob's ETag value matches the value specified. If the values do not match, the # Blob service returns status code 412 (Precondition Failed). # * +:dest_if_none_match+ - String. An ETag value. Specify an ETag value to write the page only if the destination # blob's ETag value does not match the value specified. If the values are # identical, the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required if the destination blob has an active lease. The lease ID specified for # this header must match the lease ID of the destination blob. If the request does not include # the lease ID or it is not valid, the operation fails with status code 412 (Precondition Failed). # If this header is specified and the destination blob does not currently have an active lease, # the operation will also fail with status code 412 (Precondition Failed). # In version 2012-02-12 and newer, this value must specify an active, infinite lease for a # leased blob. A finite-duration lease ID fails with 412 (Precondition Failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd894037.aspx # # Returns a tuple of (copy_id, copy_status). # # * +copy_id+ - String identifier for this copy operation. Use with get_blob or get_blob_properties to check # the status of this copy operation, or pass to abort_copy_blob to abort a pending copy. # * +copy_status+ - String. The state of the copy operation, with these values: # "success" - The copy completed successfully. # "pending" - The copy is in progress. # def copy_blob(destination_container, destination_blob, source_container, source_blob, options = {}) source_blob_uri = blob_uri(source_container, source_blob, options[:source_snapshot] ? { "snapshot" => options[:source_snapshot] } : {}).to_s return copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, options) end # Public: Aborts a pending Copy Blob operation and leaves a destination blob with zero length and full metadata. # # ==== Attributes # # * +container+ - String. The destination container name. # * +blob+ - String. The destination blob name. # * +copy_id+ - String. The copy identifier returned in the copy blob operation. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:lease_id+ - String. The lease id if the destination blob has an active infinite lease # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # # See https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx # # Returns nil on success def abort_copy_blob(container, blob, copy_id, options = {}) query = { "comp" => "copy" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] StorageService.with_query query, "copyid", copy_id uri = blob_uri(container, blob, query); headers = {} StorageService.with_header headers, "x-ms-copy-action", "abort"; unless options.empty? StorageService.with_header headers, "x-ms-lease-id", options[:lease_id] end call(:put, uri, nil, headers, options) nil end # Public: Deletes a blob or blob snapshot. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. (optional) # * +:delete_snapshots+ - Symbol. Used to specify the scope of the delete operation for snapshots. # This parameter is ignored if a blob does not have snapshots, or if a # snapshot is specified in the snapshot parameter. (optional) # # Possible values include: # * +:only+ - Deletes only the snapshots for the blob, but leaves the blob # * +:include+ - Deletes the blob and all of the snapshots for the blob # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create the blob snapshot # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create the blob snapshot # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an # active lease, specify the valid lease ID for this header. If a valid lease ID is not specified # on the request, the operation will fail with status code 403 (Forbidden). # # See http://msdn.microsoft.com/en-us/library/azure/dd179440.aspx # # Returns nil on success def delete_blob(container, blob, options = {}) query = {} StorageService.with_query query, "snapshot", options[:snapshot] StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) options[:delete_snapshots] = :include unless options[:delete_snapshots] headers = {} StorageService.with_header headers, "x-ms-delete-snapshots", options[:delete_snapshots].to_s if options[:delete_snapshots] && options[:snapshot] == nil add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] call(:delete, uri, nil, headers, options) nil end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/append.rb0000644000177000017700000003714513754103060022340 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- module Azure::Storage module Blob # Public: Creates a new append blob. Note that calling create_append_blob to create an append # blob only initializes the blob. To add content to an append blob, call append_blob_blocks method. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob def create_append_blob(container, blob, options = {}) query = {} StorageService.with_query query, "timeout", options[:timeout] if options[:timeout] uri = blob_uri(container, blob, query) headers = {} # set x-ms-blob-type to AppendBlob StorageService.with_header headers, "x-ms-blob-type", "AppendBlob" # ensure content-length is 0 StorageService.with_header headers, "Content-Length", 0 # set the rest of the optional headers StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type] StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding] StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language] StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5] StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control] StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition] StorageService.add_metadata_to_headers options[:metadata], headers add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] headers["x-ms-blob-content-type"] = Default::CONTENT_TYPE_VALUE unless headers["x-ms-blob-content-type"] # call PutBlob with empty body response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result.metadata = options[:metadata] if options[:metadata] result end # Public: Commits a new block of data to the end of an existing append blob. # This operation is permitted only on blobs created with the create_append_blob API. # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. The content of the blob. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_md5+ - String. Content MD5 for the request contents. # * +:max_size+ - Integer. The max length in bytes permitted for the append blob # * +:append_position+ - Integer. A number indicating the byte offset to compare. It will succeed only if the append position is equal to this number # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to append a block only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to append a block only if # the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to append a block only if # the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to append a block only if # the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an # active lease, specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/mt427365.aspx # # Returns a Blob def append_blob_block(container, blob, content, options = {}) query = { "comp" => "appendblock" } StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) headers = {} StorageService.with_header headers, "Content-MD5", options[:content_md5] StorageService.with_header headers, "x-ms-lease-id", options[:lease_id] StorageService.with_header headers, "x-ms-blob-condition-maxsize", options[:max_size] StorageService.with_header headers, "x-ms-blob-condition-appendpos", options[:append_position] add_blob_conditional_headers options, headers headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob result end # Public: Creates a new append blob with given content # # ==== Attributes # # * +container+ - String. The container name. # * +blob+ - String. The blob name. # * +content+ - IO or String. Content to write. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:content_type+ - String. Content type for the blob. Will be saved with blob. # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob. # * +:content_language+ - String. Content language for the blob. Will be saved with blob. # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob. # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob. # * +:content_disposition+ - String. Conveys additional information about how to process the response payload, # and also can be used to attach additional metadata # * +:max_size+ - Integer. The max length in bytes permitted for the append blob. # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has not been modified since the specified date/time. If the blob has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob # only if the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease, # specify the valid lease ID for this header. # # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx # # Returns a Blob def create_append_blob_from_content(container, blob, content, options = {}) # Fail fast if content has larger size than max_size max_size = options.delete :max_size if max_size if content.respond_to?(:size) && max_size < content.size raise Azure::Storage::Common::Core::StorageError.new("Given content has exceeded the specified maximum size for the blob.") end end options[:content_type] = get_or_apply_content_type(content, options[:content_type]) create_append_blob(container, blob, options) content = StringIO.new(content) if content.is_a? String # initialize the append block options. append_block_options = {} append_block_options[:if_modified_since] = options[:if_modified_since] if options[:if_modified_since] append_block_options[:if_unmodified_since] = options[:if_unmodified_since] if options[:if_unmodified_since] append_block_options[:if_match] = options[:if_match] if options[:if_match] append_block_options[:if_none_match] = options[:if_none_match] if options[:if_none_match] append_block_options[:lease_id] = options[:lease_id] if options[:lease_id] append_block_options[:max_size] = max_size if max_size position = 0 while !content.eof? payload = content.read(BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES) # set the append position to make sure that each append is going to the correct offset. append_block_options[:append_position] = position append_blob_block(container, blob, payload, append_block_options) # calculate the position after the append. position += payload.size end get_properties_options = {} get_properties_options[:lease_id] = options[:lease_id] if options[:lease_id] # Get the blob properties get_blob_properties(container, blob, get_properties_options) end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/version.rb0000644000177000017700000000354513754103060022553 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- module Azure module Storage module Blob class Version # Fields represent the parts defined in http://semver.org/ MAJOR = 2 unless defined? MAJOR MINOR = 0 unless defined? MINOR UPDATE = 0 unless defined? UPDATE class << self # @return [String] def to_s [MAJOR, MINOR, UPDATE].compact.join(".") end def to_uas [MAJOR, MINOR, UPDATE].join(".") end end end end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/container.rb0000644000177000017700000011067113754103060023047 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- module Azure::Storage::Blob module Container include Azure::Storage::Common::Service class Container def initialize @properties = {} @metadata = {} yield self if block_given? end attr_accessor :name attr_accessor :properties attr_accessor :metadata attr_accessor :public_access_level end # Public: Create a new container # # ==== Attributes # # * +name+ - String. The name of the container. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:metadata+ - Hash. User defined metadata for the container (optional). # * +:public_access_level+ - String. One of "container" or "blob" (optional). # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179468.aspx # # Returns a Container def create_container(name, options = {}) # Query query = {} query["timeout"] = options[:timeout].to_s if options[:timeout] # Scheme + path uri = container_uri(name, query) # Headers headers = {} StorageService.add_metadata_to_headers(options[:metadata], headers) if options[:metadata] headers["x-ms-blob-public-access"] = options[:public_access_level].to_s if options[:public_access_level] # Call response = call(:put, uri, nil, headers, options) # result container = Serialization.container_from_headers(response.headers) container.name = name container.metadata = options[:metadata] container end # Public: Returns all properties and metadata on the container. # # ==== Attributes # # * +name+ - String. The name of the container # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:lease_id+ - String. If specified, Get Container Properties only succeeds if the container’s lease is # active and matches this ID. If there is no active lease or the ID does not match, 412 # (Precondition Failed) is returned. # # See http://msdn.microsoft.com/en-us/library/azure/dd179370.aspx # # Returns a Container def get_container_properties(name, options = {}) # Query query = {} query["timeout"] = options[:timeout].to_s if options[:timeout] headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {} # Call options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY response = call(:get, container_uri(name, query, options), nil, headers, options) # result container = Serialization.container_from_headers(response.headers) container.name = name container end # Public: Returns only user-defined metadata for the specified container. # # ==== Attributes # # * +name+ - String. The name of the container # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:lease_id+ - String. If specified, Get Container Metadata only succeeds if the container’s lease is # active and matches this ID. If there is no active lease or the ID does not match, 412 # (Precondition Failed) is returned. # # See http://msdn.microsoft.com/en-us/library/azure/ee691976.aspx # # Returns a Container def get_container_metadata(name, options = {}) # Query query = { "comp" => "metadata" } query["timeout"] = options[:timeout].to_s if options[:timeout] headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {} # Call options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY response = call(:get, container_uri(name, query, options), nil, headers, options) # result container = Serialization.container_from_headers(response.headers) container.name = name container end # Public: Sets custom metadata for the container. # # ==== Attributes # # * +name+ - String. The name of the container # * +metadata+ - Hash. A Hash of the metadata values # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. If specified, Set Container Metadata only succeeds if the container’s lease is # active and matches this ID. If there is no active lease or the ID does not match, 412 # (Precondition Failed) is returned. # # See http://msdn.microsoft.com/en-us/library/azure/dd179362.aspx # # Returns nil on success def set_container_metadata(name, metadata, options = {}) # Query query = { "comp" => "metadata" } query["timeout"] = options[:timeout].to_s if options[:timeout] # Headers headers = {} StorageService.add_metadata_to_headers(metadata, headers) if metadata headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] # Call call(:put, container_uri(name, query), nil, headers, options) # Result nil end # Public: Gets the access control list (ACL) and any container-level access policies # for the container. # # ==== Attributes # # * +name+ - String. The name of the container # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # * +:lease_id+ - String. If specified, Get Container ACL only succeeds if the container’s lease is # active and matches this ID. If there is no active lease or the ID does not match, 412 # (Precondition Failed) is returned. # # See http://msdn.microsoft.com/en-us/library/azure/dd179469.aspx # # Returns a tuple of (container, signed_identifiers) # container - A Azure::Storage::Entity::Blob::Container instance # signed_identifiers - A list of Azure::Storage::Entity::SignedIdentifier instances # def get_container_acl(name, options = {}) # Query query = { "comp" => "acl" } query["timeout"] = options[:timeout].to_s if options[:timeout] headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {} # Call options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY response = call(:get, container_uri(name, query, options), nil, headers, options) # Result container = Serialization.container_from_headers(response.headers) container.name = name signed_identifiers = nil signed_identifiers = Serialization.signed_identifiers_from_xml(response.body) if response.body != nil && response.body.length > 0 return container, signed_identifiers end # Public: Sets the ACL and any container-level access policies for the container. # # ==== Attributes # # * +name+ - String. The name of the container # * +public_access_level+ - String. The container public access level # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. If specified, Set Container ACL only succeeds if the container’s lease is # active and matches this ID. If there is no active lease or the ID does not match, 412 # (Precondition Failed) is returned. # # See http://msdn.microsoft.com/en-us/library/azure/dd179391.aspx # # Returns a tuple of (container, signed_identifiers) # * +container+ - A Azure::Storage::Entity::Blob::Container instance # * +signed_identifiers+ - A list of Azure::Storage::Entity::SignedIdentifier instances # def set_container_acl(name, public_access_level, options = {}) # Query query = { "comp" => "acl" } query["timeout"] = options[:timeout].to_s if options[:timeout] # Scheme + path uri = container_uri(name, query) # Headers + body headers = {} headers["x-ms-blob-public-access"] = public_access_level if public_access_level && public_access_level.to_s.length > 0 headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id] signed_identifiers = nil signed_identifiers = options[:signed_identifiers] if options[:signed_identifiers] body = nil body = Serialization.signed_identifiers_to_xml(signed_identifiers) if signed_identifiers # Call response = call(:put, uri, body, headers, options) # Result container = Serialization.container_from_headers(response.headers) container.name = name container.public_access_level = public_access_level return container, signed_identifiers || [] end # Public: Deletes a container. # # ==== Attributes # # * +name+ - String. The name of the container. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:lease_id+ - String. Required for version 2012-02-12 and newer if the container has an active lease. To call # Delete Container on a container that has an active lease, specify the lease ID in this header. # If this header is not specified when there is an active lease, Delete Container will return 409 # (Conflict). If you specify the wrong lease ID, or a lease ID on a container that does not have # an active lease, Delete Container will return 412 (Precondition failed). # # See http://msdn.microsoft.com/en-us/library/azure/dd179408.aspx # # Returns nil on success def delete_container(name, options = {}) # Query query = {} query["timeout"] = options[:timeout].to_s if options[:timeout] headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {} # Call call(:delete, container_uri(name, query), nil, headers, options) # result nil end # Public: Establishes an exclusive write lock on a container. The lock duration can be 15 to 60 seconds, or can be infinite. # To write to a locked container, a client must provide a lease ID. # # ==== Attributes # # * +container+ - String. The container name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:duration+ - Integer. Default -1. Specifies the duration of the lease, in seconds, or negative one (-1) # for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. (optional) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the container has not been modified since the specified date/time. If the container has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the container's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease # only if the container's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request # to write, or to renew, change, or release the lease. # def acquire_container_lease(container, options = {}) acquire_lease container, nil, options end # Public: Renews the lease. The lease can be renewed if the lease ID specified on the request matches that # associated with the container. Note that the lease may be renewed even if it has expired as long as the container # has not been modified or leased again since the expiration of that lease. When you renew a lease, the # lease duration clock resets. # # ==== Attributes # # * +container+ - String. The container name. # * +lease+ - String. The lease id # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the container has not been modified since the specified date/time. If the container has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the container's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease # only if the container's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns the renewed lease id def renew_container_lease(container, lease, options = {}) renew_lease container, nil, lease, options end # Public: Change the lease ID. # # ==== Attributes # # * +container+ - String. The container name. # * +lease+ - String. The existing lease id. # * +proposed_lease+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional). # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the container has not been modified since the specified date/time. If the container has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the container's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease # only if the container's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns the changed lease id def change_container_lease(container, lease, proposed_lease, options = {}) change_lease container, nil, lease, proposed_lease, options end # Public: Releases the lease. The lease may be released if the lease ID specified on the request matches that # associated with the container. Releasing the lease allows another client to immediately acquire the lease for # the container as soon as the release is complete. # # ==== Attributes # # * +container+ - String. The container name. # * +lease+ - String. The lease id. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the container has not been modified since the specified date/time. If the container has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the container's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease # only if the container's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns nil on success def release_container_lease(container, lease, options = {}) release_lease container, nil, lease, options end # Public: Breaks the lease, if the container has an active lease. Once a lease is broken, it cannot be renewed. Any # authorized request can break the lease; the request is not required to specify a matching lease ID. When a # lease is broken, the lease break period is allowed to elapse, during which time no lease operation except # break and release can be performed on the container. When a lease is successfully broken, the response indicates # the interval in seconds until a new lease can be acquired. # # A lease that has been broken can also be released, in which case another client may immediately acquire the # lease on the container. # # ==== Attributes # # * +container+ - String. The container name. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:break_period+ - Integer. The proposed duration of seconds that the lease should continue before it is # broken, between 0 and 60 seconds. This break period is only used if it is shorter than # the time remaining on the lease. If longer, the time remaining on the lease is used. A # new lease will not be available before the break period has expired, but the lease may # be held for longer than the break period. # # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the container has not been modified since the specified date/time. If the container has been modified, # the Blob service returns status code 412 (Precondition Failed). # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to break the lease # only if the container's ETag value matches the value specified. If the values do not match, # the Blob service returns status code 412 (Precondition Failed). # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to break the lease # only if the container's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:origin+ - String. Optional. Specifies the origin from which the request is issued. The presence of this header results # in cross-origin resource sharing headers on the response. # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx # # Returns an Integer of the remaining lease time. This value is the approximate time remaining in the lease # period, in seconds. This header is returned only for a successful request to break the lease. If the break # is immediate, 0 is returned. def break_container_lease(container, options = {}) break_lease container, nil, options end # Public: Get a list of Blobs from the server # # ==== Attributes # # * +name+ - String. The name of the container to list blobs for. # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # * +:prefix+ - String. Filters the results to return only blobs # whose name begins with the specified prefix. (optional) # * +:delimiter+ - String. When the request includes this parameter, the operation # returns a BlobPrefix element in the response body that acts as a # placeholder for all blobs whose names begin with the same substring # up to the appearance of the delimiter character. The delimiter may # be a single character or a string. # * +:marker+ - String. An identifier that specifies the portion of the # list to be returned. This value comes from the property # Azure::Storage::Common::EnumerationResults.continuation_token when # there are more blobs available than were returned. The # marker value may then be used here to request the next set # of list items. (optional) # * +:max_results+ - Integer. Specifies the maximum number of blobs to return. # If max_results is not specified, or is a value greater than # 5,000, the server will return up to 5,000 items. If it is set # to a value less than or equal to zero, the server will return # status code 400 (Bad Request). (optional) # * +:metadata+ - Boolean. Specifies whether or not to return the blob metadata. # (optional, Default=false) # * +:snapshots+ - Boolean. Specifies that snapshots should be included in the # enumeration. Snapshots are listed from oldest to newest in the # response. (optional, Default=false) # * +:uncomittedblobs+ - Boolean. Specifies that blobs for which blocks have been uploaded, # but which have not been committed using put_block_list, be included # in the response. (optional, Default=false) # * +:copy+ - Boolean. Specifies that metadata related to any current or previous # copy_blob operation should be included in the response. # (optional, Default=false) # * +:timeout+ - Integer. A timeout in seconds. # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded # in the analytics logs when storage analytics logging is enabled. # * +:location_mode+ - LocationMode. Specifies the location mode used to decide # which location the request should be sent to. # # NOTE: Metadata requested with the :metadata parameter must have been stored in # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob # service. Beginning with that version, all metadata names must adhere to the naming # conventions for C# identifiers. # # See: http://msdn.microsoft.com/en-us/library/azure/dd135734.aspx # # Any metadata with invalid names which were previously stored, will be returned with the # key "x-ms-invalid-name" in the metadata hash. This may contain multiple values and be an # Array (vs a String if it only contains a single value). # # Returns an Azure::Storage::Common::EnumerationResults def list_blobs(name, options = {}) # Query query = { "comp" => "list" } query["prefix"] = options[:prefix].gsub(/\\/, "/") if options[:prefix] query["delimiter"] = options[:delimiter] if options[:delimiter] query["marker"] = options[:marker] if options[:marker] query["maxresults"] = options[:max_results].to_s if options[:max_results] query["timeout"] = options[:timeout].to_s if options[:timeout] included_datasets = [] included_datasets.push("metadata") if options[:metadata] == true included_datasets.push("snapshots") if options[:snapshots] == true included_datasets.push("uncommittedblobs") if options[:uncommittedblobs] == true included_datasets.push("copy") if options[:copy] == true query["include"] = included_datasets.join "," if included_datasets.length > 0 # Scheme + path options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY uri = container_uri(name, query, options) # Call response = call(:get, uri, nil, {}, options) # Result if response.success? Serialization.blob_enumeration_results_from_xml(response.body) else response.exception end end end end azure-storage-blob-2.0.0/lib/azure/storage/blob/autoload.rb0000644000177000017700000000403113754103060022665 0ustar avronavron# frozen_string_literal: true #------------------------------------------------------------------------- # # Copyright (c) Microsoft and contributors. All rights reserved. # # The MIT License(MIT) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files(the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions : # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-------------------------------------------------------------------------- require "rubygems" require "nokogiri" require "base64" require "azure/storage/common" module Azure module Storage module Blob autoload :Default, "azure/storage/blob/default" autoload :Version, "azure/storage/blob/version" autoload :Blob, "azure/storage/blob/blob" autoload :Block, "azure/storage/blob/block" autoload :Page, "azure/storage/blob/page" autoload :Append, "azure/storage/blob/append" autoload :Container, "azure/storage/blob/container" autoload :Serialization, "azure/storage/blob/serialization" autoload :BlobService, "azure/storage/blob/blob_service" end end end