Browse Source

add sse-c and optional header for put object

tags/v0.7.8
jojoliang 5 years ago
parent
commit
7942b364df
  1. 79
      costesting/ci_test.go
  2. 34
      object.go
  3. 4
      object_part.go

79
costesting/ci_test.go

@ -549,6 +549,85 @@ func (s *CosTestSuite) TestCreateCompleteMultipartUpload() {
assert.Nil(s.T(), err, "CompleteMultipartUpload Failed")
}
func (s *CosTestSuite) TestSSE_C() {
name := "test/TestSSE_C"
content := "test sse-c " + time.Now().Format(time.RFC3339)
f := strings.NewReader(content)
putOpt := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
ContentType: "text/html",
//XCosServerSideEncryption: "AES256",
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
},
ACLHeaderOptions: &cos.ACLHeaderOptions{
XCosACL: "public-read",
//XCosACL: "private",
},
}
_, err := s.Client.Object.Put(context.Background(), name, f, putOpt)
assert.Nil(s.T(), err, "PutObject with SSE failed")
headOpt := &cos.ObjectHeadOptions{
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
}
_, err = s.Client.Object.Head(context.Background(), name, headOpt)
assert.Nil(s.T(), err, "HeadObject with SSE failed")
getOpt := &cos.ObjectGetOptions{
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
}
var resp *cos.Response
resp, err = s.Client.Object.Get(context.Background(), name, getOpt)
assert.Nil(s.T(), err, "GetObject with SSE failed")
bodyBytes, _ := ioutil.ReadAll(resp.Body)
bodyContent := string(bodyBytes)
assert.Equal(s.T(), content, bodyContent, "GetObject with SSE failed, want: %+v, res: %+v", content, bodyContent)
copyOpt := &cos.ObjectCopyOptions{
&cos.ObjectCopyHeaderOptions{
XCosCopySourceSSECustomerAglo: "AES256",
XCosCopySourceSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosCopySourceSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
},
&cos.ACLHeaderOptions{},
}
copySource := s.Bucket + "-" + s.Appid + ".cos." + s.Region + ".myqcloud.com/" + name
_, _, err = s.Client.Object.Copy(context.Background(), "test/TestSSE_C_Copy", copySource, copyOpt)
assert.Nil(s.T(), err, "CopyObject with SSE failed")
partIni := &cos.MultiUploadOptions{
OptIni: &cos.InitiateMultipartUploadOptions{
&cos.ACLHeaderOptions{},
&cos.ObjectPutHeaderOptions{
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
},
},
PartSize: 1,
}
filePath := "tmpfile" + time.Now().Format(time.RFC3339)
newFile, err := os.Create(filePath)
assert.Nil(s.T(), err, "create tmp file Failed")
defer newFile.Close()
b := make([]byte, 1024*10)
_, err = rand.Read(b)
newFile.Write(b)
_, _, err = s.Client.Object.MultiUpload(context.Background(), "test/TestSSE_C_MultiUpload", filePath, partIni)
assert.Nil(s.T(), err, "MultiUpload with SSE failed")
err = os.Remove(filePath)
assert.Nil(s.T(), err, "remove local file Failed")
}
// End of api test
// All methods that begin with "Test" are run as tests within a

34
object.go

@ -26,6 +26,10 @@ type ObjectGetOptions struct {
ResponseContentEncoding string `url:"response-content-encoding,omitempty" header:"-"`
Range string `url:"-" header:"Range,omitempty"`
IfModifiedSince string `url:"-" header:"If-Modified-Since,omitempty"`
// SSE-C
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
}
// presignedURLTestingOptions is the opt of presigned url
@ -135,6 +139,12 @@ type ObjectPutHeaderOptions struct {
//XCosObjectType string `header:"x-cos-object-type,omitempty" url:"-"`
// Enable Server Side Encryption, Only supported: AES256
XCosServerSideEncryption string `header:"x-cos-server-side-encryption,omitempty" url:"-" xml:"-"`
// SSE-C
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
//兼容其他自定义头部
XOptionHeader *http.Header `header:"-,omitempty" url:"-" xml:"-"`
}
// ObjectPutOptions the options of put object
@ -191,6 +201,13 @@ type ObjectCopyHeaderOptions struct {
XCosMetaXXX *http.Header `header:"x-cos-meta-*,omitempty" url:"-"`
XCosCopySource string `header:"x-cos-copy-source" url:"-" xml:"-"`
XCosServerSideEncryption string `header:"x-cos-server-side-encryption,omitempty" url:"-" xml:"-"`
// SSE-C
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
XCosCopySourceSSECustomerAglo string `header:"x-cos-copy-source-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosCopySourceSSECustomerKey string `header:"x-cos-copy-source-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosCopySourceSSECustomerKeyMD5 string `header:"x-cos-copy-source-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
}
// ObjectCopyOptions is the option of Copy, choose header or body
@ -272,6 +289,10 @@ func (s *ObjectService) Delete(ctx context.Context, name string) (*Response, err
// ObjectHeadOptions is the option of HeadObject
type ObjectHeadOptions struct {
IfModifiedSince string `url:"-" header:"If-Modified-Since,omitempty"`
// SSE-C
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
}
// Head Object请求可以取回对应Object的元数据,Head的权限与Get的权限一致
@ -472,14 +493,12 @@ func worker(s *ObjectService, jobs <-chan *Jobs, results chan<- *Results) {
fd.Seek(j.Chunk.OffSet, os.SEEK_SET)
// UploadPart do not support the chunk trsf, so need to add the content-length
opt := &ObjectUploadPartOptions{
ContentLength: int(j.Chunk.Size),
}
j.Opt.ContentLength = int(j.Chunk.Size)
rt := j.RetryTimes
for {
resp, err := s.UploadPart(context.Background(), j.Name, j.UploadId, j.Chunk.Number,
&io.LimitedReader{R: fd, N: j.Chunk.Size}, opt)
&io.LimitedReader{R: fd, N: j.Chunk.Size}, j.Opt)
res.PartNumber = j.Chunk.Number
res.Resp = resp
if err != nil {
@ -581,12 +600,19 @@ func (s *ObjectService) MultiUpload(ctx context.Context, name string, filepath s
// 4.Push jobs
for _, chunk := range chunks {
partOpt := &ObjectUploadPartOptions{}
if optini != nil && optini.ObjectPutHeaderOptions != nil {
partOpt.XCosSSECustomerAglo = optini.XCosSSECustomerAglo
partOpt.XCosSSECustomerKey = optini.XCosSSECustomerKey
partOpt.XCosSSECustomerKeyMD5 = optini.XCosSSECustomerKeyMD5
}
job := &Jobs{
Name: name,
RetryTimes: 3,
FilePath: filepath,
UploadId: uploadID,
Chunk: chunk,
Opt: partOpt,
}
chjobs <- job
}

4
object_part.go

@ -44,6 +44,10 @@ type ObjectUploadPartOptions struct {
Expect string `header:"Expect,omitempty" url:"-"`
XCosContentSHA1 string `header:"x-cos-content-sha1" url:"-"`
ContentLength int `header:"Content-Length,omitempty" url:"-"`
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
}
// UploadPart 请求实现在初始化以后的分块上传,支持的块的数量为1到10000,块的大小为1 MB 到5 GB。

Loading…
Cancel
Save