Skip to content
This repository has been archived by the owner on Oct 22, 2021. It is now read-only.

Implement SSE support #17

Merged
merged 6 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package cos

import "errors"

var (
// ErrServerSideEncryptionCustomerKey will be returned while server-side encryption customer key is invalid.
ErrServerSideEncryptionCustomerKey = errors.New("invalid server-side encryption customer key")
)
136 changes: 122 additions & 14 deletions generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.14

require (
github.com/aos-dev/go-integration-test/v3 v3.0.0-20210205075620-0b779f4b3afc
github.com/aos-dev/go-storage/v3 v3.4.3-0.20210417162535-67db0dd18784
github.com/aos-dev/go-storage/v3 v3.5.1-0.20210423013030-4d27effb22ca
github.com/google/uuid v1.2.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.19
)
11 changes: 6 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ github.com/Xuanwo/templateutils v0.0.0-20201216100309-46f73cd4e4b1/go.mod h1:x0q
github.com/aos-dev/go-integration-test/v3 v3.0.0-20210205075620-0b779f4b3afc h1:s8BQqJwWe2yoTGJFOsIxnkwwMsnDqMgkO39yzEP4smw=
github.com/aos-dev/go-integration-test/v3 v3.0.0-20210205075620-0b779f4b3afc/go.mod h1:2VqxZhJVvI1jKTTERWHfCBMZQaJt10xoEJ+CxbfYZlo=
github.com/aos-dev/go-storage/v3 v3.0.1-0.20210205074802-e8a5b22166c2/go.mod h1:JznhvyhPDnETfZ3RyWm3mT/S5ic+uuYFWagSIkUZujc=
github.com/aos-dev/go-storage/v3 v3.4.3-0.20210417162535-67db0dd18784 h1:eeKDDn+8RPtYuk7lrQC48OtTNeSRF/l9P5YHa/Q3omk=
github.com/aos-dev/go-storage/v3 v3.4.3-0.20210417162535-67db0dd18784/go.mod h1:PZJT0Ta7YxVM5QoYoh8Q/X4I6e/z/7gOJqm85Aib4nY=
github.com/aos-dev/go-storage/v3 v3.5.1-0.20210423013030-4d27effb22ca h1:H7wkWwIe/7Kz1+uAFBhxDYh8GX1kcyxsUIBxPE12ksk=
github.com/aos-dev/go-storage/v3 v3.5.1-0.20210423013030-4d27effb22ca/go.mod h1:JFshvl851ZDDXtFGWDFKqkg34QEPH0xuhLJ2LjikZYc=
github.com/aos-dev/specs/go v0.0.0-20210205073047-af8ef94af73d/go.mod h1:XTNlLZtPA1inITyDH5hNnQXVjvvKUvo+lurs5GYB8NA=
github.com/aos-dev/specs/go v0.0.0-20210312090615-23109627848b h1:qIehSnBbr31ATAckM9u9h6gSz+9PkGqu79vTngx6wPw=
github.com/aos-dev/specs/go v0.0.0-20210312090615-23109627848b/go.mod h1:XTNlLZtPA1inITyDH5hNnQXVjvvKUvo+lurs5GYB8NA=
github.com/aos-dev/specs/go v0.0.0-20210420062803-1a60efa2eae3 h1:LiW0Ki0Gw6opu11JwMhxWw5M+V6I9JypJ5eAIp+Rqt4=
github.com/aos-dev/specs/go v0.0.0-20210420062803-1a60efa2eae3/go.mod h1:gNah3KaPJEfysh7uCCX+sYjQC3g2yx2VgBkFlT945Ws=
github.com/dave/dst v0.26.2 h1:lnxLAKI3tx7MgLNVDirFCsDTlTG9nKTk7GcptKcWSwY=
github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU=
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
Expand Down Expand Up @@ -42,8 +42,9 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0=
github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
Expand Down
41 changes: 38 additions & 3 deletions service.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ optional = ["default_storage_pairs", "pair_policy", "work_dir"]
optional = ["list_mode"]

[namespace.storage.op.read]
optional = ["offset", "io_callback", "size"]
optional = ["offset", "io_callback", "size", "server_side_encryption_customer_algorithm", "server_side_encryption_customer_key"]

[namespace.storage.op.stat]
optional = ["server_side_encryption_customer_algorithm", "server_side_encryption_customer_key"]

[namespace.storage.op.write]
optional = ["content_md5", "content_type", "io_callback", "storage_class"]
optional = ["content_md5", "content_type", "io_callback", "storage_class", "server_side_encryption_customer_algorithm", "server_side_encryption_customer_key", "server_side_encryption", "server_side_encryption_cos_kms_key_id", "server_side_encryption_context"]

[pairs.default_service_pairs]
type = "DefaultServicePairs"
Expand All @@ -39,5 +42,37 @@ description = "set default pairs for storager actions"
[pairs.storage_class]
type = "string"

[pairs.server_side_encryption_customer_algorithm]
type = "string"
description = "specifies the algorithm to use to when encrypting the object. Now only `AES256` is supported."

[pairs.server_side_encryption_customer_key]
type = "byte_array"
description = "specifies the customer-provided encryption key to encrypt/decrypt the source object. It must be a 32-byte AES-256 key."

[pairs.server_side_encryption_cos_kms_key_id]
type = "string"
description = "specifies the COS KMS key ID to use for object encryption."

[pairs.server_side_encryption_context]
type = "string"
description = "specifies the COS KMS Encryption Context to use for object encryption. The value of this header is a base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs."

[pairs.server_side_encryption]
type = "string"
description = "the server-side encryption algorithm used when storing this object. It can be `AES-256` for SSE-COS, and `cos/kms` for SSE-KMS."

[infos.object.meta.storage-class]
type = "string"
type = "string"

[infos.object.meta.server-side-encryption]
type = "string"

[infos.object.meta.server-side-encryption-cos-kms-key-id]
type = "string"

[infos.object.meta.server-side-encryption-customer-algorithm]
type = "string"

[infos.object.meta.server-side-encryption-customer-key-md5]
type = "string"
54 changes: 52 additions & 2 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"net/http"
"time"

"github.com/tencentyun/cos-go-sdk-v5"
Expand Down Expand Up @@ -130,7 +131,15 @@ func (s *Storage) nextObjectPageByPrefix(ctx context.Context, page *ObjectPage)
func (s *Storage) read(ctx context.Context, path string, w io.Writer, opt pairStorageRead) (n int64, err error) {
rp := s.getAbsPath(path)

resp, err := s.object.Get(ctx, rp, nil)
getOptions := &cos.ObjectGetOptions{}
// SSE-C
if opt.HasServerSideEncryptionCustomerAlgorithm {
getOptions.XCosSSECustomerAglo, getOptions.XCosSSECustomerKey, getOptions.XCosSSECustomerKeyMD5, err = calculateEncryptionHeaders(opt.ServerSideEncryptionCustomerAlgorithm, opt.ServerSideEncryptionCustomerKey)
if err != nil {
return 0, err
}
}
resp, err := s.object.Get(ctx, rp, getOptions)
if err != nil {
return 0, err
}
Expand All @@ -147,7 +156,15 @@ func (s *Storage) read(ctx context.Context, path string, w io.Writer, opt pairSt
func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o *Object, err error) {
rp := s.getAbsPath(path)

output, err := s.object.Head(ctx, rp, nil)
headOptions := &cos.ObjectHeadOptions{}
// SSE-C
if opt.HasServerSideEncryptionCustomerAlgorithm {
headOptions.XCosSSECustomerAglo, headOptions.XCosSSECustomerKey, headOptions.XCosSSECustomerKeyMD5, err = calculateEncryptionHeaders(opt.ServerSideEncryptionCustomerAlgorithm, opt.ServerSideEncryptionCustomerKey)
if err != nil {
return
}
}
output, err := s.object.Head(ctx, rp, headOptions)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -184,6 +201,18 @@ func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o
if v := output.Header.Get(storageClassHeader); v != "" {
sm[MetadataStorageClass] = v
}
if v := output.Header.Get(serverSideEncryptionHeader); v != "" {
sm[MetadataServerSideEncryption] = v
}
if v := output.Header.Get(serverSideEncryptionCosKmsKeyIdHeader); v != "" {
sm[MetadataServerSideEncryptionCosKmsKeyID] = v
}
if v := output.Header.Get(serverSideEncryptionCustomerAlgorithmHeader); v != "" {
sm[MetadataServerSideEncryptionCustomerAlgorithm] = v
}
if v := output.Header.Get(serverSideEncryptionCustomerKeyMd5Header); v != "" {
sm[MetadataServerSideEncryptionCustomerKeyMd5] = v
}
o.SetServiceMetadata(sm)

return o, nil
Expand All @@ -207,6 +236,27 @@ func (s *Storage) write(ctx context.Context, path string, r io.Reader, size int6
if opt.HasStorageClass {
putOptions.XCosStorageClass = opt.StorageClass
}
// SSE-C
if opt.HasServerSideEncryptionCustomerAlgorithm {
putOptions.XCosSSECustomerAglo, putOptions.XCosSSECustomerKey, putOptions.XCosSSECustomerKeyMD5, err = calculateEncryptionHeaders(opt.ServerSideEncryptionCustomerAlgorithm, opt.ServerSideEncryptionCustomerKey)
if err != nil {
return
}
}
// SSE-COS or SSE-KMS
if opt.HasServerSideEncryption {
putOptions.XCosServerSideEncryption = opt.ServerSideEncryption
if opt.ServerSideEncryption == ServerSideEncryptionCosKms {
// FIXME: we can remove the usage of `XOptionHeader` when cos' SDK supports SSE-KMS
putOptions.XOptionHeader = &http.Header{}
if opt.HasServerSideEncryptionCosKmsKeyID {
putOptions.XOptionHeader.Set(serverSideEncryptionCosKmsKeyIdHeader, opt.ServerSideEncryptionCosKmsKeyID)
}
if opt.HasServerSideEncryptionContext {
putOptions.XOptionHeader.Set(serverSideEncryptionContextHeader, opt.ServerSideEncryptionContext)
}
}
}
if opt.HasIoCallback {
r = iowrap.CallbackReader(r, opt.IoCallback)
}
Expand Down
Loading