92 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
| package storage
 | |
| 
 | |
| // Copyright 2017 Microsoft Corporation
 | |
| //
 | |
| //  Licensed under the Apache License, Version 2.0 (the "License");
 | |
| //  you may not use this file except in compliance with the License.
 | |
| //  You may obtain a copy of the License at
 | |
| //
 | |
| //      http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| //  Unless required by applicable law or agreed to in writing, software
 | |
| //  distributed under the License is distributed on an "AS IS" BASIS,
 | |
| //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| //  See the License for the specific language governing permissions and
 | |
| //  limitations under the License.
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"crypto/md5"
 | |
| 	"encoding/base64"
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| // PutAppendBlob initializes an empty append blob with specified name. An
 | |
| // append blob must be created using this method before appending blocks.
 | |
| //
 | |
| // See CreateBlockBlobFromReader for more info on creating blobs.
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Blob
 | |
| func (b *Blob) PutAppendBlob(options *PutBlobOptions) error {
 | |
| 	params := url.Values{}
 | |
| 	headers := b.Container.bsc.client.getStandardHeaders()
 | |
| 	headers["x-ms-blob-type"] = string(BlobTypeAppend)
 | |
| 	headers = mergeHeaders(headers, headersFromStruct(b.Properties))
 | |
| 	headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata)
 | |
| 
 | |
| 	if options != nil {
 | |
| 		params = addTimeout(params, options.Timeout)
 | |
| 		headers = mergeHeaders(headers, headersFromStruct(*options))
 | |
| 	}
 | |
| 	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
 | |
| 
 | |
| 	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	return b.respondCreation(resp, BlobTypeAppend)
 | |
| }
 | |
| 
 | |
| // AppendBlockOptions includes the options for an append block operation
 | |
| type AppendBlockOptions struct {
 | |
| 	Timeout           uint
 | |
| 	LeaseID           string     `header:"x-ms-lease-id"`
 | |
| 	MaxSize           *uint      `header:"x-ms-blob-condition-maxsize"`
 | |
| 	AppendPosition    *uint      `header:"x-ms-blob-condition-appendpos"`
 | |
| 	IfModifiedSince   *time.Time `header:"If-Modified-Since"`
 | |
| 	IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"`
 | |
| 	IfMatch           string     `header:"If-Match"`
 | |
| 	IfNoneMatch       string     `header:"If-None-Match"`
 | |
| 	RequestID         string     `header:"x-ms-client-request-id"`
 | |
| 	ContentMD5        bool
 | |
| }
 | |
| 
 | |
| // AppendBlock appends a block to an append blob.
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Append-Block
 | |
| func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
 | |
| 	params := url.Values{"comp": {"appendblock"}}
 | |
| 	headers := b.Container.bsc.client.getStandardHeaders()
 | |
| 	headers["x-ms-blob-type"] = string(BlobTypeAppend)
 | |
| 	headers["Content-Length"] = fmt.Sprintf("%v", len(chunk))
 | |
| 
 | |
| 	if options != nil {
 | |
| 		params = addTimeout(params, options.Timeout)
 | |
| 		headers = mergeHeaders(headers, headersFromStruct(*options))
 | |
| 		if options.ContentMD5 {
 | |
| 			md5sum := md5.Sum(chunk)
 | |
| 			headers[headerContentMD5] = base64.StdEncoding.EncodeToString(md5sum[:])
 | |
| 		}
 | |
| 	}
 | |
| 	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
 | |
| 
 | |
| 	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.Container.bsc.auth)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	return b.respondCreation(resp, BlobTypeAppend)
 | |
| }
 |