1package azblob 2 3import ( 4 "context" 5 "io" 6 "net/url" 7 8 "github.com/Azure/azure-pipeline-go/pipeline" 9) 10 11const ( 12 // BlockBlobMaxUploadBlobBytes indicates the maximum number of bytes that can be sent in a call to Upload. 13 BlockBlobMaxUploadBlobBytes = 256 * 1024 * 1024 // 256MB 14 15 // BlockBlobMaxStageBlockBytes indicates the maximum number of bytes that can be sent in a call to StageBlock. 16 BlockBlobMaxStageBlockBytes = 4000 * 1024 * 1024 // 4000MiB 17 18 // BlockBlobMaxBlocks indicates the maximum number of blocks allowed in a block blob. 19 BlockBlobMaxBlocks = 50000 20) 21 22// BlockBlobURL defines a set of operations applicable to block blobs. 23type BlockBlobURL struct { 24 BlobURL 25 bbClient blockBlobClient 26} 27 28// NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline. 29func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL { 30 blobClient := newBlobClient(url, p) 31 bbClient := newBlockBlobClient(url, p) 32 return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient} 33} 34 35// WithPipeline creates a new BlockBlobURL object identical to the source but with the specific request policy pipeline. 36func (bb BlockBlobURL) WithPipeline(p pipeline.Pipeline) BlockBlobURL { 37 return NewBlockBlobURL(bb.blobClient.URL(), p) 38} 39 40// WithSnapshot creates a new BlockBlobURL object identical to the source but with the specified snapshot timestamp. 41// Pass "" to remove the snapshot returning a URL to the base blob. 42func (bb BlockBlobURL) WithSnapshot(snapshot string) BlockBlobURL { 43 p := NewBlobURLParts(bb.URL()) 44 p.Snapshot = snapshot 45 return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline()) 46} 47 48// WithVersionID creates a new BlockBlobURRL object identical to the source but with the specified version id. 49// Pass "" to remove the snapshot returning a URL to the base blob. 50func (bb BlockBlobURL) WithVersionID(versionId string) BlockBlobURL { 51 p := NewBlobURLParts(bb.URL()) 52 p.VersionID = versionId 53 return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline()) 54} 55 56func (bb BlockBlobURL) GetAccountInfo(ctx context.Context) (*BlobGetAccountInfoResponse, error) { 57 return bb.blobClient.GetAccountInfo(ctx) 58} 59 60// Upload creates a new block blob or overwrites an existing block blob. 61// Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not 62// supported with Upload; the content of the existing blob is overwritten with the new content. To 63// perform a partial update of a block blob, use StageBlock and CommitBlockList. 64// This method panics if the stream is not at position 0. 65// Note that the http client closes the body stream after the request is sent to the service. 66// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob. 67func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions, tier AccessTierType, blobTagsMap BlobTagsMap, cpk ClientProvidedKeyOptions) (*BlockBlobUploadResponse, error) { 68 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 69 count, err := validateSeekableStreamAt0AndGetCount(body) 70 blobTagsString := SerializeBlobTagsHeader(blobTagsMap) 71 if err != nil { 72 return nil, err 73 } 74 return bb.bbClient.Upload(ctx, body, count, nil, nil, 75 &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, 76 &h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition, 77 cpk.EncryptionKey, cpk.EncryptionKeySha256, cpk.EncryptionAlgorithm, // CPK-V 78 cpk.EncryptionScope, // CPK-N 79 tier, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, 80 nil, // Blob ifTags 81 nil, 82 blobTagsString, // Blob tags 83 ) 84} 85 86// StageBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to CommitBlockList. 87// Note that the http client closes the body stream after the request is sent to the service. 88// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block. 89func (bb BlockBlobURL) StageBlock(ctx context.Context, base64BlockID string, body io.ReadSeeker, ac LeaseAccessConditions, transactionalMD5 []byte, cpk ClientProvidedKeyOptions) (*BlockBlobStageBlockResponse, error) { 90 count, err := validateSeekableStreamAt0AndGetCount(body) 91 if err != nil { 92 return nil, err 93 } 94 return bb.bbClient.StageBlock(ctx, base64BlockID, count, body, transactionalMD5, nil, nil, ac.pointers(), 95 cpk.EncryptionKey, cpk.EncryptionKeySha256, cpk.EncryptionAlgorithm, // CPK-V 96 cpk.EncryptionScope, // CPK-N 97 nil) 98} 99 100// StageBlockFromURL copies the specified block from a source URL to the block blob's "staging area" to be later committed by a call to CommitBlockList. 101// If count is CountToEnd (0), then data is read from specified offset to the end. 102// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-from-url. 103func (bb BlockBlobURL) StageBlockFromURL(ctx context.Context, base64BlockID string, sourceURL url.URL, offset int64, count int64, destinationAccessConditions LeaseAccessConditions, sourceAccessConditions ModifiedAccessConditions, cpk ClientProvidedKeyOptions) (*BlockBlobStageBlockFromURLResponse, error) { 104 sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag := sourceAccessConditions.pointers() 105 return bb.bbClient.StageBlockFromURL(ctx, base64BlockID, 0, sourceURL.String(), httpRange{offset: offset, count: count}.pointers(), nil, nil, nil, 106 cpk.EncryptionKey, cpk.EncryptionKeySha256, cpk.EncryptionAlgorithm, // CPK 107 cpk.EncryptionScope, // CPK-N 108 destinationAccessConditions.pointers(), sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatchETag, sourceIfNoneMatchETag, nil) 109} 110 111// CommitBlockList writes a blob by specifying the list of block IDs that make up the blob. 112// In order to be written as part of a blob, a block must have been successfully written 113// to the server in a prior PutBlock operation. You can call PutBlockList to update a blob 114// by uploading only those blocks that have changed, then committing the new and existing 115// blocks together. Any blocks not specified in the block list and permanently deleted. 116// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block-list. 117func (bb BlockBlobURL) CommitBlockList(ctx context.Context, base64BlockIDs []string, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions, tier AccessTierType, blobTagsMap BlobTagsMap, cpk ClientProvidedKeyOptions) (*BlockBlobCommitBlockListResponse, error) { 118 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 119 blobTagsString := SerializeBlobTagsHeader(blobTagsMap) 120 return bb.bbClient.CommitBlockList(ctx, BlockLookupList{Latest: base64BlockIDs}, nil, 121 &h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, nil, nil, 122 metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition, 123 cpk.EncryptionKey, cpk.EncryptionKeySha256, cpk.EncryptionAlgorithm, // CPK 124 cpk.EncryptionScope, // CPK-N 125 tier, 126 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, 127 nil, // Blob ifTags 128 nil, 129 blobTagsString, // Blob tags 130 ) 131} 132 133// GetBlockList returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter. 134// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-block-list. 135func (bb BlockBlobURL) GetBlockList(ctx context.Context, listType BlockListType, ac LeaseAccessConditions) (*BlockList, error) { 136 return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(), 137 nil, // Blob ifTags 138 nil) 139} 140 141// CopyFromURL synchronously copies the data at the source URL to a block blob, with sizes up to 256 MB. 142// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url. 143func (bb BlockBlobURL) CopyFromURL(ctx context.Context, source url.URL, metadata Metadata, srcac ModifiedAccessConditions, dstac BlobAccessConditions, srcContentMD5 []byte, tier AccessTierType, blobTagsMap BlobTagsMap) (*BlobCopyFromURLResponse, error) { 144 145 srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.pointers() 146 dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.ModifiedAccessConditions.pointers() 147 dstLeaseID := dstac.LeaseAccessConditions.pointers() 148 blobTagsString := SerializeBlobTagsHeader(blobTagsMap) 149 return bb.blobClient.CopyFromURL(ctx, source.String(), nil, metadata, tier, 150 srcIfModifiedSince, srcIfUnmodifiedSince, 151 srcIfMatchETag, srcIfNoneMatchETag, 152 dstIfModifiedSince, dstIfUnmodifiedSince, 153 dstIfMatchETag, dstIfNoneMatchETag, 154 nil, // Blob ifTags 155 dstLeaseID, nil, srcContentMD5, 156 blobTagsString, // Blob tags 157 ) 158} 159 160// PutBlobFromURL synchronously creates a new Block Blob with data from the source URL up to a max length of 256MB. 161// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob-from-url. 162func (bb BlockBlobURL) PutBlobFromURL(ctx context.Context, h BlobHTTPHeaders, source url.URL, metadata Metadata, srcac ModifiedAccessConditions, dstac BlobAccessConditions, srcContentMD5 []byte, dstContentMD5 []byte, tier AccessTierType, blobTagsMap BlobTagsMap, cpk ClientProvidedKeyOptions) (*BlockBlobPutBlobFromURLResponse, error) { 163 164 srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.pointers() 165 dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.ModifiedAccessConditions.pointers() 166 dstLeaseID := dstac.LeaseAccessConditions.pointers() 167 blobTagsString := SerializeBlobTagsHeader(blobTagsMap) 168 169 return bb.bbClient.PutBlobFromURL(ctx, 0, source.String(), nil, nil, 170 &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, dstContentMD5, &h.CacheControl, 171 metadata, dstLeaseID, &h.ContentDisposition, cpk.EncryptionKey, cpk.EncryptionKeySha256, 172 cpk.EncryptionAlgorithm, cpk.EncryptionScope, tier, dstIfModifiedSince, dstIfUnmodifiedSince, 173 dstIfMatchETag, dstIfNoneMatchETag, nil, srcIfModifiedSince, srcIfUnmodifiedSince, 174 srcIfMatchETag, srcIfNoneMatchETag, nil, nil, srcContentMD5, blobTagsString, nil) 175} 176