You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
20 KiB

4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package coscrypto_test
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/aes"
  6. "crypto/cipher"
  7. "crypto/md5"
  8. "crypto/rand"
  9. "encoding/base64"
  10. "fmt"
  11. "io"
  12. "io/ioutil"
  13. math_rand "math/rand"
  14. "net/http"
  15. "net/url"
  16. "os"
  17. "testing"
  18. "time"
  19. "git.ouxuan.net/tommy/cos-go-sdk-v5"
  20. coscrypto "git.ouxuan.net/tommy/cos-go-sdk-v5/crypto"
  21. "github.com/stretchr/testify/assert"
  22. "github.com/stretchr/testify/suite"
  23. )
  24. const (
  25. kAppid = 1259654469
  26. kBucket = "cosgosdktest-1259654469"
  27. kRegion = "ap-guangzhou"
  28. )
  29. type CosTestSuite struct {
  30. suite.Suite
  31. Client *cos.Client
  32. CClient *coscrypto.CryptoClient
  33. Master coscrypto.MasterCipher
  34. }
  35. func (s *CosTestSuite) SetupSuite() {
  36. u, _ := url.Parse("https://" + kBucket + ".cos." + kRegion + ".myqcloud.com")
  37. b := &cos.BaseURL{BucketURL: u}
  38. s.Client = cos.NewClient(b, &http.Client{
  39. Transport: &cos.AuthorizationTransport{
  40. SecretID: os.Getenv("COS_SECRETID"),
  41. SecretKey: os.Getenv("COS_SECRETKEY"),
  42. },
  43. })
  44. material := make(map[string]string)
  45. material["desc"] = "cos crypto suite test"
  46. kmsclient, _ := coscrypto.NewKMSClient(s.Client.GetCredential(), kRegion)
  47. s.Master, _ = coscrypto.CreateMasterKMS(kmsclient, os.Getenv("KMSID"), material)
  48. s.CClient = coscrypto.NewCryptoClient(s.Client, s.Master)
  49. opt := &cos.BucketPutOptions{
  50. XCosACL: "public-read",
  51. }
  52. r, err := s.Client.Bucket.Put(context.Background(), opt)
  53. if err != nil && r != nil && r.StatusCode == 409 {
  54. fmt.Println("BucketAlreadyOwnedByYou")
  55. } else if err != nil {
  56. assert.Nil(s.T(), err, "PutBucket Failed")
  57. }
  58. }
  59. func (s *CosTestSuite) TestPutGetDeleteObject_DecryptWithKey_10MB() {
  60. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  61. originData := make([]byte, 1024*1024*10+1)
  62. _, err := rand.Read(originData)
  63. f := bytes.NewReader(originData)
  64. // 加密存储
  65. _, err = s.CClient.Object.Put(context.Background(), name, f, nil)
  66. assert.Nil(s.T(), err, "PutObject Failed")
  67. // 获取解密信息
  68. resp, err := s.CClient.Object.Head(context.Background(), name, nil)
  69. assert.Nil(s.T(), err, "HeadObject Failed")
  70. cipherKey := resp.Header.Get(coscrypto.COSClientSideEncryptionKey)
  71. cipherKeybs, err := base64.StdEncoding.DecodeString(cipherKey)
  72. assert.Nil(s.T(), err, "base64 Decode Failed")
  73. cipherIV := resp.Header.Get(coscrypto.COSClientSideEncryptionStart)
  74. cipherIVbs, err := base64.StdEncoding.DecodeString(cipherIV)
  75. assert.Nil(s.T(), err, "base64 Decode Failed")
  76. key, err := s.Master.Decrypt(cipherKeybs)
  77. assert.Nil(s.T(), err, "Master Decrypt Failed")
  78. iv, err := s.Master.Decrypt(cipherIVbs)
  79. assert.Nil(s.T(), err, "Master Decrypt Failed")
  80. // 正常读取
  81. resp, err = s.Client.Object.Get(context.Background(), name, nil)
  82. assert.Nil(s.T(), err, "GetObject Failed")
  83. defer resp.Body.Close()
  84. encryptedData, _ := ioutil.ReadAll(resp.Body)
  85. assert.NotEqual(s.T(), bytes.Compare(encryptedData, originData), 0, "encryptedData == originData")
  86. // 手动解密
  87. block, err := aes.NewCipher(key)
  88. assert.Nil(s.T(), err, "NewCipher Failed")
  89. decrypter := cipher.NewCTR(block, iv)
  90. decryptedData := make([]byte, len(originData))
  91. decrypter.XORKeyStream(decryptedData, encryptedData)
  92. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  93. _, err = s.CClient.Object.Delete(context.Background(), name)
  94. assert.Nil(s.T(), err, "DeleteObject Failed")
  95. }
  96. func (s *CosTestSuite) TestPutGetDeleteObject_Normal_10MB() {
  97. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  98. originData := make([]byte, 1024*1024*10+1)
  99. _, err := rand.Read(originData)
  100. f := bytes.NewReader(originData)
  101. // 加密存储
  102. _, err = s.CClient.Object.Put(context.Background(), name, f, nil)
  103. assert.Nil(s.T(), err, "PutObject Failed")
  104. // 解密读取
  105. resp, err := s.CClient.Object.Get(context.Background(), name, nil)
  106. assert.Nil(s.T(), err, "GetObject Failed")
  107. defer resp.Body.Close()
  108. decryptedData, _ := ioutil.ReadAll(resp.Body)
  109. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  110. _, err = s.CClient.Object.Delete(context.Background(), name)
  111. assert.Nil(s.T(), err, "DeleteObject Failed")
  112. }
  113. func (s *CosTestSuite) TestPutGetDeleteObject_VersionID() {
  114. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  115. originData := make([]byte, 1024*1024*10+1)
  116. _, err := rand.Read(originData)
  117. f := bytes.NewReader(originData)
  118. opt := &cos.BucketPutVersionOptions{
  119. Status: "Enabled",
  120. }
  121. _, err = s.CClient.Bucket.PutVersioning(context.Background(), opt)
  122. assert.Nil(s.T(), err, "PutVersioning Failed")
  123. time.Sleep(3 * time.Second)
  124. // 加密存储
  125. resp, err := s.CClient.Object.Put(context.Background(), name, f, nil)
  126. assert.Nil(s.T(), err, "PutObject Failed")
  127. versionId := resp.Header.Get("x-cos-version-id")
  128. _, err = s.CClient.Object.Delete(context.Background(), name)
  129. assert.Nil(s.T(), err, "DeleteObject Failed")
  130. // 解密读取
  131. resp, err = s.CClient.Object.Get(context.Background(), name, nil, versionId)
  132. assert.Nil(s.T(), err, "GetObject Failed")
  133. defer resp.Body.Close()
  134. decryptedData, _ := ioutil.ReadAll(resp.Body)
  135. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  136. delopt := &cos.ObjectDeleteOptions{
  137. VersionId: versionId,
  138. }
  139. _, err = s.CClient.Object.Delete(context.Background(), name, delopt)
  140. assert.Nil(s.T(), err, "DeleteObject Failed")
  141. opt.Status = "Suspended"
  142. _, err = s.CClient.Bucket.PutVersioning(context.Background(), opt)
  143. assert.Nil(s.T(), err, "PutVersioning Failed")
  144. }
  145. func (s *CosTestSuite) TestPutGetDeleteObject_ZeroFile() {
  146. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  147. // 加密存储
  148. _, err := s.CClient.Object.Put(context.Background(), name, bytes.NewReader([]byte("")), nil)
  149. assert.Nil(s.T(), err, "PutObject Failed")
  150. // 解密读取
  151. resp, err := s.CClient.Object.Get(context.Background(), name, nil)
  152. assert.Nil(s.T(), err, "GetObject Failed")
  153. defer resp.Body.Close()
  154. decryptedData, _ := ioutil.ReadAll(resp.Body)
  155. assert.Equal(s.T(), bytes.Compare([]byte(""), decryptedData), 0, "decryptData != originData")
  156. _, err = s.CClient.Object.Delete(context.Background(), name)
  157. assert.Nil(s.T(), err, "DeleteObject Failed")
  158. }
  159. func (s *CosTestSuite) TestPutGetDeleteObject_WithMetaData() {
  160. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  161. originData := make([]byte, 1024*1024*10+1)
  162. _, err := rand.Read(originData)
  163. f := bytes.NewReader(originData)
  164. m := md5.New()
  165. m.Write(originData)
  166. contentMD5 := m.Sum(nil)
  167. opt := &cos.ObjectPutOptions{
  168. &cos.ACLHeaderOptions{
  169. XCosACL: "private",
  170. },
  171. &cos.ObjectPutHeaderOptions{
  172. ContentLength: 1024*1024*10 + 1,
  173. ContentMD5: base64.StdEncoding.EncodeToString(contentMD5),
  174. XCosMetaXXX: &http.Header{},
  175. },
  176. }
  177. opt.XCosMetaXXX.Add("x-cos-meta-isEncrypted", "true")
  178. // 加密存储
  179. _, err = s.CClient.Object.Put(context.Background(), name, f, opt)
  180. assert.Nil(s.T(), err, "PutObject Failed")
  181. // 解密读取
  182. resp, err := s.CClient.Object.Get(context.Background(), name, nil)
  183. assert.Nil(s.T(), err, "GetObject Failed")
  184. defer resp.Body.Close()
  185. decryptedData, _ := ioutil.ReadAll(resp.Body)
  186. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  187. assert.Equal(s.T(), resp.Header.Get("x-cos-meta-isEncrypted"), "true", "meta data isn't consistent")
  188. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionCekAlg), coscrypto.AesCtrAlgorithm, "meta data isn't consistent")
  189. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionWrapAlg), coscrypto.CosKmsCryptoWrap, "meta data isn't consistent")
  190. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionUnencryptedContentMD5), base64.StdEncoding.EncodeToString(contentMD5), "meta data isn't consistent")
  191. _, err = s.CClient.Object.Delete(context.Background(), name)
  192. assert.Nil(s.T(), err, "DeleteObject Failed")
  193. }
  194. func (s *CosTestSuite) TestPutGetDeleteObject_ByFile() {
  195. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  196. filepath := "tmpfile" + time.Now().Format(time.RFC3339)
  197. newfile, err := os.Create(filepath)
  198. assert.Nil(s.T(), err, "Create File Failed")
  199. defer os.Remove(filepath)
  200. originData := make([]byte, 1024*1024*10+1)
  201. _, err = rand.Read(originData)
  202. newfile.Write(originData)
  203. newfile.Close()
  204. m := md5.New()
  205. m.Write(originData)
  206. contentMD5 := m.Sum(nil)
  207. opt := &cos.ObjectPutOptions{
  208. &cos.ACLHeaderOptions{
  209. XCosACL: "private",
  210. },
  211. &cos.ObjectPutHeaderOptions{
  212. ContentLength: 1024*1024*10 + 1,
  213. ContentMD5: base64.StdEncoding.EncodeToString(contentMD5),
  214. XCosMetaXXX: &http.Header{},
  215. },
  216. }
  217. opt.XCosMetaXXX.Add("x-cos-meta-isEncrypted", "true")
  218. // 加密存储
  219. _, err = s.CClient.Object.PutFromFile(context.Background(), name, filepath, opt)
  220. assert.Nil(s.T(), err, "PutFromFile Failed")
  221. // 解密读取
  222. downfile := "downfile" + time.Now().Format(time.RFC3339)
  223. resp, err := s.CClient.Object.GetToFile(context.Background(), name, downfile, nil)
  224. assert.Nil(s.T(), err, "GetToFile Failed")
  225. assert.Equal(s.T(), resp.Header.Get("x-cos-meta-isEncrypted"), "true", "meta data isn't consistent")
  226. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionCekAlg), coscrypto.AesCtrAlgorithm, "meta data isn't consistent")
  227. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionWrapAlg), coscrypto.CosKmsCryptoWrap, "meta data isn't consistent")
  228. assert.Equal(s.T(), resp.Header.Get(coscrypto.COSClientSideEncryptionUnencryptedContentMD5), base64.StdEncoding.EncodeToString(contentMD5), "meta data isn't consistent")
  229. fd, err := os.Open(downfile)
  230. assert.Nil(s.T(), err, "Open File Failed")
  231. defer os.Remove(downfile)
  232. defer fd.Close()
  233. m = md5.New()
  234. io.Copy(m, fd)
  235. downContentMD5 := m.Sum(nil)
  236. assert.Equal(s.T(), bytes.Compare(contentMD5, downContentMD5), 0, "decryptData != originData")
  237. _, err = s.CClient.Object.Delete(context.Background(), name)
  238. assert.Nil(s.T(), err, "DeleteObject Failed")
  239. }
  240. func (s *CosTestSuite) TestPutGetDeleteObject_DecryptWithNewClient_10MB() {
  241. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  242. originData := make([]byte, 1024*1024*10+1)
  243. _, err := rand.Read(originData)
  244. f := bytes.NewReader(originData)
  245. // 加密存储
  246. _, err = s.CClient.Object.Put(context.Background(), name, f, nil)
  247. assert.Nil(s.T(), err, "PutObject Failed")
  248. u, _ := url.Parse("https://" + kBucket + ".cos." + kRegion + ".myqcloud.com")
  249. b := &cos.BaseURL{BucketURL: u}
  250. c := cos.NewClient(b, &http.Client{
  251. Transport: &cos.AuthorizationTransport{
  252. SecretID: os.Getenv("COS_SECRETID"),
  253. SecretKey: os.Getenv("COS_SECRETKEY"),
  254. },
  255. })
  256. {
  257. // 使用不同的MatDesc客户端读取, 期待错误
  258. material := make(map[string]string)
  259. material["desc"] = "cos crypto suite test 2"
  260. kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), kRegion)
  261. master, _ := coscrypto.CreateMasterKMS(kmsclient, os.Getenv("KMSID"), material)
  262. client := coscrypto.NewCryptoClient(c, master)
  263. resp, err := client.Object.Get(context.Background(), name, nil)
  264. assert.Nil(s.T(), resp, "Get Object Failed")
  265. assert.NotNil(s.T(), err, "Get Object Failed")
  266. }
  267. {
  268. // 使用相同的MatDesc客户端读取, 但KMSID不一样,期待正确,kms解密是不需要KMSID
  269. material := make(map[string]string)
  270. material["desc"] = "cos crypto suite test"
  271. kmsclient, _ := coscrypto.NewKMSClient(s.Client.GetCredential(), kRegion)
  272. master, _ := coscrypto.CreateMasterKMS(kmsclient, "KMSID", material)
  273. client := coscrypto.NewCryptoClient(c, master)
  274. resp, err := client.Object.Get(context.Background(), name, nil)
  275. assert.Nil(s.T(), err, "Get Object Failed")
  276. defer resp.Body.Close()
  277. decryptedData, _ := ioutil.ReadAll(resp.Body)
  278. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  279. }
  280. {
  281. // 使用相同的MatDesc和KMSID客户端读取, 期待正确
  282. material := make(map[string]string)
  283. material["desc"] = "cos crypto suite test"
  284. kmsclient, _ := coscrypto.NewKMSClient(s.Client.GetCredential(), kRegion)
  285. master, _ := coscrypto.CreateMasterKMS(kmsclient, os.Getenv("KMSID"), material)
  286. client := coscrypto.NewCryptoClient(c, master)
  287. resp, err := client.Object.Get(context.Background(), name, nil)
  288. assert.Nil(s.T(), err, "Get Object Failed")
  289. defer resp.Body.Close()
  290. decryptedData, _ := ioutil.ReadAll(resp.Body)
  291. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  292. }
  293. _, err = s.CClient.Object.Delete(context.Background(), name)
  294. assert.Nil(s.T(), err, "DeleteObject Failed")
  295. }
  296. func (s *CosTestSuite) TestPutGetDeleteObject_RangeGet() {
  297. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  298. contentLength := 1024*1024*10 + 1
  299. originData := make([]byte, contentLength)
  300. _, err := rand.Read(originData)
  301. f := bytes.NewReader(originData)
  302. // 加密存储
  303. _, err = s.CClient.Object.Put(context.Background(), name, f, nil)
  304. assert.Nil(s.T(), err, "PutObject Failed")
  305. // Range解密读取
  306. for i := 0; i < 10; i++ {
  307. math_rand.Seed(time.Now().UnixNano())
  308. rangeStart := math_rand.Intn(contentLength)
  309. rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart)
  310. if rangeEnd == rangeStart || rangeStart >= contentLength-1 {
  311. continue
  312. }
  313. opt := &cos.ObjectGetOptions{
  314. Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd),
  315. }
  316. resp, err := s.CClient.Object.Get(context.Background(), name, opt)
  317. assert.Nil(s.T(), err, "GetObject Failed")
  318. defer resp.Body.Close()
  319. decryptedData, _ := ioutil.ReadAll(resp.Body)
  320. assert.Equal(s.T(), bytes.Compare(originData[rangeStart:rangeEnd+1], decryptedData), 0, "decryptData != originData")
  321. }
  322. // 解密读取
  323. resp, err := s.CClient.Object.Get(context.Background(), name, nil)
  324. assert.Nil(s.T(), err, "GetObject Failed")
  325. defer resp.Body.Close()
  326. decryptedData, _ := ioutil.ReadAll(resp.Body)
  327. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  328. _, err = s.CClient.Object.Delete(context.Background(), name)
  329. assert.Nil(s.T(), err, "DeleteObject Failed")
  330. }
  331. func (s *CosTestSuite) TestPutGetDeleteObject_WithListenerAndRange() {
  332. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  333. contentLength := 1024*1024*10 + 1
  334. originData := make([]byte, contentLength)
  335. _, err := rand.Read(originData)
  336. f := bytes.NewReader(originData)
  337. // 加密存储
  338. popt := &cos.ObjectPutOptions{
  339. nil,
  340. &cos.ObjectPutHeaderOptions{
  341. Listener: &cos.DefaultProgressListener{},
  342. },
  343. }
  344. _, err = s.CClient.Object.Put(context.Background(), name, f, popt)
  345. assert.Nil(s.T(), err, "PutObject Failed")
  346. // Range解密读取
  347. for i := 0; i < 10; i++ {
  348. math_rand.Seed(time.Now().UnixNano())
  349. rangeStart := math_rand.Intn(contentLength)
  350. rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart)
  351. if rangeEnd == rangeStart || rangeStart >= contentLength-1 {
  352. continue
  353. }
  354. opt := &cos.ObjectGetOptions{
  355. Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd),
  356. Listener: &cos.DefaultProgressListener{},
  357. }
  358. resp, err := s.CClient.Object.Get(context.Background(), name, opt)
  359. assert.Nil(s.T(), err, "GetObject Failed")
  360. defer resp.Body.Close()
  361. decryptedData, _ := ioutil.ReadAll(resp.Body)
  362. assert.Equal(s.T(), bytes.Compare(originData[rangeStart:rangeEnd+1], decryptedData), 0, "decryptData != originData")
  363. }
  364. // 解密读取
  365. opt := &cos.ObjectGetOptions{
  366. Listener: &cos.DefaultProgressListener{},
  367. }
  368. resp, err := s.CClient.Object.Get(context.Background(), name, opt)
  369. assert.Nil(s.T(), err, "GetObject Failed")
  370. defer resp.Body.Close()
  371. decryptedData, _ := ioutil.ReadAll(resp.Body)
  372. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  373. _, err = s.CClient.Object.Delete(context.Background(), name)
  374. assert.Nil(s.T(), err, "DeleteObject Failed")
  375. }
  376. func (s *CosTestSuite) TestPutGetDeleteObject_Copy() {
  377. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  378. contentLength := 1024*1024*10 + 1
  379. originData := make([]byte, contentLength)
  380. _, err := rand.Read(originData)
  381. f := bytes.NewReader(originData)
  382. // 加密存储
  383. popt := &cos.ObjectPutOptions{
  384. nil,
  385. &cos.ObjectPutHeaderOptions{
  386. Listener: &cos.DefaultProgressListener{},
  387. },
  388. }
  389. resp, err := s.CClient.Object.Put(context.Background(), name, f, popt)
  390. assert.Nil(s.T(), err, "PutObject Failed")
  391. encryptedDataCRC := resp.Header.Get("x-cos-hash-crc64ecma")
  392. time.Sleep(3 * time.Second)
  393. sourceURL := fmt.Sprintf("%s/%s", s.CClient.BaseURL.BucketURL.Host, name)
  394. {
  395. // x-cos-metadata-directive必须为Copy,否则丢失加密信息,无法解密
  396. dest := "test/ObjectCopy1" + time.Now().Format(time.RFC3339)
  397. res, _, err := s.CClient.Object.Copy(context.Background(), dest, sourceURL, nil)
  398. assert.Nil(s.T(), err, "ObjectCopy Failed")
  399. assert.Equal(s.T(), encryptedDataCRC, res.CRC64, "CRC isn't consistent, return:%v, want:%v", res.CRC64, encryptedDataCRC)
  400. // Range解密读取
  401. for i := 0; i < 3; i++ {
  402. math_rand.Seed(time.Now().UnixNano())
  403. rangeStart := math_rand.Intn(contentLength)
  404. rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart)
  405. if rangeEnd == rangeStart || rangeStart >= contentLength-1 {
  406. continue
  407. }
  408. opt := &cos.ObjectGetOptions{
  409. Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd),
  410. Listener: &cos.DefaultProgressListener{},
  411. }
  412. resp, err := s.CClient.Object.Get(context.Background(), dest, opt)
  413. assert.Nil(s.T(), err, "GetObject Failed")
  414. defer resp.Body.Close()
  415. decryptedData, _ := ioutil.ReadAll(resp.Body)
  416. assert.Equal(s.T(), bytes.Compare(originData[rangeStart:rangeEnd+1], decryptedData), 0, "decryptData != originData")
  417. }
  418. // 解密读取
  419. resp, err := s.CClient.Object.Get(context.Background(), dest, nil)
  420. assert.Nil(s.T(), err, "GetObject Failed")
  421. defer resp.Body.Close()
  422. decryptedData, _ := ioutil.ReadAll(resp.Body)
  423. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  424. _, err = s.CClient.Object.Delete(context.Background(), dest)
  425. assert.Nil(s.T(), err, "DeleteObject Failed")
  426. }
  427. {
  428. // x-cos-metadata-directive必须为Copy,否则丢失加密信息,无法解密
  429. opt := &cos.ObjectCopyOptions{
  430. &cos.ObjectCopyHeaderOptions{
  431. XCosMetadataDirective: "Replaced",
  432. },
  433. nil,
  434. }
  435. dest := "test/ObjectCopy2" + time.Now().Format(time.RFC3339)
  436. res, _, err := s.CClient.Object.Copy(context.Background(), dest, sourceURL, opt)
  437. assert.Nil(s.T(), err, "ObjectCopy Failed")
  438. assert.Equal(s.T(), encryptedDataCRC, res.CRC64, "CRC isn't consistent, return:%v, want:%v", res.CRC64, encryptedDataCRC)
  439. // 解密读取
  440. resp, err := s.CClient.Object.Get(context.Background(), dest, nil)
  441. assert.Nil(s.T(), err, "GetObject Failed")
  442. defer resp.Body.Close()
  443. decryptedData, _ := ioutil.ReadAll(resp.Body)
  444. assert.NotEqual(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  445. _, err = s.CClient.Object.Delete(context.Background(), dest)
  446. assert.Nil(s.T(), err, "DeleteObject Failed")
  447. }
  448. {
  449. // MultiCopy若是分块拷贝,则无法拷贝元数据
  450. dest := "test/ObjectCopy3" + time.Now().Format(time.RFC3339)
  451. res, _, err := s.CClient.Object.MultiCopy(context.Background(), dest, sourceURL, nil)
  452. assert.Nil(s.T(), err, "ObjectMultiCopy Failed")
  453. assert.Equal(s.T(), encryptedDataCRC, res.CRC64, "CRC isn't consistent, return:%v, want:%v", res.CRC64, encryptedDataCRC)
  454. // Range解密读取
  455. for i := 0; i < 3; i++ {
  456. math_rand.Seed(time.Now().UnixNano())
  457. rangeStart := math_rand.Intn(contentLength)
  458. rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart)
  459. if rangeEnd == rangeStart || rangeStart >= contentLength-1 {
  460. continue
  461. }
  462. opt := &cos.ObjectGetOptions{
  463. Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd),
  464. Listener: &cos.DefaultProgressListener{},
  465. }
  466. resp, err := s.CClient.Object.Get(context.Background(), dest, opt)
  467. assert.Nil(s.T(), err, "GetObject Failed")
  468. defer resp.Body.Close()
  469. decryptedData, _ := ioutil.ReadAll(resp.Body)
  470. assert.Equal(s.T(), bytes.Compare(originData[rangeStart:rangeEnd+1], decryptedData), 0, "decryptData != originData")
  471. }
  472. // 解密读取
  473. resp, err := s.CClient.Object.Get(context.Background(), dest, nil)
  474. assert.Nil(s.T(), err, "GetObject Failed")
  475. defer resp.Body.Close()
  476. decryptedData, _ := ioutil.ReadAll(resp.Body)
  477. assert.Equal(s.T(), bytes.Compare(originData, decryptedData), 0, "decryptData != originData")
  478. _, err = s.CClient.Object.Delete(context.Background(), dest)
  479. assert.Nil(s.T(), err, "DeleteObject Failed")
  480. }
  481. _, err = s.CClient.Object.Delete(context.Background(), name)
  482. assert.Nil(s.T(), err, "DeleteObject Failed")
  483. }
  484. func TestCosTestSuite(t *testing.T) {
  485. suite.Run(t, new(CosTestSuite))
  486. }
  487. func (s *CosTestSuite) TearDownSuite() {
  488. }