1package azblob 2 3import ( 4 "context" 5 "net/url" 6 7 "github.com/Azure/azure-pipeline-go/pipeline" 8) 9 10// A BlobURL represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. 11type BlobURL struct { 12 blobClient blobClient 13} 14 15// NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline. 16func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL { 17 blobClient := newBlobClient(url, p) 18 return BlobURL{blobClient: blobClient} 19} 20 21// URL returns the URL endpoint used by the BlobURL object. 22func (b BlobURL) URL() url.URL { 23 return b.blobClient.URL() 24} 25 26// String returns the URL as a string. 27func (b BlobURL) String() string { 28 u := b.URL() 29 return u.String() 30} 31 32// WithPipeline creates a new BlobURL object identical to the source but with the specified request policy pipeline. 33func (b BlobURL) WithPipeline(p pipeline.Pipeline) BlobURL { 34 return NewBlobURL(b.blobClient.URL(), p) 35} 36 37// WithSnapshot creates a new BlobURL object identical to the source but with the specified snapshot timestamp. 38// Pass "" to remove the snapshot returning a URL to the base blob. 39func (b BlobURL) WithSnapshot(snapshot string) BlobURL { 40 p := NewBlobURLParts(b.URL()) 41 p.Snapshot = snapshot 42 return NewBlobURL(p.URL(), b.blobClient.Pipeline()) 43} 44 45// ToAppendBlobURL creates an AppendBlobURL using the source's URL and pipeline. 46func (b BlobURL) ToAppendBlobURL() AppendBlobURL { 47 return NewAppendBlobURL(b.URL(), b.blobClient.Pipeline()) 48} 49 50// ToBlockBlobURL creates a BlockBlobURL using the source's URL and pipeline. 51func (b BlobURL) ToBlockBlobURL() BlockBlobURL { 52 return NewBlockBlobURL(b.URL(), b.blobClient.Pipeline()) 53} 54 55// ToPageBlobURL creates a PageBlobURL using the source's URL and pipeline. 56func (b BlobURL) ToPageBlobURL() PageBlobURL { 57 return NewPageBlobURL(b.URL(), b.blobClient.Pipeline()) 58} 59 60// DownloadBlob reads a range of bytes from a blob. The response also includes the blob's properties and metadata. 61// Passing azblob.CountToEnd (0) for count will download the blob from the offset to the end. 62// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob. 63func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac BlobAccessConditions, rangeGetContentMD5 bool) (*DownloadResponse, error) { 64 var xRangeGetContentMD5 *bool 65 if rangeGetContentMD5 { 66 xRangeGetContentMD5 = &rangeGetContentMD5 67 } 68 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 69 dr, err := b.blobClient.Download(ctx, nil, nil, 70 httpRange{offset: offset, count: count}.pointers(), 71 ac.LeaseAccessConditions.pointers(), xRangeGetContentMD5, 72 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 73 if err != nil { 74 return nil, err 75 } 76 return &DownloadResponse{ 77 b: b, 78 r: dr, 79 ctx: ctx, 80 getInfo: HTTPGetterInfo{Offset: offset, Count: count, ETag: dr.ETag()}, 81 }, err 82} 83 84// DeleteBlob marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. 85// Note that deleting a blob also deletes all its snapshots. 86// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob. 87func (b BlobURL) Delete(ctx context.Context, deleteOptions DeleteSnapshotsOptionType, ac BlobAccessConditions) (*BlobDeleteResponse, error) { 88 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 89 return b.blobClient.Delete(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions, 90 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 91} 92 93// Undelete restores the contents and metadata of a soft-deleted blob and any associated soft-deleted snapshots. 94// For more information, see https://docs.microsoft.com/rest/api/storageservices/undelete-blob. 95func (b BlobURL) Undelete(ctx context.Context) (*BlobUndeleteResponse, error) { 96 return b.blobClient.Undelete(ctx, nil, nil) 97} 98 99// SetTier operation sets the tier on a blob. The operation is allowed on a page 100// blob in a premium storage account and on a block blob in a blob storage account (locally 101// redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and 102// bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation 103// does not update the blob's ETag. 104// For detailed information about block blob level tiering see https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers. 105func (b BlobURL) SetTier(ctx context.Context, tier AccessTierType, lac LeaseAccessConditions) (*BlobSetTierResponse, error) { 106 return b.blobClient.SetTier(ctx, tier, nil, nil, lac.pointers()) 107} 108 109// GetBlobProperties returns the blob's properties. 110// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob-properties. 111func (b BlobURL) GetProperties(ctx context.Context, ac BlobAccessConditions) (*BlobGetPropertiesResponse, error) { 112 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 113 return b.blobClient.GetProperties(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), 114 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 115} 116 117// SetBlobHTTPHeaders changes a blob's HTTP headers. 118// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties. 119func (b BlobURL) SetHTTPHeaders(ctx context.Context, h BlobHTTPHeaders, ac BlobAccessConditions) (*BlobSetHTTPHeadersResponse, error) { 120 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 121 return b.blobClient.SetHTTPHeaders(ctx, nil, 122 &h.CacheControl, &h.ContentType, h.ContentMD5, &h.ContentEncoding, &h.ContentLanguage, 123 ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, 124 &h.ContentDisposition, nil) 125} 126 127// SetBlobMetadata changes a blob's metadata. 128// https://docs.microsoft.com/rest/api/storageservices/set-blob-metadata. 129func (b BlobURL) SetMetadata(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobSetMetadataResponse, error) { 130 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 131 return b.blobClient.SetMetadata(ctx, nil, metadata, ac.LeaseAccessConditions.pointers(), 132 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 133} 134 135// CreateSnapshot creates a read-only snapshot of a blob. 136// For more information, see https://docs.microsoft.com/rest/api/storageservices/snapshot-blob. 137func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobCreateSnapshotResponse, error) { 138 // CreateSnapshot does NOT panic if the user tries to create a snapshot using a URL that already has a snapshot query parameter 139 // because checking this would be a performance hit for a VERY unusual path and I don't think the common case should suffer this 140 // performance hit. 141 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() 142 return b.blobClient.CreateSnapshot(ctx, nil, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, ac.LeaseAccessConditions.pointers(), nil) 143} 144 145// AcquireLease acquires a lease on the blob for write and delete operations. The lease duration must be between 146// 15 to 60 seconds, or infinite (-1). 147// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. 148func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac ModifiedAccessConditions) (*BlobAcquireLeaseResponse, error) { 149 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() 150 return b.blobClient.AcquireLease(ctx, nil, &duration, &proposedID, 151 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 152} 153 154// RenewLease renews the blob's previously-acquired lease. 155// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. 156func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac ModifiedAccessConditions) (*BlobRenewLeaseResponse, error) { 157 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() 158 return b.blobClient.RenewLease(ctx, leaseID, nil, 159 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 160} 161 162// ReleaseLease releases the blob's previously-acquired lease. 163// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. 164func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac ModifiedAccessConditions) (*BlobReleaseLeaseResponse, error) { 165 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() 166 return b.blobClient.ReleaseLease(ctx, leaseID, nil, 167 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 168} 169 170// BreakLease breaks the blob's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1) 171// constant to break a fixed-duration lease when it expires or an infinite lease immediately. 172// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. 173func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac ModifiedAccessConditions) (*BlobBreakLeaseResponse, error) { 174 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() 175 return b.blobClient.BreakLease(ctx, nil, leasePeriodPointer(breakPeriodInSeconds), 176 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 177} 178 179// ChangeLease changes the blob's lease ID. 180// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. 181func (b BlobURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac ModifiedAccessConditions) (*BlobChangeLeaseResponse, error) { 182 ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() 183 return b.blobClient.ChangeLease(ctx, leaseID, proposedID, 184 nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) 185} 186 187// LeaseBreakNaturally tells ContainerURL's or BlobURL's BreakLease method to break the lease using service semantics. 188const LeaseBreakNaturally = -1 189 190func leasePeriodPointer(period int32) (p *int32) { 191 if period != LeaseBreakNaturally { 192 p = &period 193 } 194 return nil 195} 196 197// StartCopyFromURL copies the data at the source URL to a blob. 198// For more information, see https://docs.microsoft.com/rest/api/storageservices/copy-blob. 199func (b BlobURL) StartCopyFromURL(ctx context.Context, source url.URL, metadata Metadata, srcac ModifiedAccessConditions, dstac BlobAccessConditions) (*BlobStartCopyFromURLResponse, error) { 200 srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.pointers() 201 dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.ModifiedAccessConditions.pointers() 202 dstLeaseID := dstac.LeaseAccessConditions.pointers() 203 204 return b.blobClient.StartCopyFromURL(ctx, source.String(), nil, metadata, 205 srcIfModifiedSince, srcIfUnmodifiedSince, 206 srcIfMatchETag, srcIfNoneMatchETag, 207 dstIfModifiedSince, dstIfUnmodifiedSince, 208 dstIfMatchETag, dstIfNoneMatchETag, 209 dstLeaseID, nil) 210} 211 212// AbortCopyFromURL stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata. 213// For more information, see https://docs.microsoft.com/rest/api/storageservices/abort-copy-blob. 214func (b BlobURL) AbortCopyFromURL(ctx context.Context, copyID string, ac LeaseAccessConditions) (*BlobAbortCopyFromURLResponse, error) { 215 return b.blobClient.AbortCopyFromURL(ctx, copyID, nil, ac.pointers(), nil) 216} 217