This commit is contained in:
a158
2026-04-05 20:22:11 +08:00
commit 3cf88acc07
184 changed files with 82333 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
.idea
.github
.git
.vscode
build/*
cmake-build-debug/*
/.vs
/out/build/x64-Debug

645
CHANGELOG.md Normal file
View File

@@ -0,0 +1,645 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
## [v5.5.20](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.19...v5.5.20) - 2026-03-02
通过滑动窗口优化分块上传和下载对象的方式,提升并发上传和下载的速度
### Merged
- 通过滑动窗口优化分块上传和下载对象的并发执行效率,提升上传和下载的速度 [`#196`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/196)
- 修复已知问题,移除编译好的三方库文件(提供编译说明) [`#192`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/192)
### Commits
- 去除编译好的 poco 和 openssl 动态和静态库文件 [`840e821`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/840e82186802635da6949ab7502594c93c57bc46)
- 通过滑动窗口提高并发上传和下载对象的速度 [`a8c6698`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a8c6698efe43b82902bbfd0cd28ce4f835e28730)
- 修复使用临时token时生成的预签名URL无法正常使用的问题 [`f986371`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/f98637163d1667e6be73f3ceccdf2ad699a4599c)
- 添加列举桶内对象的demo [`ef48e42`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ef48e42eba48181d868a02a4bb5b99c897f6062f)
- Updated CHANGELOG.md [`b273cfe`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b273cfe57eea0ff7a2a37e428cd28987ee77362e)
- 更新SDK版本号 [`03af8e0`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/03af8e03b3043f06667249d280c44caf5b769799)
## [v5.5.19](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.18...v5.5.19) - 2025-10-28
1. Support automatic retries based on HTTP response status codes upon failure detection
2. Fix progress callback overflow issue (exceeding 100%) in asynchronous upload-download methods after configuration
3. Add part length validation for each downloaded part during partial downloads
## What's Changed
* opt cpu&mem for MultiPutObject&PutObjectResumableSingleThreadSync,add cmake option USE_OPENSSL_MD5 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/182
* Add SetCheckPartCrc64() for MultiPutObjectReq by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/185
* add retry policy by @lgtczh in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/186
* Feature zackcao e5e98908 by @lgtczh in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/190
## New Contributors
* @lgtczh made their first contribution in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/190
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.18...v5.5.19
### Merged
- Feature zackcao e5e98908 [`#190`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/190)
- add retry policy [`#186`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/186)
- Add SetCheckPartCrc64() for MultiPutObjectReq [`#185`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/185)
- opt cpu&mem for MultiPutObject&PutObjectResumableSingleThreadSync,add cmake option USE_OPENSSL_MD5 [`#182`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/182)
### Commits
- [合规重试]普通接口请求支持重试策略 [`f800cf7`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/f800cf7354e148227a375c69e179a862fa437d58)
- 修复下载对象时没校验实际接收的数据长度,客户端网络环境差时可能导致下载数据不全但不报错的异常问题 [`6aa0c12`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/6aa0c12527c7b05de78d4d3ee33e3e61cf2e9f1a)
- [合规重试]高级接口请求支持重试策略 [`3f6afa8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/3f6afa8f5a0516f3a199f904fb2f2d86f2c3473f)
- [合规重试]添加重试相关配置和工具类 [`38c1383`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/38c138322baf31e242a4b4d9216219393b63ffd9)
- MultiPutObject opt continue [`4205a57`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4205a578c1c20cb10a771687a6892e3a1d833d82)
- 修改智研代码检查问题 [`81e57ab`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/81e57ab02eb2432642034fed4220f9c75e8c238f)
- Updated CHANGELOG.md [`3efcdf2`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/3efcdf231fb0bc1f4e2abde0558446340935490b)
- 修复异步上传或下载对象回调函数进度可能超过100%的问题 [`24266a4`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/24266a42389b0673d2eb10716656bf22aa5a7c77)
- open USE_OPENSSL_MD5 for ut [`890ad7b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/890ad7b5d302a6338fa9896a16c4b35b49fd3815)
- fix:门禁回填 [`a01fc07`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a01fc0755536fe46290a07e36756cad2c47d4137)
## [v5.5.18](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.17...v5.5.18) - 2025-05-29
## What's Changed
* fix cpp-lint error by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/178
* adapt strict signature by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/180
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.17...v5.5.18
### Merged
- adapt strict signature [`#180`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/180)
- fix cpp-lint error [`#178`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/178)
### Commits
- continue... [`58e0bf3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/58e0bf3259459e54d3f622d10354e0ad87be67c6)
- 修复静态检查问题 [`c57e1df`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c57e1df81f1f02974f71d7c8df62142870337be5)
- continue... [`0b91af6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0b91af6a4aeb87061433f7a635aefcc607551492)
- dev/strict-sign [`9d267b9`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/9d267b921b067bb4226f403c351c590237dd3ce2)
- continue... [`732a796`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/732a7962ac365b49f3aae02607b58cd84870a1bb)
- continue... [`77674a3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/77674a3eff977e9a63e7d3ba1a2b5bcfad387a58)
- add ut case [`39473a9`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/39473a91f897118677c9ed5d4a53716562d709fe)
- continue... [`62f75cf`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/62f75cf9a147849015875406f2fae9846c9d25e8)
- continue... [`42ed716`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/42ed7164155180ffa1021d24048abf2c07c80e68)
- fix ut case [`acdf829`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/acdf829ab8df23c8b7bdbd9cacf9d6ee69a04713)
- Updated CHANGELOG.md [`d742653`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/d74265338f60e61f9fcdda5cdb25a90d766b0c17)
- fix ut case... [`51dc50a`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/51dc50a6dab833bf19959226a79212e2d38de212)
- fix ut case... [`114d1cd`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/114d1cd33a4cdf53cd4834b8b54872121127db0b)
- continue... [`65505df`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/65505df5e97b8ebd6ee4a1b2152b612407ee7332)
- continue... [`b4d2922`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b4d2922fc34b36328b2216abb1626c44b385a352)
- fix ut case... [`19f440e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/19f440e8a4762668421b928c06d15fc7b7c6913c)
- fix ut case... [`f5be9ae`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/f5be9ae54d413469477fb545862cbec87099cbea)
- continue... [`03a018b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/03a018b8399e631abc7005a285ea1cbb1934b420)
- fix ut case... [`e397d60`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e397d60748dea98cd16744a8dbd049cda59f1843)
- fix ut case... [`ba5e869`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ba5e8695c3478a06e714d34f1906a8c0bf86096d)
## [v5.5.17](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.15...v5.5.17) - 2025-01-21
## What's Changed
* 新增单线程断点上传接口 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/173
* 签名header 优化 by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/174
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.15...v5.5.17
### Merged
- 修改版本号 [`#175`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/175)
- x-ci*的header签入签名 [`#174`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/174)
- 新增单线程断点上传接口 [`#173`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/173)
### Commits
- 新增单线程断点接口 [`6d18e3b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/6d18e3ba101823ff86590c6d33ec616d71d128ae)
- ut [`e8e642e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e8e642ec223c3c7b6c05da45203236f19e6b4752)
- Updated CHANGELOG.md [`fcd7941`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/fcd7941669b173a9d0162a3eab034428989ac286)
## [v5.5.15](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.14...v5.5.15) - 2024-12-09
## What's Changed
* 双向认证 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/169
* demo 优化 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/170
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.14...v5.5.15
### Merged
- demo 优化 [`#170`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/170)
- Feature huberyxxiao 42e1ad74 [`#169`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/169)
### Commits
- demofix [`e3b547d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e3b547d0552765fa157d4fe7b8b39f7e3a7dabee)
- 双向认证 [`4299cc4`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4299cc42c077f98e858e464085f21ac8317e09ed)
- fix [`9432469`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/94324697633c0047f80f7c6594503c6effb4b214)
- Updated CHANGELOG.md [`b8266fa`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b8266fa3e5c7559e191e79372f5379e0de417154)
- test [`24730f1`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/24730f1a2b4c7258b9ad075a07d80caa453d827f)
- demo fix [`c991e09`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c991e099d082bbdc5169ed2e2e764e164b8e6bd2)
- fix [`802f4a9`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/802f4a91d1a9f04c85579937a12382a3e001af07)
## [v5.5.14](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.13...v5.5.14) - 2024-09-23
demo 优化;
优化 chunk 类接口响应解析 body
## What's Changed
* 优化 demo优化 chunk 类接口响应解析 body by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/166
* Feature huberyxxiao 9134bc9d by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/167
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.13...v5.5.14
### Merged
- demo 优化 [`#167`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/167)
- 优化 demo优化 chunk 类接口响应解析 body [`#166`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/166)
### Commits
- object 相关 demo 优化Complete&Copy 增加body 解析etag 判断请求正常逻辑 [`ef18673`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ef18673dc1506a0e83bef3f767a6e3a5aa647a22)
- 安全优化 [`46c61c2`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/46c61c2c46c7f436501c7161527b6ea7a16897de)
- add demo [`255f97f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/255f97f488b3729484fb66cfbc2bf3d3f66b523b)
- Updated CHANGELOG.md [`4ed035c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4ed035c042a838642daea5a289dc51a8e80795b5)
## [v5.5.13](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.12...v5.5.13) - 2024-07-16
## What's Changed
* 修复qt环境下encode问题 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/165
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.12...v5.5.13
### Merged
- 修复qt环境下encode问题 [`#165`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/165)
- 提交 [`#164`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/164)
### Commits
- fix demo [`acdf5c3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/acdf5c33a60ecbb56ffe8faa4a6c9ced9abe17db)
- 单测补充 [`7cfdb27`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7cfdb27f2b504ec1c263bee8a1d71ed807df4a0b)
- 代码规范 [`acc53fa`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/acc53fa98c19eb2fafa24aee35c0089d75b333e3)
- 安全问题修复 [`58bb1a6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/58bb1a62fa99fac327f12ea37babbde023f2e374)
- ut [`1ef653b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1ef653b4cfa8271bf5f10494089dc9da0d5d2f43)
- ut [`1b54654`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1b54654a6f22c088f65f7ba3350489b1dbd51b17)
- ut [`d2e6d13`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/d2e6d13031e9341a770b342d49543d870221ef62)
- ut [`9e2fe3f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/9e2fe3f2346763558dfa46935fa367fc8922e0a2)
- 单测补充 [`9f0802a`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/9f0802af8d12c2b7284ed5ee5b53269f436b6bea)
- 万象单测 [`37dd168`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/37dd16811fe299c6bc78984ab3fd169f7351fd29)
- ut [`17d4ba8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/17d4ba8597b90a05619a6c289053d49ee87b4630)
- ut [`e7cbd69`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e7cbd699722dfafa76f3ab28b8084da6fc4f5fd1)
- 单测补充 [`11227ee`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/11227eec0bd0a8853fca8676827c71cbc34e6317)
- ut [`bc1db72`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/bc1db7274851ee9226d687daad42fcb28b7d17dd)
- ut [`2d7d4bb`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/2d7d4bbf99bb99b8bfd7ccb5901f1b3a92a7bf28)
- ut [`fce627f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/fce627f2d57c9faf2d6a9c75fa4287b3567b01ee)
- 单测补充 [`2f4db4b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/2f4db4b47f9be883cc1fa25575fc403033ade8a9)
- Updated CHANGELOG.md [`8fc05d4`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8fc05d40f64cff3c296092ba633fd52185ba1f32)
- ut [`bda2b42`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/bda2b428dcc0932977a31f6e8f3cc8bc091e8d98)
- ut [`241adae`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/241adaee10ae7987fbc41b40dacc7540c88e7673)
## [v5.5.12](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.11...v5.5.12) - 2024-07-08
## What's Changed
* 批量图片审核增加 timeout 参数&图片处理参数头部签名 by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/160
* 安全优化 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/161
* 修复安全问题 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/163
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.11...v5.5.12
### Merged
- 修复安全问题 [`#163`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/163)
- 安全优化 [`#161`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/161)
- 批量图片审核增加 timeout 参数&图片处理参数头部签名 [`#160`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/160)
### Commits
- Updated CHANGELOG.md [`e178f03`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e178f030ecc413381a77997986cad05cc5710084)
## [v5.5.11](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.10...v5.5.11) - 2024-04-12
## What's Changed
* Feature huberyxxiao by @tencentyuncos in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/136
* Feature huberyxxiao 73b21a23 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/137
* Feature wqingzhang 07b4400f by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/139
* input增加url参数&Jobdetails部分参数补齐 by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/140
* 数据万象媒体处理&内容审核相关功能补齐 by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/142
* Feature huberyxxiao dbbe8ae4 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/146
* Feature huberyxxiao 29593a27 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/147
* 图片处理Pic-Operations头签入签名 by @wqingzhang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/149
* Feature huberyxxiao 144d3000 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/151
* 复合上传复用https支持 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/153
* Feature huberyxxiao 58acd2e4 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/154
* fix by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/156
* Feature huberyxxiao b3b34cad by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/157
* Feature huberyxxiao 024bd8e2 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/158
## New Contributors
* @tencentyuncos made their first contribution in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/136
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.10...v5.5.11
### Merged
- Feature huberyxxiao 024bd8e2 [`#158`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/158)
- Feature huberyxxiao b3b34cad [`#157`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/157)
- fix [`#156`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/156)
- Feature huberyxxiao 58acd2e4 [`#154`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/154)
- 复合上传复用https支持 [`#153`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/153)
- Feature huberyxxiao 144d3000 [`#151`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/151)
- 图片处理Pic-Operations头签入签名 [`#149`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/149)
- Feature huberyxxiao 29593a27 [`#147`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/147)
- Feature huberyxxiao dbbe8ae4 [`#146`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/146)
- 数据万象媒体处理&内容审核相关功能补齐 [`#142`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/142)
- input增加url参数&Jobdetails部分参数补齐 [`#140`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/140)
- Feature wqingzhang 07b4400f [`#139`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/139)
- Feature huberyxxiao 73b21a23 [`#137`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/137)
- Feature huberyxxiao [`#136`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/136)
### Commits
- 媒体处理任务补充&审核字段更新 [`a8f6e0e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a8f6e0e945e7788265864bba6454e5a5f0f72597)
- add ut [`248546b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/248546b9c2cb1929f20a493d9401dab1fc33aff6)
- upload [`36e5ffd`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/36e5ffd161e763ecc449b8898a9de970aac56aca)
- add ut [`c0fac35`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c0fac35cac5329f9eadf35179fcbe68f966eb54b)
- 媒体处理 截图任务 [`7846c94`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7846c94339063a6ae2ed225487c82596246c204c)
- 单元测试 [`9975c2b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/9975c2b88ace3abc21cb4a19a8c143c817053cce)
- add ut [`cf3ab93`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/cf3ab93d4ff49cffdb9e5c199bccb58cef9c41b0)
- 文件压缩任务 [`61d9ecf`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/61d9ecf923a03e54e7d9c7c4afc3e62624e5e0c2)
- add object tagging interface [`60a7f40`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/60a7f401a9263449d8ca53d2bd1b41cbf8badda4)
- add ut;fix test_utils [`fc7b40b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/fc7b40b98f90e44d76fd4df8d0457370b972e9ca)
- 万象单元测试 [`6ab7321`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/6ab73211eaa44d98ac5968b542dcd53e47b4e018)
- 支持异步断点下载;支持多AZ存储桶创建;支持存储桶策略接口;优化签名列表 [`1603c0c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1603c0c142a301e894b5755216cdde1d24c04a4f)
- 万象ut覆盖率补充 [`5f19f0c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/5f19f0cdba470ebece5c17074178b85ea623e368)
- 媒体处理&内容审核参数补齐 [`8772d33`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8772d337abe0910d2d160f717873c9965b64db65)
- 万象单元测试覆盖 [`662d8e9`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/662d8e9c446fd7509d2644048b3cbe378b1b0db2)
- Async [`0a9a3b5`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0a9a3b511f62ac72f3482c83e3ba6fc6a7997ce9)
- 单元测试 [`8972b59`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8972b591939baa5a815fc552e0d9edb0cc4b828d)
- 单元测试 [`e36f1cc`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e36f1cce020114cca6cb2baf119e3e6769f2d4d9)
- 文件压缩接口 [`fd9f95b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/fd9f95bb18835e51397b578c3124f89664e9a812)
- add ut [`ff68eb6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ff68eb6c888f023c4bb0a60a1ec9319f2c58eb8d)
## [v5.5.10](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.9...v5.5.10) - 2023-03-07
## What's Changed
* ut match stage 1 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/125
* fix: 主程序结束早于异步任务导致的crash by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/128
* 增加允许不签Host的接口&IsDomainSameToHost支持按实例单独配置 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/130
* fix:修复PutObjectByStream接口 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/131
* remove unnecessary sdk release library by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/132
* 修复lcov数据不准确问题 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/133
* 修正lcov提取路径 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/134
## New Contributors
* @Huberyxiao made their first contribution in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/128
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.9...v5.5.10
### Merged
- 修正lcov提取路径 [`#134`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/134)
- 修复lcov数据不准确问题 [`#133`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/133)
- remove unnecessary sdk release library [`#132`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/132)
- fix:修复PutObjectByStream接口 [`#131`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/131)
- 增加允许不签Host的接口&IsDomainSameToHost支持按实例单独配置 [`#130`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/130)
- fix: 主程序结束早于异步任务导致的crash [`#128`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/128)
- ut match stage 1 [`#125`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/125)
### Commits
- 增加允许不签Host的接口 [`7f87180`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7f8718097a9efcc9b8dfa7a22f20632dfac0ebb3)
- IsDomainSameToHost支持按实例单独配置 [`072ff3d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/072ff3d1d53fbd2daec34690f0cb5ac13956d527)
- Updated CHANGELOG.md [`4c0c85d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4c0c85d69534abbcfc79b3bae30231a2e2f433fc)
- Updated CHANGELOG.md [`4dced4b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4dced4b8242bda3a193165235bf111559421c5a4)
- fix:PutObjectByStream [`e1ea968`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e1ea9685c73677763d765fa5cf92ed271e3b7250)
## [v5.5.9](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.8...v5.5.9) - 2022-11-24
## What's Changed
* async upload sstream by @maddoxwang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/117
* support android&ios mobile by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/118
* etag不匹配时增加body长度信息与requestid by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/121
* 增加SetVerifyCert函数支持配置不校验服务端证书(默认校验) by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/122
## New Contributors
* @maddoxwang made their first contribution in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/117
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.8...v5.5.9
### Merged
- 增加SetVerifyCert函数支持配置不校验服务端证书(默认校验) [`#122`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/122)
- etag不匹配时增加body长度信息与requestid [`#121`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/121)
- support android&ios mobile [`#118`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/118)
- 内存数据异步上传接口实现&线程池线程数设置 [`#117`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/117)
### Commits
- Updated CHANGELOG.md [`c7da7c0`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c7da7c08e51660883ed062bea16db7776628a8db)
## [v5.5.8](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.7...v5.5.8) - 2022-07-28
## What's Changed
* DestDomain支持按实例单独配置 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/115
* fixed macos compile error by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/116
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.7...v5.5.8
### Merged
- fixed macos compile error [`#116`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/116)
- DestDomain支持按实例单独配置 [`#115`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/115)
### Commits
- Updated CHANGELOG.md [`1aab4b6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1aab4b6cc707c865330e58a6c9487ac12c718b25)
## [v5.5.7](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.6...v5.5.7) - 2022-07-20
## What's Changed
* ip访问模式支持按实例级别单独配置 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/114
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.6...v5.5.7
### Merged
- ip访问模式支持按实例级别单独配置 [`#114`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/114)
### Commits
- ip访问模式支持按实例级别单独配置(没有主动设置ip模式则兼容之前的ip配置全局共享方式) [`d6d7d3e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/d6d7d3e0c6fa6a3763f8fdb260fecbe1f341770a)
- Updated CHANGELOG.md [`eaf0941`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/eaf0941162a26acc20a440404460e84832cc772e)
- 解决用SetDestDomain设置域名后生成预签名url(GeneratePresignedUrl)异常的问题 [`56cb3f2`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/56cb3f26f876543cd7699422855b32542e0a7e1c)
## [v5.5.6](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.5...v5.5.6) - 2022-07-07
## What's Changed
* 允许独立配置IntranetAddr by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/109
* update version to v5.5.6 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/111
**Full Changelog**: https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.5...v5.5.6
### Merged
- update version to v5.5.6 [`#111`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/111)
- 允许独立配置IntranetAddr [`#109`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/109)
### Commits
- Updated CHANGELOG.md [`b27ddb3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b27ddb3805ad4985406aa707b4d3d9d1ec3ed43d)
## [v5.5.5](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.4...v5.5.5) - 2022-06-20
增加URISyntaxException异常信息处理
### Merged
- 增加URISyntaxException异常信息处理 [`#108`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/108)
- CI Auditing [`#106`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/106)
- CI auditing [`#1`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/1)
- 图片上传时处理兼容覆盖原图不检查Etag [`#105`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/105)
### Commits
- auditing fix [`a04c6f6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a04c6f607b7762b9ba813b74ba5105453a2e5239)
- auditing api [`e5df62b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e5df62b830fa7a96416748020d8fd3dcdf72d0cd)
- update [`7f5f02e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7f5f02e486f7f3ada7cc2427be013a7a6aeed8f4)
- ci auditing api [`c6446fd`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c6446fda8dd5c7d1198da97edc3f848f49db0854)
- 图片上传时处理若覆盖原图则不检查Etag [`1b6a7d7`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1b6a7d7c4d576be9dde45d54d9daab2211df2948)
- Updated CHANGELOG.md [`8276a1e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8276a1ee728d75ee068dd3d1b149823e8b0ff03c)
- fix [`5b28a85`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/5b28a856f74400b5f31613b052cdd9074423e619)
## [v5.5.4](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.2...v5.5.4) - 2022-04-14
1.完善aysnc api
2.完善async api UT测试
3.增加稳定性测试工具
### Merged
- Dev/async api [`#103`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/103)
### Commits
- 1.optimize async api 2.add stable test tool [`19a52ae`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/19a52ae311f5fd3ab0bca2f713e655ec64f1da77)
- optimize async api [`8ced1ae`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8ced1ae32ab286ac69adcfe35934fa20d44b3508)
- Updated CHANGELOG.md [`1106925`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1106925ecbc401c3c9099c0a748c3ea97f510acd)
## [v5.5.2](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.1...v5.5.2) - 2022-02-15
optimize async api
### Merged
- fix bug [`#101`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/101)
- fix compile bug [`#99`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/99)
- optimize async api [`#97`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/97)
- update demo [`#95`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/95)
- Optimize ii [`#94`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/94)
### Commits
- 1.check validation of secret_id/secret_key/region [`c28447a`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c28447abd002964fd51a45b98b3643daba402ca1)
- Updated CHANGELOG.md [`0af840b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0af840bacdf2c1e295e4b4ed01de8ad0dea4a92f)
- Updated CHANGELOG.md [`4fbbe5b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4fbbe5b97703264a5dad4259049f57df3b37365a)
- update doc [`5339a9c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/5339a9c62b45fb5bf61a3159dd957b50c7cd972a)
## [v5.5.1](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.0...v5.5.1) - 2021-12-01
1.add new api
2.check crc64 for multipart uploading
3.support uploading wide-char files for windows
4.optimize UT
### Merged
- Win widechar [`#93`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/93)
- check crc64 [`#92`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/92)
- fix bug [`#91`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/91)
- update makefile [`#90`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/90)
- 1.add referer api [`#89`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/89)
- add media api [`#85`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/85)
- 1.add append object [`#84`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/84)
- fix scripts bug [`#83`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/83)
- optimize tool [`#82`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/82)
- Fixes #79 [`#81`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/81)
- Fixed a crash caused by vector out-of-bound [`#80`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/80)
- fix multipart upload bug [`#76`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/76)
- fix bug [`#73`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/73)
### Fixed
- Merge pull request #81 from unity-cn/poco-global-fix [`#79`](https://github.com/tencentyun/cos-cpp-sdk-v5/issues/79)
### Commits
- 1.support upload widechar file for windows [`29ef003`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/29ef0039b58d1adf41dd96724a96b71fb475d151)
- optimize UT [`90ddc5b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/90ddc5b05c525769d6433592838615f31d03aa1f)
- fixed crash caused by static initialization order [`a7d7fc8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a7d7fc8996f4ec8b6972056c5d9eb4ad012cb76f)
- use function static variable for lazy-initialization [`8f26de2`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/8f26de217d895a7ca3693fc059be4e8349565315)
- Updated CHANGELOG.md [`7d472c8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7d472c83b764a395dfc5927a28865661a8677807)
- Update cos_demo.cpp [`053789d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/053789d6b37b53016e53c0420ba0afc197f90c89)
- Update Readme.txt [`b053805`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b053805092e61ac3586e54da5969fa4ffd31c4b5)
- Update README.md [`b43d1a8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b43d1a8cf7f6f56b3afc003ee5610eb7ad0da9f8)
- Update cos_defines.h [`433d95b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/433d95b76f7dabce99e91840a704eae9a7dd3c56)
- out-of-bound fix [`0afb5ff`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0afb5ff5ba3d37cc4711e2289d4b95ffbaa49455)
- Update README.md [`e5fc9a8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e5fc9a88897b3a2e1fdb4e7a2591530c6586a91e)
## [v5.5.0](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/5.4.5...v5.5.0) - 2021-07-16
1.更新版本号为5.5.0
2.不再单独维护windows_dev分支多个系统Linux/Windows/macOS等都使用master分支
3.增加logcallback功能特别在Windows系统下可以设置日志回调打印日志到自定义日志文件
4.优化日志,日志中打印上传下载速率,方便问题定位
5.优化Makefile多个系统共用同一套Makefile支持Linux/Windows/macOS系统增加编译选项可以支持编译动态库/编译demo/编译unittest
6.优化UT
7.去掉不必要的库依赖例如JsoncppOpenSSLboost等目前只依赖Poco库并把相关头文件以及库文件添加到工程目录中不需要再另行下载依赖库
8.tools目录中增加测速工具方便问题定位
9.libs目录中添加已编译好的库文件包括Linux/Win32/Win64/macOS等不同版本不需要编译代码即可使用sdk
### Merged
- v5.5.0 [`#72`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/72)
- fix bug [`#71`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/71)
- Sdk v5 optimize [`#70`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/70)
- fix multidownload bug [`#68`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/68)
- add get object url [`#67`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/67)
- add timestamp delta [`#61`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/61)
- add linux lib [`#60`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/60)
- add intelligent tiering [`#59`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/59)
### Commits
- 1.更新版本号为5.5.0 [`578bdbb`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/578bdbb352abb5d1d499857115b9a56577493437)
- 1.support CI 2.add async api 3.other optimize [`aabac6f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/aabac6f6c63a3ed34e5a562c3e7c5445166ae102)
- update doc api [`521b06b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/521b06bc8e6af2878f9b6d532a0b99cb9d18b9ee)
- update resumable get object [`ca75b4b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ca75b4b86dcaf38e767d273a20b0922f07375646)
- fix bugs [`1ab3269`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1ab326960b6c1eef01ed3c6d195c862c7cd0d1a7)
- Updated CHANGELOG.md [`0439cd7`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0439cd752fdde37f8d118b44314c62aa323dccb9)
- fix multidown bug [`344058f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/344058f49c1e143394f67e8e31125e7ecd4034db)
- fix async api bug [`b867d96`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b867d9692838dbdafb9c1669d0ebdd3f93ab2dee)
- update version to v5.4.6 [`acbae66`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/acbae6632e884b99a8850defc02fbd94737ef781)
- Delete libcossdk_for_linux.a [`c44071f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c44071f0890af3d85bb9624dc6df2326a755a868)
## [5.4.5](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/5.4.4...5.4.5) - 2021-02-25
1.add cos live api
2.support resume upload
### Merged
- add lib [`#57`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/57)
- support resume upload [`#56`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/56)
- add cos live [`#54`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/54)
- 响应头中找不到ETag则尝试查找Etag [`#52`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/52)
### Commits
- suppurt resume upload [`fc4a15f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/fc4a15ff658c17ab702d6520ef70d08568d4d164)
- Updated CHANGELOG.md [`1fbc8fd`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1fbc8fd24afe40c187b3649b60634ad3a6c749f3)
- add auto changelog workflow [`b87abb4`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b87abb4330ef42fc14794e6226de173694bc8933)
- Delete libcossdk.a [`ffdcf88`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ffdcf88f47d08b2a8dfe2afa314ae1384ecc44ce)
- add libcossdk.a [`a58e74f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a58e74f230722e1827baa469572cb3d1c7c74eed)
## [5.4.4](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.4.3...5.4.4) - 2020-07-13
1.add feature traffic-limit
2.add api select object content
3.other code optimize
4.fix some bugs
### Merged
- new version 5.4.4 [`#47`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/47)
- fix bug [`#46`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/46)
- add api select object content [`#45`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/45)
- Object options [`#44`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/44)
- Traffic limit [`#43`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/43)
- fix [`#42`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/42)
- LGTM [`#41`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/41)
- fix bug [`#40`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/40)
- fix [`#39`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/39)
- add the domainintentoryloggingwebsite and tagging API for bucket operation. [`#36`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/36)
- Add the control of whether domain same to host [`#31`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/31)
- Add the dest domain through the config file [`#30`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/30)
- Add the uint64_t header for lower compile [`#29`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/29)
- Check the get object resp content length with real recv, 200 but fail case. [`#28`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/28)
- Add list multi upload parts interface [`#22`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/22)
- Fix the check md5 casue the empty file problem(poco's streambuf issue). [`#21`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/21)
- Check delete object params [`#20`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/20)
- Add the SetXCosMeta in multiupload, send the config to init upload part. [`#19`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/19)
- add check md5 for each request, fix the range request check error [`#18`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/18)
- Add SetCredentail to set tmp ak, sk, token and fix bugs [`#14`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/14)
- fix bugs for mul compile [`#13`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/13)
- 添加HeadBucket接口修复BUG [`#12`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/12)
- Add put object md5 check and ut [`#11`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/11)
- string自动填充\0修复原string中末尾两个\0的问题 [`#9`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/9)
- 兼容s3 listparts return header EncodingType [`#8`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/8)
- result id to resp [`#7`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/7)
### Commits
- update [`abc6cfe`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/abc6cfeded4ca70b42982365df388094202b971d)
- 1.add feature traffic-limit; 2.optimize unittest; 3.using lib PocoJson to parse config [`b0db880`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b0db8806057a47d3e589f7b9e1c14f376893263c)
- 1.add api OptionsObject 2.add more signature header [`ab07ba4`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ab07ba4f8b7b03679c4735f6c2f92ff2d5165035)
- 1)use sharedptr to transfer config. 2)use the scpoed lock for the config [`bc71794`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/bc7179432c8763d5f7204d02e5161db89273c61d)
- add head bucket api and fix bugs [`88d8b95`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/88d8b95ccd4568ccabc35a69ab59f2ba335ab1fd)
- add put object md5 check and ut [`5d693cb`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/5d693cb008373e3a5cba11e9c8f6a996c424032a)
- Add the iostream copy istream from recevieResponse which Poco's streambuf can not relocate the pos then casue the recv_stream can not reuse [`e354859`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e3548592a61aed437b1640f029963e13c74bbe85)
- turn on/off md5 check [`ac0023e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ac0023e79bfc88ad028df67cb3603491077f7902)
- Check the resp content length with real recv, 200 but fail case. [`a5c50c3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a5c50c347db42a3d0e51c815bbf8bda598482b66)
- add the SetXCosMeta in multiupload send the config to init upload part [`d33a532`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/d33a532dc7a57ddfdd3c915c65b189293620019d)
- add mult xcosmeta [`1ac1af9`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1ac1af9915954af6825f9123edbdbd441a1b6a5c)
- update [`271108a`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/271108a064733a83184a9c32d6dd6e8d22b0024e)
- Add ut for deleteobject with empty param [`9005a6c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/9005a6c94ea9d7edaac2797ee85dd1f6020b448e)
- modify README.md [`6c6235a`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/6c6235ac757bc22388b580845c7fff2b9483c8a2)
- change & to copy [`f087902`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/f087902da6bc318ab5a6447bbf68e811caa7bb3b)
- use the err info check [`a7d7fb3`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a7d7fb31b466d28376ac3aa2ec7a2814d96981ab)
- fix name [`c91e03b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c91e03b72f247b8816653968999f0d4e3170df87)
- update [`6555620`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/655562079d7f44eb1a04e3235a7ce1da25c4c6b6)
- 兼容s3 listparts return header EncodingType [`ded884e`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ded884e1b5399b4204c22c04bc8e9577e3643229)
- test new branch [`7710f75`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7710f7543f4c421ae76bf7513543f180720fe5c1)
## v5.4.3 - 2018-05-28
### Merged
- add merge xml tool [`#5`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/5)
- fix parse deleteObjects bug [`#3`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/3)
- V4 [`#2`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/2)
- V2 [`#1`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/1)
### Commits
- cos-cpp-sdk-v5 first commit [`92b0b21`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/92b0b21198d1c3ae3eecfefee65ca03a9b000b06)
- add https and ut [`a9a29fc`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/a9a29fc7b0c27a0c2dc0b910bc04a403d89e0add)
- update poco [`1b26e3b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1b26e3b9c9f40b80d72bd134131790c3f793dece)
- add Poco header [`e11c33f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e11c33f8c22565d8f2838a0996714d223f3ede98)
- add cos-cpp-sdk.md and fix acl bug [`0d81ac8`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/0d81ac863798827ba8ac5c4b3484389008c7b7a2)
- V4 interface [`b772a89`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/b772a89f95a59b33af7afb290c3a77e509806e1c)
- 1. copy 2. fix parse xml bug 3. bucket-name [`c465cdc`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/c465cdc0f1e9e15f2b9e5906c00ef72405afd01b)
- add versioning and get service [`7db5353`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7db53533aa0b4716a8d7a0a5699292d558b774a0)
- add delete object [`6647acb`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/6647acbfe8370883cf47f197e13e1b4045f0b3b4)
- add unittest [`af6b257`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/af6b257977d82b90663301177fe6bcf60e0da1d8)
- 文档修改 [`4f5c951`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4f5c95137b07a60a8f3027899d924d6e5eba368e)
- SSE [`ec79580`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ec795805e1d3d66332ea186253a5520eed313f33)
- 多线程Copy [`48592f6`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/48592f6c6e9528fcae522c28be45a298cc6cffcd)
- add getbucketversions ut [`82bf59f`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/82bf59fb778c97723ba5130e42ea05aab99f8bd7)
- add v4 demo [`ba04316`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ba0431637a0b2fdf1c7b208d8f0c20ca57fa275c)
- remove nearline storage class [`d0ad816`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/d0ad816cdd4166f280a4a9a783b65dc806361203)
- DeleteObject 可以指定Versionn [`58a232c`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/58a232ccd6cbacd2085c799392e99c1a38a8fd26)
- 修复poco初始化多次异常 [`1a508df`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/1a508df4642dfebe4888f05f76dcefadd8deb086)
- fix SetObjectName bug [`ddef881`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/ddef881ac55898a344044bccea8eb710c5051fbf)
- fix post obj restore bug [`be5bfa0`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/be5bfa073d613c2f8bfa46c1d47b3e850821d12f)

104
CMakeLists.txt Normal file
View File

@@ -0,0 +1,104 @@
cmake_minimum_required(VERSION 2.8)
CMAKE_policy(SET CMP0015 NEW)
project(cos-cpp-sdk)
set(CMAKE_VERBOSE_MAKEFILE ON)
option(BUILD_UNITTEST "Build unittest" OFF)
option(BUILD_DEMO "Build demo" ON)
option(BUILD_SHARED_LIB "Build shared library" OFF)
option(ENABLE_COVERAGE "Enable Coverage" OFF)
option(USE_OPENSSL_MD5 "Use Openssl Md5" OFF)
if(APPLE)
set(OS_TYPE "APPLE")
elseif(UNIX)
set(OS_TYPE "LINUX")
elseif(WIN32)
set(OS_TYPE "WINDOWS")
else()
message(FATAL_ERROR "unkonwn os type")
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
set(OS_TYPE "Android")
message(STATUS "SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
set(OS_TYPE "iOS")
message(STATUS "SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
message(STATUS "OS type: ${OS_TYPE}")
set(POCO_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/include/)
set(POCO_LIBS PocoNetSSL PocoNet PocoCrypto PocoUtil PocoJSON PocoXML PocoFoundation)
if (${OS_TYPE} STREQUAL "WINDOWS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(BUILD_TARGET "Win32")
if (CMAKE_CL_64)
set(BUILD_TARGET "x64")
endif()
message(STATUS "Build target: ${BUILD_TARGET}")
if (NOT DEFINED ${CMAKE_BUILD_TYPE})
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/poco)
set(OPENSSL_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/openssl)
set(SYSTEM_LIBS "")
set(OPENSSL_LIBS libssl libcrypto)
#需要加该参数不然VS会报错
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
elseif(${OS_TYPE} STREQUAL "iOS")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/poco/)
set(OPENSSL_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/openssl/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra")
set(SYSTEM_LIBS stdc++ pthread)
set(OPENSSL_LIBS ssl crypto)
elseif(${OS_TYPE} STREQUAL "Android")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/poco/)
set(OPENSSL_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/openssl/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra")
set(SYSTEM_LIBS stdc++)
set(OPENSSL_LIBS ssl crypto)
# Linux or MacOs
else()
if (${OS_TYPE} STREQUAL "APPLE")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/macOS/poco/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra")
else()
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/linux/poco/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra")
endif()
set(SYSTEM_LIBS stdc++ pthread)
set(OPENSSL_LIBS ssl crypto)
endif()
if(ENABLE_COVERAGE)
# coverage option
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
add_subdirectory(src)
if(BUILD_UNITTEST)
message(STATUS "Build unittest")
set(GTEST_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/include/gtest/)
set(GTEST_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/linux/gtest/)
if (${OS_TYPE} STREQUAL "WINDOWS")
set(GTEST_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/gtest)
endif()
set(GTEST_LIBS gtest gtest_main)
set(UT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/unittest/include/)
add_subdirectory(unittest)
endif()
if(BUILD_DEMO)
message(STATUS "Build demo")
add_subdirectory(demo)
endif()

2280
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 腾讯云
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

592
README.md Normal file
View File

@@ -0,0 +1,592 @@
## 下载与安装
#### 编译选项
根目录下的CMakeLists.txt可以配置编译选项有如下编译选项
```shell
option(BUILD_UNITTEST "Build unittest" OFF) #配置编译单元测试
option(BUILD_DEMO "Build demo" ON) #配置编译demo测试代码
option(BUILD_SHARED_LIB "Build shared library" OFF) #配置编译动态库
```
#### 库依赖
依赖动态库poco、openssl。
#### SDK 需要自行基于源码重新编译
下载 [XML C++ SDK 源码](https://github.com/tencentyun/cos-cpp-sdk-v5)
> 使用时请将对应系统的库文件以及sdk include头文件拷贝至您的工程中。
third-party目录下有第三方依赖库
```shell
third_party/lib/linux/poco/ #linux下依赖的poco动态库
third_party/lib/Win32/openssl/ #Win32依赖的openssl库
third_party/lib/Win32/poco/ #Win32依赖的poco库
third_party/lib/x64/openssl/ #Win64依赖的openssl库
third_party/lib/x64/poco/ #Win64依赖的poco库
third_party/lib/macOS/poco/ #macOS依赖的poco库
```
> 使用时也请将对应系统的依赖库拷贝至您的工程中。
#### 编译 Linux 版本 SDK
#### 1. 安装编译工具及依赖库
```shell
yum install -y gcc gcc-c++ make cmake openssl
#cmake版本要求大于2.8
```
#### 2. 编译及安装 Poco 库
> Poco 版本推荐使用 1.9.4,当 OpenSSL 版本大于 1.0 版本时,推荐使用 1.12.4 版本。
```shell
# 下载 Poco 源码并解压
wget https://github.com/pocoproject/poco/archive/refs/tags/poco-${version}-release.zip
unzip poco-${version}-release.zip # 解压
# 进入 Poco 主目录并执行编译
cd poco-poco-${version}-release
./configure --omit=Data/MySQL,Data/ODBC
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release -j8
sudo cmake --build . --target install
```
> 上述命令执行完成后会将 Poco 动态库安装到 /usr/local/lib 目录中,所有头文件会被复制到 /usr/local/include/Poco 目录中,在生产环境使用时,请将库文件和头文件拷贝至您的工程中,保证程序能找到对应的动态库和头文件。
#### 3. 编译SDK
下载 [XML C++ SDK 源码](https://github.com/tencentyun/cos-cpp-sdk-v5) 到您的开发环境,并执行以下命令:
```shell
cd ${cos-cpp-sdk}
mkdir -p build
cd build
cmake .. -DBUILD_DEMO=OFF
make -j8
```
#### 4. 测试demo
如果不需要测试demo可跳过此步骤。
```shell
cd ${cos-cpp-sdk}
# 如果要编译 Demo, 接下来两个命令必须执行
cp -R /usr/local/include/Poco ./third_party/include/
cp /usr/local/lib/libPoco* ./third_party/lib/linux/poco/
vim demo/cos_demo.cpp #修改demo中的存储桶名以及测试代码
cd build && make #编译demo
ls bin/cos_demo #生成的可执行文件在bin目录
vim bin/config.json #修改密钥和园区
./bin/cos_demo #运行demon
# 编译 SDK
mkdir build
cd build
cmake ..
make -j8
ls bin/cos_demo #生成的可执行文件在bin目录
vim bin/config.json #修改密钥和园区
./bin/cos_demo #运行demon
```
#### 5. 使用SDK
编译生成的库文件在build/lib目录中静态库名称为`libcossdk.a` 动态库名称为`libcossdk-shared.so`。使用时请将库文件和 include 目录拷贝至您的工程中,同时参考第 4 步将依赖的 Poco 库文件和头文件复制到您的工程的对应目录中,使得 SDK 能找到这些文件include 路径下。
### 编译 Windows 版本 SDK
#### 1. 安装 visual studio 2017
安装 visual studio 2017 开发环境。
#### 2. 安装 CMake 工具
从 [CMake官网](https://cmake.org/download/) 下载 Windows 版本的 CMake 编译工具,并将 `${CMake的安装路径}\bin`,配置在 Windows 的系统环境变量 Path 中。
#### 3. 安装 OpenSSL
从 [OpenSSL官网](https://slproweb.com/products/Win32OpenSSL.html) 下载 Windows 版本的 OpenSSL并安装。
#### 4. 编译并安装 Poco
> Poco 版本推荐使用 1.9.4,当 OpenSSL 版本大于 1.0 版本时,推荐使用 1.12.4 版本。
```shell
# 下载 Poco 源码并解压
wget https://github.com/pocoproject/poco/archive/refs/tags/poco-${version}-release.zip
unzip poco-${version}-release.zip # 解压
# 进入 Poco 主目录并执行编译
cd poco-poco-${version}-release
./configure --omit=Data/MySQL,Data/ODBC
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release --target install -j8
```
> 编译成功后,会得到 Poco 的动态链接库和静态库,分别位于 cmake-build/bin 和 cmake-build/lib 中。执行 cmake .. 时可以通过指定 -DCMAKE_INSTALL_PREFIX=${自定义安装目录} 来设置安装目录,默认安装到 C:\Program Files (x86)\Poco 目录。
#### 5. 编译SDK
i. 下载 [XML C++ SDK 源码](https://github.com/tencentyun/cos-cpp-sdk-v5) 到您的开发环境。
ii. 打开 Windows 的命令行cd 到 C++ SDK 的源码目录下,执行命令
```shell
mkdir build
cd build
# cmake .. #生成 Win32 makefile
cmake -G "Visual Studio 15 2017 Win64" .. -DBUILD_DEMO=OFF # 生成 Win64 makefile, 不编译 demo
```
iii. 使用 visual studio 2017 打开解决方案,进行编译。
#### 6. 测试demo
> 如果不需要测试demo可跳过此步骤。
修改demo代码并编译生成的cos_demo.exe在bin目录中修改bin/config.json可运行cos_demo.exe。
```shell
# 复制 openssl 动态链接库和静态库到指定目录
cp ${OpenSSL安装目录}/bin/libcrypto-*.dll ${SDK目录}/third_party/lib/${target}/openssl/
cp ${OpenSSL安装目录}/bin/libssl-*.dll ${SDK目录}/third_party/lib/${target}/openssl/
cp ${OpenSSL安装目录}/lib/VC/${target}/MD/openssl.lib ${SDK目录}/third_party/lib/${target}/openssl/
cp ${OpenSSL安装目录}/lib/VC/${target}/MD/libssl.lib ${SDK目录}/third_party/lib/${target}/openssl/
cp ${OpenSSL安装目录}/lib/VC/${target}/MD/libcrypto.lib ${SDK目录}/third_party/lib/${target}/
# 复制 poco 的动态链接库和静态库到指定目录
cp ${Poco安装目录}/bin/Poco*.dll ${SDK目录}/third_party/lib/${target}/poco/
cp ${Poco安装目录}/lib/Poco*.lib ${SDK目录}/third_party/lib/${target}/poco/
# 复制相关头文件到指定文件
cp -R ${OpenSSL安装路径}/include/openssl ${SDK目录}/third_party/include/
cp -R ${Poco安装目录}/include/Poco ${SDK目录}/third_party/include/
# 开始编译
cd build
# cmake .. #生成 Win32 makefile
cmake -G "Visual Studio 15 2017 Win64" .. -DBUILD_DEMO=ON # 默认编译 demo—DBUILD_DEMO=ON 可以不指定
```
#### 5. 使用SDK
编译生成的库文件在build/Release目录中静态库名称为`cossdk.lib`。使用时请将库文件和 include 目录拷贝至您的工程中,同时参考第 6 步将依赖的 OpenSSL 和 Poco 库文件和头文件复制到您的工程的对应目录中,使得 SDK 能找到这些文件include 路径下。
### 编译 Mac 版本 SDK
#### 1. 安装编译工具及依赖库
```shell
brew install gcc make cmake openssl
```
#### 2. 编译并安装 Poco 库
> Poco 版本推荐使用 1.9.4,当 OpenSSL 版本大于 1.0 版本时,推荐使用 1.12.4 版本。
```shell
# 下载 Poco 源码并解压
wget https://github.com/pocoproject/poco/archive/refs/tags/poco-${version}-release.zip
unzip poco-${version}-release.zip # 解压
# 进入 Poco 主目录并执行编译
cd poco-poco-${version}-release
./configure --omit=Data/MySQL,Data/ODBC
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release -j8
sudo cmake --build . --target install
```
> 上述命令执行完成后会将 Poco 动态库安装到 /usr/local/lib 目录中,所有头文件会被复制到 /usr/local/include/Poco 目录中,在生产环境使用时,请将库文件和头文件拷贝至您的工程中,保证程序能找到对应的动态库和头文件。
#### 3. 编译SDK
下载 [XML C++ SDK 源码](https://github.com/tencentyun/cos-cpp-sdk-v5) 到您的开发环境,并执行以下命令:
```shell
cd ${cos-cpp-sdk}
mkdir -p build
cd build
cmake .. -DBUILD_DEMO=OFF # 不编译 demo
make
```
#### 4. 测试demo
如果不需要测试demo可跳过此步骤。
修改demo代码并编译生成的cos_demo在bin目录中修改bin/config.json可运行cos_demo。
```shell
# 复制 Poco 的动态链接库和静态库到指定目录
cp /usr/local/lib/libPoco* ${SDK目录}/third_party/lib/macOS/poco/
# 复制相关头文件到指定文件
cp -R /usr/local/include/Poco ${SDK目录}/third_party/include/
# 开始编译
cd build
cmake .. -DBUILD_DEMO=ON # 默认编译 demo—DBUILD_DEMO=ON 可以不指定
make -j8
```
#### 5. 使用SDK
编译生成的库文件在build/lib目录中静态库名称为`libcossdk.a` 动态库名称为`libcossdk-shared.dylib`。使用时请将库文件和 include 目录拷贝至您的工程中,同时参考第 4 步将依赖的 Poco 库文件和头文件复制到您的工程的对应目录中,使得 SDK 能找到这些文件include 路径下。
### 常见编译问题
1. 编译可执行程序的时候提示错误:
PocoCrypto.so.64: undefined reference to `PEM_write_bio_PrivateKey@libcrypto.so.10'
libPocoNetSSL.so.64: undefined reference to `X509_check_host@libcrypto.so.10'
ibPocoCrypto.so.64: undefined reference to `ECDSA_sign@OPENSSL_1.0.1_EC'
libPocoCrypto.so.64: undefined reference to `CRYPTO_set_id_callback@libcrypto.so.10'
ibPocoCrypto.so.64: undefined reference to `EVP_PKEY_id@libcrypto.so.10'
libPocoNetSSL.so.64: undefined reference to `SSL_get1_session@libssl.so.10'
libPocoNetSSL.so.64: undefined reference to `SSL_get_shutdown@libssl.so.10'
libPocoCrypto.so.64: undefined reference to `EVP_PKEY_set1_RSA@libcrypto.so.10'
libPocoCrypto.so.64: undefined reference to `SSL_load_error_strings@libssl.so.10'
这种情况一般是工程里自带的poco库的编译依赖的ssl版本与客户机器上的版本不一致导致的需要用户重新编译poco库并替换掉third_party里的poco库。
```shell
wget https://github.com/pocoproject/poco/archive/refs/tags/poco-1.9.4-release.zip
cd poco-poco-1.9.4-release/
./configure --omit=Data/ODBC,Data/MySQL
mkdir my_build
cd my_build
cmake ..
make -j5
```
2. 编译poco库的时候无法编译出PocoNetSSL库一般是因为机器没装openssl-devel库
```shell
yum install -y openssl-devel
```
3. 编译可执行程序的时候提示错误:
undefined reference to `qcloud_cos::CosConfig::CosConfig(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
这种情况一般是因为工程自带的libcossdk.a编译使用的gcc版本与客户机器上的gcc版本不一致导致的需要客户重新编译poco库和libcossdk。
## 开始使用
下面为您介绍如何使用 COS C++ SDK 完成一个基础操作,如初始化客户端、创建存储桶、查询存储桶列表、上传对象、查询对象列表、下载对象和删除对象。
>? 关于文章中出现的 SecretId、SecretKey、Bucket 等名称的含义和获取方式请参见 [COS 术语信息](https://cloud.tencent.com/document/product/436/7751#.E6.9C.AF.E8.AF.AD.E4.BF.A1.E6.81.AF)。
>
### 初始化
配置文件各字段介绍:
```
"SecretId":"********************************", // sercret_id替换为用户的 SecretId登录访问管理控制台查看密钥https://console.cloud.tencent.com/cam/capi
"SecretKey":"*******************************", // sercret_key替换为用户的 SecretKey登录访问管理控制台查看密钥https://console.cloud.tencent.com/cam/capi
"Region":"ap-guangzhou", // 存储桶地域, 替换为客户存储桶所在地域可以在COS控制台指定存储桶的概览页查看存储桶地域信息参考 https://console.cloud.tencent.com/cos5/bucket/ ,关于地域的详情见 https://cloud.tencent.com/document/product/436/6224
"SignExpiredTime":360, // 签名超时时间, 单位s
"ConnectTimeoutInms":6000, // connect超时时间, 单位ms
"ReceiveTimeoutInms":60000, // recv超时时间, 单位ms
"UploadPartSize":10485760, // 上传文件分片大小1M~5G, 默认为10M
"UploadCopyPartSize":20971520, // 上传复制文件分片大小5M~5G, 默认为20M
"UploadThreadPoolSize":5, // 单文件分块上传线程池大小
"DownloadSliceSize":4194304, // 下载文件分片大小
"DownloadThreadPoolSize":5, // 单文件下载线程池大小
"AsynThreadPoolSize":2, // 异步上传下载线程池大小
"LogoutType":1, // 日志输出类型,0:不输出,1:输出到屏幕,2输出到syslog
"LogLevel":3, // 日志级别:1: ERR, 2: WARN, 3:INFO, 4:DBG
"IsDomainSameToHost":false, // 是否使用专有的host
"DestDomain":"", // 特定host
"IsUseIntranet":false, // 是否使用特定ip和端口号
"IntranetAddr":"" // 特定ip和端口号,例如“127.0.0.1:80”
```
### 使用自定义域名访问 COS
在 config.json 中增加如下配置:
```cpp
"IsDomainSameToHost":true,
"DestDomain":"mydomain.com",
```
### 使用临时密钥访问 COS
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
qcloud_cos::CosConfig config("./config.json");
// 如果使用永久密钥不需要填入token如果使用临时密钥需要填入临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048
config.SetTmpToken("xxx");
qcloud_cos::CosAPI cos(config);
}
```
### 自定义Log回调
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
void TestLogCallback(const std::string& log) {
std::ofstream ofs;
ofs.open("test.log", std::ios_base::app);
ofs << log;
ofs.close();
}
int main(int argc, char** argv) {
qcloud_cos::CosConfig config("./config.json");
config.SetLogCallback(&TestLogCallback);
qcloud_cos::CosAPI cos(config);
}
```
### 创建存储桶
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造创建存储桶的请求
std::string bucket_name = "examplebucket-1250000000"; // Bucket名称
qcloud_cos::PutBucketReq req(bucket_name);
qcloud_cos::PutBucketResp resp;
// 3. 调用创建存储桶接口
qcloud_cos::CosResult result = cos.PutBucket(req, &resp);
// 4. 处理调用结果
if (result.IsSucc()) {
// 创建成功
} else {
// 创建存储桶失败,可以调用 CosResult 的成员函数输出错误信息,例如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```
### 查询存储桶列表
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造查询存储桶列表的请求
qcloud_cos::GetServiceReq req;
qcloud_cos::GetServiceResp resp;
qcloud_cos::CosResult result = cos.GetService(req, &resp);
// 3. 获取响应信息
const qcloud_cos::Owner& owner = resp.GetOwner();
const std::vector<qcloud_cos::Bucket>& buckets = resp.GetBuckets();
std::cout << "owner.m_id=" << owner.m_id << ", owner.display_name=" << owner.m_display_name << std::endl;
for (std::vector<qcloud_cos::Bucket>::const_iterator itr = buckets.begin(); itr != buckets.end(); ++itr) {
const qcloud_cos::Bucket& bucket = *itr;
std::cout << "Bucket name=" << bucket.m_name << ", location="
<< bucket.m_location << ", create_date=" << bucket.m_create_date << std::endl;
}
// 4. 处理调用结果
if (result.IsSucc()) {
// 查询存储桶列表成功
} else {
// 查询存储桶列表失败,可以调用 CosResult 的成员函数输出错误信息,比如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```
### 上传对象
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造上传文件的请求
std::string bucket_name = "examplebucket-1250000000"; // 上传的目的 Bucket 名称
std::string object_name = "exampleobject"; //exampleobject 即为对象键Key是对象在存储桶中的唯一标识。例如在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg。
// request 的构造函数中需要传入本地文件路径
qcloud_cos::PutObjectByFileReq req(bucket_name, object_name, "/path/to/local/file");
req.SetXCosStorageClass("STANDARD_IA") // 调用 Set 方法设置元数据等
qcloud_cos::PutObjectByFileResp resp;
// 3. 调用上传文件接口
qcloud_cos::CosResult result = cos.PutObject(req, &resp);
// 4. 处理调用结果
if (result.IsSucc()) {
// 上传文件成功
} else {
// 上传文件失败,可以调用 CosResult 的成员函数输出错误信息,比如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```
### 查询对象列表
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造查询对象列表的请求
std::string bucket_name = "examplebucket-1250000000"; // 上传的目标存储桶名称
qcloud_cos::GetBucketReq req(bucket_name);
qcloud_cos::GetBucketResp resp;
qcloud_cos::CosResult result = cos.GetBucket(req, &resp);
std::vector<qcloud_cos::Content> cotents = resp.GetContents();
for (std::vector<qcloud_cos::Content>::const_iterator itr = cotents.begin(); itr != cotents.end(); ++itr) {
const qcloud_cos::Content& content = *itr;
std::cout << "key name=" << content.m_key << ", lastmodified ="
<< content.m_last_modified << ", size=" << content.m_size << std::endl;
}
// 3. 处理调用结果
if (result.IsSucc()) {
// 查询对象列表成功
} else {
// 查询对象列表失败,可以调用 CosResult 的成员函数输出错误信息,例如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```
### 下载对象
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造下载对象的请求
std::string bucket_name = "examplebucket-1250000000"; // 上传的目的 Bucket 名称
std::string object_name = "exampleobject"; // exampleobject 即为对象键Key是对象在存储桶中的唯一标识。例如在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg。
std::string local_path = "/tmp/exampleobject";
// request 需要提供 appid、bucketname、object,以及本地的路径(包含文件名)
qcloud_cos::GetObjectByFileReq req(bucket_name, object_name, local_path);
qcloud_cos::GetObjectByFileResp resp;
// 3. 调用下载对象接口
qcloud_cos::CosResult result = cos.GetObject(req, &resp);
// 4. 处理调用结果
if (result.IsSucc()) {
// 下载文件成功
} else {
// 下载文件失败,可以调用 CosResult 的成员函数输出错误信息,例如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```
### 删除对象
```cpp
#include "cos_api.h"
#include "cos_sys_config.h"
#include "cos_defines.h"
int main(int argc, char *argv[]) {
// 1. 指定配置文件路径,初始化 CosConfig
qcloud_cos::CosConfig config("./config.json");
qcloud_cos::CosAPI cos(config);
// 2. 构造删除对象的请求
std::string bucket_name = "examplebucket-1250000000"; // 上传的目标存储桶名称
std::string object_name = "exampleobject"; // exampleobject 即为对象键Key是对象在存储桶中的唯一标识。例如在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg。
// 3. 调用删除对象接口
qcloud_cos::DeleteObjectReq req(bucket_name, object_name);
qcloud_cos::DeleteObjectResp resp;
qcloud_cos::CosResult result = cos.DeleteObject(req, &resp);
// 4. 处理调用结果
if (result.IsSucc()) {
// 删除对象成功
} else {
// 删除对象失败,可以调用 CosResult 的成员函数输出错误信息,例如 requestID 等
std::cout << "ErrorInfo=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
```

2514
cos-cpp-sdk.md Normal file

File diff suppressed because it is too large Load Diff

76
demo/CMakeLists.txt Normal file
View File

@@ -0,0 +1,76 @@
project(cos-demo)
if (NOT ${OS_TYPE} STREQUAL "WINDOWS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
endif()
file(GLOB cos_demo_src "${CMAKE_SOURCE_DIR}/demo/cos_demo.cpp")
file(GLOB put_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/put_object_demo.cpp")
file(GLOB get_object_url_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/get_object_url_demo.cpp")
file(GLOB head_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/head_object_demo.cpp")
file(GLOB get_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/get_object_demo.cpp")
file(GLOB delete_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/delete_object_demo.cpp")
file(GLOB put_get_object_acl_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/put_get_object_acl_demo.cpp")
file(GLOB put_get_delete_object_tagging_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/put_get_delete_object_tagging_demo.cpp")
file(GLOB restore_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/restore_object_demo.cpp")
file(GLOB copy_move_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/copy_move_object_demo.cpp")
file(GLOB multi_put_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/multi_put_object_demo.cpp")
file(GLOB multi_get_object_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/multi_get_object_demo.cpp")
file(GLOB select_objec_demo_src "${CMAKE_SOURCE_DIR}/demo/object_op_demo/select_objec_demo.cpp")
file(GLOB get_bucket_list_demo_src "${CMAKE_SOURCE_DIR}/demo/bucket_op_demo/get_bucket_list_demo.cpp")
file(GLOB delete_bucket_demo_src "${CMAKE_SOURCE_DIR}/demo/bucket_op_demo/delete_bucket_demo.cpp")
file(GLOB head_bucket_demo_src "${CMAKE_SOURCE_DIR}/demo/bucket_op_demo/head_bucket_demo.cpp")
file(GLOB put_bucket_demo_src "${CMAKE_SOURCE_DIR}/demo/bucket_op_demo/put_bucket_demo.cpp")
file(GLOB get_bucket_demo_src "${CMAKE_SOURCE_DIR}/demo/bucket_op_demo/get_bucket_demo.cpp")
link_directories(${POCO_LINK_DIR} ${OPENSSL_LINK_DIR}) #这一行要放到add_executable前面
add_executable(cos_demo ${cos_demo_src})
add_executable(put_object_demo ${put_object_demo_src})
add_executable(get_object_url_demo ${get_object_url_demo_src})
add_executable(head_object_demo ${head_object_demo_src})
add_executable(get_object_demo ${get_object_demo_src})
add_executable(delete_object_demo ${delete_object_demo_src})
add_executable(put_get_object_acl_demo ${put_get_object_acl_demo_src})
add_executable(put_get_delete_object_tagging_demo ${put_get_delete_object_tagging_demo_src})
add_executable(restore_object_demo ${restore_object_demo_src})
add_executable(copy_move_object_demo ${copy_move_object_demo_src})
add_executable(multi_put_object_demo ${multi_put_object_demo_src})
add_executable(multi_get_object_demo ${multi_get_object_demo_src})
add_executable(select_objec_demo ${select_objec_demo_src})
add_executable(get_bucket_list_demo ${get_bucket_list_demo_src})
add_executable(delete_bucket_demo ${delete_bucket_demo_src})
add_executable(head_bucket_demo ${head_bucket_demo_src})
add_executable(put_bucket_demo ${put_bucket_demo_src})
add_executable(get_bucket_demo ${get_bucket_demo_src})
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
target_link_libraries(cos_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(put_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(get_object_url_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(head_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(get_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(delete_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(put_get_object_acl_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(put_get_delete_object_tagging_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(restore_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(copy_move_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(multi_put_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(multi_get_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(select_objec_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(get_bucket_list_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(delete_bucket_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(head_bucket_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(put_bucket_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
target_link_libraries(get_bucket_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/include/ ${POCO_INCLUDE_DIR})
if(${OS_TYPE} STREQUAL "WINDOWS")
file(GLOB poco_libs "${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/poco/*")
file(GLOB ssl_libs "${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/openssl/*")
file(COPY ${poco_libs}
DESTINATION ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE})
file(COPY ${ssl_libs}
DESTINATION ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE})
endif()

View File

@@ -0,0 +1,73 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行存储桶的删除
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void DeleteBucket(qcloud_cos::CosAPI& cos) {
qcloud_cos::DeleteBucketReq req(bucket_name);
qcloud_cos::DeleteBucketResp resp;
qcloud_cos::CosResult result = cos.DeleteBucket(req, &resp);
std::cout << "===================DeleteBucketResponse====================="
<< std::endl;
PrintResult(result, resp);
std::cout << "========================================================="
<< std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
DeleteBucket(cos);
}

View File

@@ -0,0 +1,78 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行存储桶列表的获取
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void GetBucket(qcloud_cos::CosAPI& cos) {
qcloud_cos::GetBucketReq req(bucket_name);
qcloud_cos::GetBucketResp resp;
qcloud_cos::CosResult result = cos.GetBucket(req, &resp);
std::cout << "===================GetBucket=====================" << std::endl;
std::vector<qcloud_cos::Content> cotents = resp.GetContents();
for (std::vector<qcloud_cos::Content>::const_iterator itr = cotents.begin(); itr != cotents.end(); ++itr) {
const qcloud_cos::Content& content = *itr;
std::cout << "key name=" << content.m_key << ", lastmodified ="
<< content.m_last_modified << ", size=" << content.m_size << std::endl;
}
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
GetBucket(cos);
}

View File

@@ -0,0 +1,80 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行存储桶列表的获取
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void GetService(qcloud_cos::CosAPI& cos) {
qcloud_cos::GetServiceReq req;
qcloud_cos::GetServiceResp resp;
qcloud_cos::CosResult result = cos.GetService(req, &resp);
std::cout << "===================GetService====================="
<< std::endl;
PrintResult(result, resp);
const qcloud_cos::Owner& owner = resp.GetOwner();
const std::vector<qcloud_cos::Bucket>& buckets = resp.GetBuckets();
std::cout << "owner.m_id=" << owner.m_id << ", owner.display_name=" << owner.m_display_name << std::endl;
for (std::vector<qcloud_cos::Bucket>::const_iterator itr = buckets.begin();
itr != buckets.end(); ++itr) {
const qcloud_cos::Bucket& bucket = *itr;
std::cout << "Bucket name=" << bucket.m_name
<< ", location=" << bucket.m_location
<< ", create_date=" << bucket.m_create_date << std::endl;
}
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
GetService(cos);
}

View File

@@ -0,0 +1,84 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行存储桶检索和判断是否存在
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void HeadBucket(qcloud_cos::CosAPI& cos) {
qcloud_cos::HeadBucketReq req(bucket_name);
qcloud_cos::HeadBucketResp resp;
qcloud_cos::CosResult result = cos.HeadBucket(req, &resp);
std::cout << "===================HeadBucketResponse====================="
<< std::endl;
PrintResult(result, resp);
std::cout << "=========================================================="
<< std::endl;
}
void IsBucketExist(qcloud_cos::CosAPI& cos) {
std::cout << "===================IsBucketExist====================="
<< std::endl;
std::cout << (cos.IsBucketExist("abcdefg") ? "true" : "false") << std::endl;
std::cout << (cos.IsBucketExist(bucket_name) ? "true" : "false") << std::endl;
std::cout
<< "===================================================================="
<< std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
HeadBucket(cos);
IsBucketExist(cos);
}

View File

@@ -0,0 +1,85 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行存储桶的创建
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou@xxx";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void PutBucket(qcloud_cos::CosAPI& cos) {
qcloud_cos::PutBucketReq req(bucket_name);
//创建MAZ存储桶使用下方进行设置
//req.SetMAZBucket();
qcloud_cos::PutBucketResp resp;
qcloud_cos::CosResult result = cos.PutBucket(req, &resp);
std::cout << "===================PutBucketResponse====================="
<< std::endl;
PrintResult(result, resp);
std::cout << "========================================================="
<< std::endl;
}
int main() {
try{
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PutBucket(cos);
}
catch(const std::exception& e){
std::cerr << e.what() << "]]" << '\n';
std::cout << (strcmp(e.what(),"Invalid region configuration in CosConfig :ap-guangzhou@xxx") == 0) << std::endl;
}
std::cout << "Hello, World!" << std::endl;
}

20
demo/config.json Normal file
View File

@@ -0,0 +1,20 @@
{
"SecretId":"*****************************",
"SecretKey":"****************************",
"Region":"ap-guangzhou",
"SignExpiredTime":360,
"ConnectTimeoutInms":6000,
"ReceiveTimeoutInms":5000,
"AsynThreadPoolSize":2,
"UploadPartSize":10485760,
"UploadCopyPartSize":10485760,
"UploadThreadPoolSize":5,
"LogoutType":1,
"LogLevel":3,
"DownloadThreadPoolSize":5,
"DownloadSliceSize":4194304,
"IsDomainSameToHost":false,
"DestDomain":"",
"IsUseIntranet":false,
"IntranetAddr":""
}

4185
demo/cos_demo.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象的复制和移动
* 包括:桶内复制、高级对象复制、桶内移动、用户自行分块复制
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
/*
* 该 Demo 示范如何拷贝一个对象至当前 CosAPI 指定的存储桶中
* 最大支持拷贝不超过5GB的对象支持跨区域复制
*/
void PutObjectCopyDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test_dst.txt"; // 复制目标对象名称
std::string source = bucket_name + ".cos." + region + ".myqcloud.com/test.txt"; // 复制源对象
qcloud_cos::PutObjectCopyReq req(bucket_name, object_name);
req.SetXCosCopySource(source);
qcloud_cos::PutObjectCopyResp resp;
qcloud_cos::CosResult result = cos.PutObjectCopy(req, &resp);
std::cout << "===================PutObjectCopyResponse====================" << std::endl;
PrintResult(result, resp);
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范如何使用高级复制接口拷贝对象至当前 CosAPI 指定的存储桶中
* 该接口封装了简单拷贝和分块拷贝,根据文件大小智能的选择拷贝对象的方式
* 支持大对象,支持跨区域复制。推荐调用此接口
* 通过全局可以设置分块拷贝分块大小
*/
void CopyDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test_dst.txt"; // 复制后对象名称
std::string source = bucket_name + ".cos." + region + ".myqcloud.com/test_src.txt"; ; // 复制源对象
// 设置分块拷贝的分块大小默认20MB最大支持5GB最小支持1MB
// 此配置是全局性配置主动设置后后续初始化的所有CopyReq都使用此配置
CosSysConfig::SetUploadCopyPartSize(20 * 1024 * 1024);
qcloud_cos::CopyReq req(bucket_name, object_name);
qcloud_cos::CopyResp resp;
req.SetXCosCopySource(source);
qcloud_cos::CosResult result = cos.Copy(req, &resp);
std::cout << "===========================Copy=============================" << std::endl;
PrintResult(result, resp);
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范如何在当前CosAPI的存储桶中移动一个对象
* 支持大对象移动,但仅支持当前存储桶
* 如需要移动跨桶对象,请使用 PutObjectCopy 或 Copy 接口复制后删除原文件
*/
void MoveObjectDemo(qcloud_cos::CosAPI& cos) {
std::string src_object = "test_src.txt";
std::string dst_object = "test_dst.txt";
qcloud_cos::MoveObjectReq req(bucket_name, src_object, dst_object);
qcloud_cos::CosResult result = cos.MoveObject(req);
std::cout << "========================MoveObject==========================" << std::endl;
if (result.IsSucc()) {
std::cout << "MoveObject Succ." << std::endl;
} else {
std::cout << "MoveObject Fail, ErrorMsg: " << result.GetErrorMsg() << std::endl;
}
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范用户如何自行组合分块操作拷贝对象到目标存储桶
* 分块操作基于初始化、拷贝分块、完成分块三个接口实现将整个源对象切分为多个分块,然后再将这些分块拷贝到目标存储桶中
* 支持大对象,支持跨区域,其中每个分块最大支持 5GB最小支持 1MB最后一个分块可以小于 1MB
*/
void CopyPartDemo(qcloud_cos::CosAPI& cos) {
std::string dst_object = "test_dst.txt";
std::string source = bucket_name + ".cos." + region + ".myqcloud.com/test_src.txt"; // 复制源对象
// 1. InitMultiUpload
qcloud_cos::InitMultiUploadReq init_req(bucket_name, dst_object);
qcloud_cos::InitMultiUploadResp init_resp;
qcloud_cos::CosResult init_result = cos.InitMultiUpload(init_req, &init_resp);
std::cout << "=====================InitMultiUpload=====================" << std::endl;
PrintResult(init_result, init_resp);
std::cout << "=========================================================" << std::endl;
// 2. UploadPartCopyData
// UploadPartCopyData 部分,可以根据实际选择分块数量和每次分块的 range这里以 2 个分块为例
std::vector<std::string> etags;
std::vector<uint64_t> part_numbers;
std::string upload_id = init_resp.GetUploadId();
{
uint64_t part_number = 1;
qcloud_cos::UploadPartCopyDataReq req(bucket_name, dst_object, upload_id, part_number);
req.SetXCosCopySource(source);
req.SetXCosCopySourceRange("bytes=0-104857599"); // 可根据实际选择 range
qcloud_cos::UploadPartCopyDataResp resp;
qcloud_cos::CosResult result = cos.UploadPartCopyData(req, &resp);
std::cout << "==================UploadPartCopyDataResp1=====================" << std::endl;
PrintResult(result, resp);
std::cout << "==============================================================" << std::endl;
if (result.IsSucc()) {
part_numbers.push_back(1);
etags.push_back(resp.GetEtag());
}
}
{
uint64_t part_number = 2;
qcloud_cos::UploadPartCopyDataReq req(bucket_name, dst_object, upload_id, part_number);
req.SetXCosCopySource(source);
req.SetXCosCopySourceRange("bytes=104857600-209715199"); // 可根据实际选择 range
qcloud_cos::UploadPartCopyDataResp resp;
qcloud_cos::CosResult result = cos.UploadPartCopyData(req, &resp);
std::cout << "==================UploadPartCopyDataResp2=====================" << std::endl;
PrintResult(result, resp);
std::cout << "==============================================================" << std::endl;
if (result.IsSucc()) {
part_numbers.push_back(2);
etags.push_back(resp.GetEtag());
}
}
// 3. Complete
CompleteMultiUploadReq comp_req(bucket_name, dst_object, upload_id);
CompleteMultiUploadResp comp_resp;
comp_req.SetEtags(etags);
comp_req.SetPartNumbers(part_numbers);
qcloud_cos::CosResult result = cos.CompleteMultiUpload(comp_req, &comp_resp);
std::cout << "===================Complete=============================" << std::endl;
PrintResult(result, comp_resp);
std::cout << "========================================================" << std::endl;
return;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PutObjectCopyDemo(cos);
CopyDemo(cos);
MoveObjectDemo(cos);
CopyPartDemo(cos);
}

View File

@@ -0,0 +1,152 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行删除对象操作
* 包括:删除单个对象、删除指定多个对象、删除指定目录的所有对象、删除指定前缀的对象
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void DeleteObjectDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::DeleteObjectReq req(bucket_name, object_name);
// req.SetXCosVersionId("xxxxx");// 可以指定删除的版本
qcloud_cos::DeleteObjectResp resp;
qcloud_cos::CosResult result = cos.DeleteObject(req, &resp);
std::cout << "===================DeleteObjectResponse=====================" << std::endl;
PrintResult(result, resp);
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范如何批量删除对象
* 该方法是否成功需要判断resp.GetErrorMsgs()是否为空
*/
void DeleteObjectsDemo(qcloud_cos::CosAPI& cos) {
std::vector<ObjectVersionPair> to_be_deleted;
{
ObjectVersionPair pair;
std::string object_name = "test_dir/audio.mp3";
std::string version_id = ""; // 有需要可以指定删除的版本,如果为空则不指定
to_be_deleted.push_back(ObjectVersionPair(object_name, version_id));
}
{
std::string object_name = "test_dir/video.mp4";
std::string version_id = ""; // 有需要可以指定删除的版本,如果为空则不指定
to_be_deleted.push_back(ObjectVersionPair(object_name, version_id));
}
qcloud_cos::DeleteObjectsReq req(bucket_name, to_be_deleted);
// req.SetQuiet(); // 设置为 Quiet模式 则不返回删除成功的对象信息,默认为 Verbose 模式
qcloud_cos::DeleteObjectsResp resp;
qcloud_cos::CosResult result = cos.DeleteObjects(req, &resp);
std::cout << "===================DeleteObjectsResponse=====================" << std::endl;
std::vector<DeletedInfo> deleted_infos = resp.GetDeletedInfos(); // 单个删除成功的对象条目,仅当使用 Verbose 模式才会返回该元素
std::vector<ErrorInfo> error_infos = resp.GetErrorMsgs(); // 单个删除失败的对象条目
if (!error_infos.empty()) {
std::cout << "==================Failed part message==================" << std::endl;
for (ErrorInfo& error_info : error_infos) {
std::cout << "key: " << error_info.m_key << "\ncode: " << error_info.m_code << "\nmessage: " << error_info.m_message << std::endl;
std::cout << "====================================" << std::endl;
}
} else {
std::cout << "DeleteObjects All Succ." << std::endl;
}
std::cout << "=============================================================" << std::endl;
}
void DeleteDirectoryDemo(qcloud_cos::CosAPI& cos) {
std::string directory_name = "test_dir/"; // 目录名称,注意末尾需要有/
DeleteObjectsByPrefixReq req(bucket_name, directory_name);
DeleteObjectsByPrefixResp resp;
CosResult result = cos.DeleteObjects(req, &resp);
std::cout << "===================DeleteDirectory=====================" << std::endl;
if (result.IsSucc()) {
std::cout << "DeleteDirectory Succ." << std::endl;
} else {
std::cout << "DeleteDirectory Fail, ErrorMsg: " << result.GetErrorMsg() << std::endl;
}
std::cout << "Succ del objs:" << std::endl;
for (auto& obj : resp.m_succ_del_objs) {
std::cout << obj << std::endl;
}
std::cout << "=======================================================" << std::endl;
}
void DeleteObjectsByPrefixDemo(qcloud_cos::CosAPI& cos) {
std::string prefix = "test_dir"; // 指定前缀test_dir目录下的所有对象均会被删除且以test_dir开头的对象也会被删除
DeleteObjectsByPrefixReq req(bucket_name, prefix);
DeleteObjectsByPrefixResp resp;
CosResult result = cos.DeleteObjects(req, &resp);
std::cout << "===================DeleteObjectsByPrefix=====================" << std::endl;
if (result.IsSucc()) {
std::cout << "DeleteObjectsByPrefix Succ." << std::endl;
} else {
std::cout << "DeleteObjectsByPrefix Fail, ErrorMsg: "
<< result.GetErrorMsg() << std::endl;
}
std::cout << "Succ del objs:" << std::endl;
for (auto& obj : resp.m_succ_del_objs) {
std::cout << obj << std::endl;
}
std::cout << "=============================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
DeleteObjectDemo(cos);
DeleteObjectsDemo(cos);
DeleteDirectoryDemo(cos);
DeleteObjectsByPrefixDemo(cos);
}

View File

@@ -0,0 +1,167 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
#include <openssl/ssl.h>
/**
* 本样例演示了如何使用 COS C++ SDK 进行简单下载和列出
* 包括:下载到本地文件、下载到流、列出桶下的文件
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/**
* 本方法为 SSL_CTX 的回调方法,用户可以在此方法中配置 SSL_CTX 信息
*/
int SslCtxCallback(void *ssl_ctx, void *data) {
std::cout << "ssl_ctx: " << ssl_ctx << " data: " << data << std::endl;
SSL_CTX *ctx = (SSL_CTX *)ssl_ctx;
std::cout << "ssl_ctx in" << std::endl;
SSL_CTX_use_PrivateKey_file(ctx, "/data/cert/client.key", SSL_FILETYPE_PEM);
SSL_CTX_use_certificate_chain_file(ctx, "/data/cert/client.crt");
std::cout << "ssl_ctx out" << std::endl;
return 0;
}
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void GetObjectByFileDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test_src.txt";
std::string file_path = "./test_file/text2.txt";
qcloud_cos::GetObjectByFileReq req(bucket_name, object_name, file_path);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800
// uint64_t traffic_limit = 0;
// req.SetTrafficLimit(traffic_limit);
qcloud_cos::GetObjectByFileResp resp;
qcloud_cos::CosResult result = cos.GetObject(req, &resp);
std::cout << "===================GetObjectResponse=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
void GetObjectByStreamDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
std::ostringstream os;
qcloud_cos::GetObjectByStreamReq req(bucket_name, object_name, os);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800
// uint64_t traffic_limit = 0;
// req.SetTrafficLimit(traffic_limit);
qcloud_cos::GetObjectByStreamResp resp;
qcloud_cos::CosResult result = cos.GetObject(req, &resp);
std::cout << "===================GetObjectResponse=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
std::cout << os.str() << std::endl;
}
/**
* 使用 https 双向认证
*/
void GetObjectByStreamDemoWithMutualAuthentication(qcloud_cos::CosAPI& cos) {
std::string object_name = "index.html";
std::ostringstream os;
qcloud_cos::GetObjectByStreamReq req(bucket_name, object_name, os);
req.SetHttps();
req.SetSSLCtxCallback(SslCtxCallback, nullptr);
qcloud_cos::GetObjectByStreamResp resp;
qcloud_cos::CosResult result = cos.GetObject(req, &resp);
std::cout << "===================GetObjectResponse=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
std::cout << os.str() << std::endl;
}
void GetBucketDemo(qcloud_cos::CosAPI& cos) {
qcloud_cos::GetBucketReq req(bucket_name);
// 设置列出的对象名以 prefix 为前缀
req.SetPrefix("test");
// 设置最大列出多少个对象, 一次 listobject 最大支持1000
req.SetMaxKeys(10);
qcloud_cos::GetBucketResp resp;
qcloud_cos::CosResult result = cos.GetBucket(req, &resp);
std::cout << "===================GetBucketResponse=====================" << std::endl;
if (result.IsSucc()) {
// object contents 表示此次列出的对象列表
std::vector<Content> contents = resp.GetContents();
for (const Content& content : contents) {
// 对象的 key
std::string key = content.m_key;
// 对象的 etag
std::string etag = content.m_etag;
// 对象的长度
std::string file_size = content.m_size;
// 对象的存储类型
std::string storage_classes = content.m_storage_class;
std::cout << "key:" << key << "\netag:" << etag << "\nfile_size:" << file_size << "\nstorage_classes" << storage_classes << std::endl;
std::cout << "==================================" << std::endl;
}
if (resp.IsTruncated()) {
// 表示还没有列完,被截断了
// 下一次开始的位置
std::string next_marker = resp.GetNextMarker();
std::cout << "next_marker:" << next_marker << std::endl;
}
} else {
std::cout << "GetBucket Fail, ErrorMsg: " << result.GetErrorMsg() << std::endl;
}
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
GetObjectByFileDemo(cos);
GetObjectByStreamDemo(cos);
// GetObjectByStreamDemoWithMutualAuthentication(cos);
GetBucketDemo(cos);
}

View File

@@ -0,0 +1,86 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 获取对象链接
* 包括:预签名链接、对象访问 URL
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void GeneratePresignedUrlDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::GeneratePresignedUrlReq req(bucket_name, object_name, qcloud_cos::HTTP_GET); // 可设置请求方法
// 下方代码块可选则是否设置。默认签名生效的开始时间是本地当前时间,默认有效期 60s
{
req.SetHttps(); // 是否为 https
uint64_t start_time_in_s = time(NULL);
req.SetStartTimeInSec(start_time_in_s); // 设置签名生效的开始时间
req.SetExpiredTimeInSec(60); // 设置签名的有效期
}
std::string presigned_url = cos.GeneratePresignedUrl(req);
std::cout << "===================GeneratePresignedUrl=====================" << std::endl;
std::cout << "Presigend Url=[" << presigned_url << "]" << std::endl;
std::cout << "============================================================" << std::endl;
}
void GetObjectUrlDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
bool is_https = true; // 是否为 https
std::string object_url = cos.GetObjectUrl(bucket_name, object_name, is_https);
std::cout << "=======================GetObjectUrl=========================" << std::endl;
std::cout << "object url=[" << object_url << "]" << std::endl;
std::cout << "============================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
GeneratePresignedUrlDemo(cos);
GetObjectUrlDemo(cos);
}

View File

@@ -0,0 +1,82 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行 Head Object 相关操作
* 包括Head Object、判断对象是否存在
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void IsObjectExistDemo(qcloud_cos::CosAPI& cos) {
bool is_exist = cos.IsObjectExist(bucket_name, "test.txt");
std::cout << "=====================IsObjectExist=======================" << std::endl;
std::cout << (is_exist ? "true" : "false") << std::endl;
std::cout << "=========================================================" << std::endl;
}
void HeadObjectDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::HeadObjectReq req(bucket_name, object_name);
qcloud_cos::HeadObjectResp resp;
qcloud_cos::CosResult result = cos.HeadObject(req, &resp);
std::cout << "===================HeadObjectResponse=====================" << std::endl;
std::map<std::string, std::string> cos_metas = resp.GetXCosMetas(); // 获取自定义的元数据map
std::string cos_meta = resp.GetXCosMeta("x-cos-meta-*"); // 获取指定自定义的元数据
std::string restore = resp.GetXCosRestore(); // 获得 archive 类型对象的当前恢复状态
std::string sse = resp.GetXCosServerSideEncryption(); // Server端加密使用的算法
PrintResult(result, resp);
std::cout << "==========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
IsObjectExistDemo(cos);
HeadObjectDemo(cos);
}

View File

@@ -0,0 +1,273 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象的高级下载
* 包括:多线程下载、断点下载(多线程、支持断点)、异步多线程下载、异步断点下载、异步简单下载
* 均只支持下载到文件
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
/*
* 该 Demo 示范如何使用多线程下载接口下载对象
* 仅支持下载到文件,利用了分 range 多线程同时下载的方式下载对象
* 可通过全局设置下载线程池大小、range 大小。该线程池是每次上传独立的
*/
void MultiGetObjectDemo(qcloud_cos::CosAPI& cos) {
std::string file_path = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
// 此配置是全局性配置,主动设置后,后续涉及多线程下载的接口,都使用此配置
CosSysConfig::SetDownThreadPoolSize(10); // 下载线程池大小 默认10
CosSysConfig::SetDownSliceSize(4 * 1024 * 1024); // 下载 range 大小 默认4M
qcloud_cos::MultiGetObjectReq req(bucket_name, object_name, file_path);
qcloud_cos::MultiGetObjectResp resp;
qcloud_cos::CosResult result = cos.MultiGetObject(req, &resp);
std::cout << "===================GetObjectResponse=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
/*
* 该 Demo 示范如何使用断点下载接口下载对象
* 仅支持下载到文件,利用了分 range 多线程同时下载的方式下载对象,支持断点下载
* 可通过全局设置下载线程池大小、range 大小。该线程池是每次上传独立的。
*/
void ResumableGetObjectDemo(qcloud_cos::CosAPI& cos) {
std::string file_path = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
qcloud_cos::GetObjectByFileReq req(bucket_name, object_name, file_path);
qcloud_cos::GetObjectByFileResp resp;
CosResult result = cos.ResumableGetObject(req, &resp);
std::cout << "===================ResumableGetObject====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
/*
* 该方法是异步下载对象的进度回调示例
*/
void ProgressCallback(uint64_t transferred_size, uint64_t total_size, void* user_data) {
qcloud_cos::ObjectReq* req = static_cast<qcloud_cos::ObjectReq*>(user_data);
if (0 == transferred_size % 1048576) {
std::cout << "ObjectName:" << req->GetObjectName() << ", TranferedSize:" << transferred_size << ",TotalSize:" << total_size << std::endl;
}
}
/*
* 该方法是异步下载对象的完成回调示例
*/
void GetObjectAsyncDoneCallback(const SharedAsyncContext& context, void* user_data) {
UNUSED_PARAM(user_data)
std::cout << "MultiGetObjectAsyncDoneCallback, BucketName:"
<< context->GetBucketName()
<< ", ObjectName:" << context->GetObjectName()
<< ", LocalFile:" << context->GetLocalFilePath() << std::endl;
// qcloud_cos::MultiGetObjectReq对应的响应为qcloud_cos::GetObjectByFileResp
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncMultiGetObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncMultiGetObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
}
/*
* 该 Demo 示范如何通过异步多线程接口下载对象
* 仅支持下载到文件,利用了分 range 多线程同时下载的方式下载对象
* 可通过全局设置异步线程池大小、下载线程池大小、range 大小
* 注意异步线程池是全局共用的供所有的异步调用使用。下载线程池、range 大小与所有多线程类型下载接口共用配置
* 例如调用两次异步接口,则两个异步操作会使用异步线程池进行调度。而每个异步操作中,可能会调用多线程相关接口创建出供本次使用的下载线程池,从而并发下载对象。
* 支持下载进度回调和下载状态回调
*/
void AsyncMultiGetObjectDemo(qcloud_cos::CosAPI& cos) {
CosSysConfig::SetAsynThreadPoolSize(2); // 设置异步线程池大小 默认2
std::string local_file = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
qcloud_cos::AsyncMultiGetObjectReq req(bucket_name, object_name, local_file);
// 设置下载进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置下载状态回调
req.SetDoneCallback(&GetObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始下载
SharedAsyncContext context = cos.AsyncMultiGetObject(req);
std::cout << "===================AsyncMultiGetObject======================" << std::endl;
// 等待下载结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// context->WaitUntilFinish()阻塞完毕的逻辑是:异步线程在下载时文件落盘完毕。
// 此时您的主线程如果立即结束异步线程可能正在进行资源释放、结束线程等过程。此时可能会产生crash。
// 此问题并不会对文件的下载造成影响,仅仅是体验上可能会出现意料之外的崩溃信息。
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncMultiGetObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncMultiGetObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范如何通过异步断点下载接口下载对象
* 仅支持下载到文件,利用了分 range 多线程同时下载的方式下载对象,支持断点下载
* 可通过全局设置异步线程池大小、下载线程池大小、range 大小。
* 注意异步线程池是全局共用的供所有的异步调用使用。下载线程池、range 大小与所有多线程类型下载接口共用配置
* 例如调用两次异步接口,则两个异步操作会使用异步线程池进行调度。而每个异步操作中,可能会调用多线程相关接口创建出供本次使用的下载线程池,从而并发下载对象。
* 支持下载进度回调和下载状态回调
*/
void AsyncResumableGetObjectDemo(qcloud_cos::CosAPI& cos) {
std::string local_file = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
qcloud_cos::AsyncGetObjectReq req(bucket_name, object_name, local_file);
// 设置下载进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置下载状态回调
req.SetDoneCallback(&GetObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始下载
SharedAsyncContext context = cos.AsyncResumableGetObject(req);
std::cout << "===================AsyncResumableGetObject======================" << std::endl;
// 等待下载结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// context->WaitUntilFinish()阻塞完毕的逻辑是:异步线程在下载时文件落盘完毕。
// 此时您的主线程如果立即结束异步线程可能正在进行资源释放、结束线程等过程。此时可能会产生crash。
// 此问题并不会对文件的下载造成影响,仅仅是体验上可能会出现意料之外的崩溃信息。
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncResumableGetObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncResumableGetObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "================================================================" << std::endl;
}
/*
* 该 Demo 示范如何通过异步简单接口下载对象
* 仅支持下载到文件
* 可通过全局设置异步线程池大小
* 注意:异步线程池是全局共用的,供异步调用使用
* 例如调用两次异步接口,则两个异步操作会使用异步线程池进行调度
* 支持下载进度回调和下载状态回调
*/
void AsyncGetObjectDemo(qcloud_cos::CosAPI& cos) {
std::string local_file = "test_file/text.txt";
std::string object_name = "text.txt";
qcloud_cos::AsyncGetObjectReq req(bucket_name, object_name, local_file);
req.SetRecvTimeoutInms(1000 * 60);
// 设置下载进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置下载状态回调
req.SetDoneCallback(&GetObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始下载
SharedAsyncContext context = cos.AsyncGetObject(req);
std::cout << "===================AsyncGetObject======================" << std::endl;
// 等待下载结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// context->WaitUntilFinish()阻塞完毕的逻辑是:异步线程在下载时文件落盘完毕。
// 此时您的主线程如果立即结束异步线程可能正在进行资源释放、结束线程等过程。此时可能会产生crash。
// 此问题并不会对文件的下载造成影响,仅仅是体验上可能会出现意料之外的崩溃信息。
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncGetObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncGetObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "=======================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
MultiGetObjectDemo(cos);
ResumableGetObjectDemo(cos);
AsyncMultiGetObjectDemo(cos);
AsyncResumableGetObjectDemo(cos);
AsyncGetObjectDemo(cos);
}

View File

@@ -0,0 +1,439 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
// #include <openssl/ssl.h> // 双向认证引用头
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象的高级上传
* 包括:高级上传接口(多线程、支持断点续传功能)、异步高级上传接口、异步简单上传接口(流&文件)、分块上传(用户自行调用初始化、上传、完成分块接口)
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
// config.SetDestDomain("xxx.xxxx.com"); // 配置自定义域名
// config.SetDomainSameToHost(true); // 配置自定义域名签名
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
/**
* 本方法为 SSL_CTX 的回调方法,用户可以在此方法中配置 SSL_CTX 信息
*/
// int SslCtxCallback(void *ssl_ctx, void *data) {
// std::cout << "ssl_ctx: " << ssl_ctx << " data: " << data << std::endl;
// SSL_CTX *ctx = (SSL_CTX *)ssl_ctx;
// std::cout << "ssl_ctx in" << std::endl;
// SSL_CTX_use_PrivateKey_file(ctx, "/data/cert/client.key", SSL_FILETYPE_PEM);
// SSL_CTX_use_certificate_chain_file(ctx, "/data/cert/client.crt");
// std::cout << "ssl_ctx out" << std::endl;
// return 0;
// }
/*
* 该 Demo 示范如何使用高级上传接口进行对象上传
* 仅支持文件上传,不支持流式上传,封装了分块上传的各接口
* 可通过全局设置上传线程池大小、分块大小。该上传线程池是每次上传独立的。
*/
void MultiUploadObjectDemo(qcloud_cos::CosAPI& cos) {
std::string local_file = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
// 此配置是全局性配置,主动设置后,后续的高级上传,都使用此配置
CosSysConfig::SetUploadThreadPoolSize(5); // 上传线程池大小 默认5
CosSysConfig::SetUploadPartSize(10 * 1024 * 1024); // 上传分块大小 默认10M
qcloud_cos::MultiPutObjectReq req(bucket_name, object_name, local_file);
// req.SetHttps(); // 设置 https 请求
// req.SetSSLCtxCallback(SslCtxCallback, nullptr); //双向认证回调
qcloud_cos::MultiPutObjectResp resp;
qcloud_cos::CosResult result = cos.MultiPutObject(req, &resp);
std::cout << "===================MultiUploadObject=======================" << std::endl;
if (result.IsSucc()) {
std::cout << "MultiUpload Succ." << std::endl;
std::cout << resp.GetLocation() << std::endl;
std::cout << resp.GetKey() << std::endl;
std::cout << resp.GetBucket() << std::endl;
std::cout << resp.GetEtag() << std::endl;
} else {
std::cout << "MultiUpload Fail." << std::endl;
// 获取具体失败在哪一步
std::string resp_tag = resp.GetRespTag();
if ("Init" == resp_tag) {
// print result
} else if ("Upload" == resp_tag) {
// print result
} else if ("Complete" == resp_tag) {
// print result
}
PrintResult(result, resp);
}
std::cout << "===========================================================" << std::endl;
}
/*
* 该方法是异步上传对象的进度回调示例
*/
void ProgressCallback(uint64_t transferred_size, uint64_t total_size, void* user_data) {
qcloud_cos::ObjectReq* req = static_cast<qcloud_cos::ObjectReq*>(user_data);
if (0 == transferred_size % 1048576) {
std::cout << "ObjectName:" << req->GetObjectName() << ", TranferedSize:" << transferred_size << ",TotalSize:" << total_size << std::endl;
}
}
/*
* 该方法是异步上传对象的完成回调示例
*/
void PutObjectAsyncDoneCallback(const SharedAsyncContext& context, void* user_data) {
UNUSED_PARAM(user_data)
std::cout << "PutObjectAsyncDoneCallback, BucketName:" << context->GetBucketName() << ", ObjectName:" << context->GetObjectName() << ", LocalFile:" << context->GetLocalFilePath() << std::endl;
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncMultiPutObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
// std::cout << "Location:" << resp.GetLocation() << std::endl;
// std::cout << "Bucket:" << resp.GetBucket() << std::endl;
// std::cout << "Key:" << resp.GetKey() << std::endl;
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncMultiGetObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
}
/*
* 该 Demo 示范如何通过异步高级上传对象进行对象上传
* 仅支持文件上传,不支持流式上传,封装了分块上传的各接口、
* 可通过全局设置异步线程池大小、上传线程池大小、分块大小
* 注意:异步线程池是全局共用的,供异步调用使用。上传线程池、分块大小是和高级接口共用配置
* 例如调用两次异步接口,则两个异步操作会使用异步线程池进行调度。而每个异步操作会调用高级接口创建出供本次使用的上传线程池,从而并发上传对象。
* 支持上传进度回调和上传状态回调
*/
void AsyncMultiPutObjectDemo(qcloud_cos::CosAPI& cos) {
std::string local_file = "test_file/big_file.txt";
std::string object_name = "big_file.txt";
qcloud_cos::AsyncMultiPutObjectReq req(bucket_name, object_name, local_file);
req.SetRecvTimeoutInms(1000 * 60);
// 设置上传进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置上传状态回调
req.SetDoneCallback(&PutObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始上传
SharedAsyncContext context = cos.AsyncMultiPutObject(req);
std::cout << "===================AsyncMultiPutObject======================" << std::endl;
// 等待上传结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncMultiPutObject succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
// std::cout << "Location:" << resp.GetLocation() << std::endl;
// std::cout << "Bucket:" << resp.GetBucket() << std::endl;
// std::cout << "Key:" << resp.GetKey() << std::endl;
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncMultiPutObject failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "============================================================" << std::endl;
}
/*
* 该 Demo 示范如何通过异步普通接口上传对象
* 包括流和文件两种方式上传
* 可通过全局设置异步线程池大小
* 注意:异步线程池是全局共用的,供异步调用使用
* 例如调用两次异步接口,则两个异步操作会使用异步线程池进行调度
* 支持上传进度回调和上传状态回调
*/
void AsyncPutObjectDemo(qcloud_cos::CosAPI& cos) {
// 流上传
{
std::string object_name = "text.txt";
std::istringstream iss("put object");
qcloud_cos::AsyncPutObjectByStreamReq req(bucket_name, object_name, iss);
req.SetRecvTimeoutInms(1000 * 60);
// 设置上传进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置上传状态回调
req.SetDoneCallback(&PutObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始上传
SharedAsyncContext context = cos.AsyncPutObject(req);
std::cout << "===================AsyncPutObjectByStream======================" << std::endl;
// 等待上传结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncPutObjectByStream succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
// std::cout << "Location:" << resp.GetLocation() << std::endl;
// std::cout << "Bucket:" << resp.GetBucket() << std::endl;
// std::cout << "Key:" << resp.GetKey() << std::endl;
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncPutObjectByStream failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "===============================================================" << std::endl;
}
// 文件上传
{
std::string local_file = "test_file/text.txt";
std::string object_name = "text.txt";
qcloud_cos::AsyncPutObjectReq req(bucket_name, object_name, local_file);
req.SetRecvTimeoutInms(1000 * 60);
// 设置上传进度回调
req.SetTransferProgressCallback(&ProgressCallback);
// 设置上传状态回调
req.SetDoneCallback(&PutObjectAsyncDoneCallback);
// 设置私有数据,对应回调中的 user_data
req.SetUserData(&req);
// 开始上传
SharedAsyncContext context = cos.AsyncPutObject(req);
std::cout << "===================AsyncPutObjectByFile======================" << std::endl;
// 等待上传结束
std::cout << "wait finish..." << std::endl;
context->WaitUntilFinish();
// 检查结果
if (context->GetResult().IsSucc()) {
// 获取响应
std::cout << "AsyncPutObjectByFile succeed" << std::endl;
std::cout << "Result:" << context->GetResult().DebugString() << std::endl;
AsyncResp resp = context->GetAsyncResp();
// std::cout << "Location:" << resp.GetLocation() << std::endl;
// std::cout << "Bucket:" << resp.GetBucket() << std::endl;
// std::cout << "Key:" << resp.GetKey() << std::endl;
std::cout << "ETag:" << resp.GetEtag() << std::endl;
std::cout << "Crc64:" << resp.GetXCosHashCrc64Ecma() << std::endl;
} else {
std::cout << "AsyncPutObjectByFile failed" << std::endl;
std::cout << "ErrorMsg:" << context->GetResult().GetErrorMsg() << std::endl;
}
std::cout << "=============================================================" << std::endl;
}
}
/*
* 该 Demo 示范用户如何自行组合分块上传各接口进行对象上传
* 分块操作基于初始化、上传分块、完成分块三个接口可以实现将对象切分为多个分块,然后再将这些分块上传到 cos最后发起 Complete 完成分块上传
* 本 Demo 中的上传分块接口 UploadPartData 仅支持传入流最多支持10000分块每个分块大小为1MB - 5GB最后一个分块可以小于1MB
*/
void PutPartDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "big_file.txt";
// 1. InitMultiUpload
qcloud_cos::InitMultiUploadReq init_req(bucket_name, object_name);
qcloud_cos::InitMultiUploadResp init_resp;
qcloud_cos::CosResult init_result = cos.InitMultiUpload(init_req, &init_resp);
std::cout << "=====================InitMultiUpload=====================" << std::endl;
PrintResult(init_result, init_resp);
std::cout << "=========================================================" << std::endl;
// 2. UploadPartData
// UploadPartData 部分,可以根据实际选择分块数量和分块大小,这里以 2 个分块为例
// Complete 需要的两个列表:
std::vector<std::string> etags;
std::vector<uint64_t> part_numbers;
std::string upload_id = init_resp.GetUploadId();
{
uint64_t part_number = 1;
// 模拟上传分块数据,这里以 100M 为例
uint64_t copy_size = 1024 * 1024 * 100;
std::vector<char> data(copy_size, 'A');
std::string content(data.begin(), data.end());
std::istringstream iss(content);
qcloud_cos::UploadPartDataReq req(bucket_name, object_name, upload_id, iss);
req.SetPartNumber(part_number);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800, 即800Kb/s-800Mb/s
uint64_t traffic_limit = 8192*1024*10; // 100MB 文件 5M
req.SetTrafficLimit(traffic_limit);
qcloud_cos::UploadPartDataResp resp;
std::chrono::time_point<std::chrono::steady_clock> start_ts, end_ts;
start_ts = std::chrono::steady_clock::now();
qcloud_cos::CosResult result = cos.UploadPartData(req, &resp);
end_ts = std::chrono::steady_clock::now();
auto time_consumed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(end_ts - start_ts)
.count();
float rate =
((float)copy_size / 1024 / 1024) / ((float)time_consumed_ms / 1000);
SDK_LOG_ERR("send part_number: %d, send_size: %" PRIu64 " MB, time_consumed: %" PRIu64
" ms, rate: %.2f MB/s , traffic_limit : %.2f MB", part_number, copy_size/ 1024 / 1024, time_consumed_ms, rate, traffic_limit/1024/1024/8.0);
std::cout << "==================UploadPartDataResp1=====================" << std::endl;
PrintResult(result, resp);
std::cout << "==========================================================" << std::endl;
if (result.IsSucc()) {
part_numbers.push_back(part_number);
etags.push_back(resp.GetEtag());
}
}
{
uint64_t part_number = 2;
uint64_t copy_size = 1024 * 1024 * 100;
std::vector<char> data(copy_size, 'A');
std::string content(data.begin(), data.end());
std::istringstream iss(content);
qcloud_cos::UploadPartDataReq req(bucket_name, object_name, upload_id, iss);
req.SetPartNumber(part_number);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800, 即800Kb/s-800Mb/s
uint64_t traffic_limit = 8192 * 1024 * 5 ;
req.SetTrafficLimit(traffic_limit);
qcloud_cos::UploadPartDataResp resp;
qcloud_cos::CosResult result = cos.UploadPartData(req, &resp);
std::cout << "==================UploadPartDataResp2=====================" << std::endl;
PrintResult(result, resp);
std::cout << "==========================================================" << std::endl;
if (result.IsSucc()) {
part_numbers.push_back(part_number);
etags.push_back(resp.GetEtag());
}
}
{
uint64_t part_number = 3;
uint64_t copy_size = 1024 * 1024 * 10;
std::vector<char> data(copy_size, 'A');
std::string content(data.begin(), data.end());
std::istringstream iss(content);
qcloud_cos::UploadPartDataReq req(bucket_name, object_name, upload_id, iss);
req.SetPartNumber(part_number);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800, 即800Kb/s-800Mb/s
uint64_t traffic_limit = 8192 * 1024;
req.SetTrafficLimit(traffic_limit);
qcloud_cos::UploadPartDataResp resp;
qcloud_cos::CosResult result = cos.UploadPartData(req, &resp);
std::cout << "==================UploadPartDataResp2=====================" << std::endl;
PrintResult(result, resp);
std::cout << "==========================================================" << std::endl;
if (result.IsSucc()) {
part_numbers.push_back(part_number);
etags.push_back(resp.GetEtag());
}
}
// 3. Complete
CompleteMultiUploadReq comp_req(bucket_name, object_name, upload_id);
CompleteMultiUploadResp comp_resp;
comp_req.SetEtags(etags);
comp_req.SetPartNumbers(part_numbers);
qcloud_cos::CosResult result = cos.CompleteMultiUpload(comp_req, &comp_resp);
std::cout << "===================Complete=============================" << std::endl;
PrintResult(result, comp_resp);
std::cout << "========================================================" << std::endl;
return;
}
void PutObjectResumableSingleThreadSyncDemo(qcloud_cos::CosAPI& cos) {
std::string local_file = "SingleThreadSync.txt";
std::string object_name = "SingleThreadSync.txt";
qcloud_cos::PutObjectResumableSingleSyncReq req(bucket_name, object_name, local_file);
req.AddHeader("x-cos-meta-ssss1","1xxxxxxx");
req.AddHeader("x-cos-meta-ssss2","2xxxxxxx");
req.AddHeader("x-cos-meta-ssss3","3xxxxxxx");
req.AddHeader("x-cos-meta-ssss4","4xxxxxxx");
uint64_t traffic_limit = 8192 * 1024;//1MB
req.SetTrafficLimit(traffic_limit);
//req.SetHttps();
//req.SetSSLCtxCallback(SslCtxCallback, nullptr);
qcloud_cos::PutObjectResumableSingleSyncResp resp;
qcloud_cos::CosResult result = cos.PutObjectResumableSingleThreadSync(req, &resp);
if (result.IsSucc()) {
std::cout << "MultiUpload Succ." << std::endl;
std::cout << resp.GetLocation() << std::endl;
std::cout << resp.GetKey() << std::endl;
std::cout << resp.GetBucket() << std::endl;
std::cout << resp.GetEtag() << std::endl;
} else {
std::cout << "MultiUpload Fail." << std::endl;
// 获取具体失败在哪一步
std::string resp_tag = resp.GetRespTag();
if ("Init" == resp_tag) {
// print result
} else if ("Upload" == resp_tag) {
// print result
} else if ("Complete" == resp_tag) {
// print result
}
PrintResult(result, resp);
}
std::cout << "===========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
MultiUploadObjectDemo(cos);
AsyncMultiPutObjectDemo(cos);
AsyncPutObjectDemo(cos);
PutPartDemo(cos);
PutObjectResumableSingleThreadSyncDemo(cos);
}

View File

@@ -0,0 +1,115 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象标签的设置、获取和删除
* 包括:设置标签、获取标签、删除标签
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
std::string uin = "23300000000";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void PutObjectTaggingDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::PutObjectTaggingReq req(bucket_name, object_name);
qcloud_cos::PutObjectTaggingResp resp;
std::vector<Tag> tagset;
Tag tag1;
tag1.SetKey("age");
tag1.SetValue("19");
Tag tag2;
tag2.SetKey("name");
tag2.SetValue("xiaoming");
Tag tag3;
tag3.SetKey("sex");
tag3.SetValue("male");
tagset.push_back(tag1);
tagset.push_back(tag2);
tagset.push_back(tag3);
req.SetTagSet(tagset);
qcloud_cos::CosResult result = cos.PutObjectTagging(req, &resp);
std::cout << "=========================PutBucketTagging===========================" << std::endl;
PrintResult(result, resp);
std::cout << "====================================================================" << std::endl;
}
void GetObjectTaggingDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::GetObjectTaggingReq req(bucket_name, object_name);
qcloud_cos::GetObjectTaggingResp resp;
qcloud_cos::CosResult result = cos.GetObjectTagging(req, &resp);
std::cout << "=========================GetObjectTagging===========================" << std::endl;
std::vector<Tag> tagset = resp.GetTagSet();
for (std::vector<Tag>::iterator it = tagset.begin(); it != tagset.end(); ++it) {
std::cout << it->GetKey() << ":" << it->GetValue() << std::endl;
}
PrintResult(result, resp);
std::cout << "====================================================================" << std::endl;
}
void DeleteObjectTaggingDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::DeleteObjectTaggingReq req(bucket_name, object_name);
qcloud_cos::DeleteObjectTaggingResp resp;
qcloud_cos::CosResult result = cos.DeleteObjectTagging(req, &resp);
std::cout << "=======================DeleteObjectTagging==========================" << std::endl;
PrintResult(result, resp);
std::cout << "====================================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PutObjectTaggingDemo(cos);
GetObjectTaggingDemo(cos);
DeleteObjectTaggingDemo(cos);
}

View File

@@ -0,0 +1,115 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象 ACL 的设置和获取
* 包括:通过 body 和 head 两种方式设置对象的 ACL、获取对象的 ACL
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
std::string uin = "23300000000";
std::string sub_uin = "23300000000";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
/*
* 该 Demo 示范如何上传对象的 ACL
* 本样例先通过 body 的方式为主账号持有的对象设置子账号 FULL_CONTROL 访问权限。再通过 head 的方式设置子账号 READ 访问权限
*/
void PutObjectACLDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
// 1 通过Body设置ACL配置 (设置ACL可以通过Body、Header两种方式但只能二选一否则会有冲突)
// ACL 请求构造参考 api 文档https://cloud.tencent.com/document/product/436/7748
{
qcloud_cos::PutObjectACLReq req(bucket_name, object_name);
qcloud_cos::Owner owner = {"qcs::cam::uin/" + uin + ":uin/" + uin,
"testacl"};
qcloud_cos::Grant grant;
req.SetOwner(owner);
grant.m_grantee.m_type = "CanonicalUser";
grant.m_grantee.m_id = "qcs::cam::uin/" + uin + ":uin/" + sub_uin;
grant.m_perm = "FULL_CONTROL";
req.AddAccessControlList(grant);// 可以加入多条grant
qcloud_cos::PutObjectACLResp resp;
qcloud_cos::CosResult result = cos.PutObjectACL(req, &resp);
std::cout << "===================PutObjectACLResponse======================" << std::endl;
PrintResult(result, resp);
std::cout << "=============================================================" << std::endl;
}
// 2 通过Header设置ACL配置
{
qcloud_cos::PutObjectACLReq req(bucket_name, object_name);
req.SetXCosAcl("default"); // 对应 api 中的 x-cos-acl
std::string grant_read = "id=\"" + uin + "/"+ sub_uin + "\"";
req.SetXCosGrantRead(grant_read); // 对应 api 中的 x-cos-grant-read
// std::string grant_full_control = "id=\"" + uin + "/"+ sub_uin + "/\"";
// req.SetXCosGrantFullControl(grant_full_control); // 对应 api 中的 x-cos-grant-full-control
qcloud_cos::PutObjectACLResp resp;
qcloud_cos::CosResult result = cos.PutObjectACL(req, &resp);
std::cout << "===================PutObjectACLResponse======================" << std::endl;
PrintResult(result, resp);
std::cout << "=============================================================" << std::endl;
}
}
void GetObjectACLDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::GetObjectACLReq req(bucket_name, object_name);
qcloud_cos::GetObjectACLResp resp;
qcloud_cos::CosResult result = cos.GetObjectACL(req, &resp);
std::cout << "======================GetObjectACLResponse========================" << std::endl;
PrintResult(result, resp);
std::cout << "==================================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PutObjectACLDemo(cos);
GetObjectACLDemo(cos);
}

View File

@@ -0,0 +1,129 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行简单上传和批量上传
* 包括:上传本地文件、上传流类型、上传目录类型、上传本地文件夹下的对象
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void PutObjectByFileDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
std::string file_path = "./test_file/text.txt";
qcloud_cos::PutObjectByFileReq req(bucket_name, object_name, file_path);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800
// uint64_t traffic_limit = 0;
// req.SetTrafficLimit(traffic_limit);
qcloud_cos::PutObjectByFileResp resp;
qcloud_cos::CosResult result = cos.PutObject(req, &resp);
std::cout << "====================PutObjectByFile======================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
void PutObjectByStreamDemo(qcloud_cos::CosAPI& cos) {
std::istringstream iss("put object");
std::string object_name = "text.txt";
qcloud_cos::PutObjectByStreamReq req(bucket_name, object_name, iss);
// 限速上传对象,默认单位为 bit/s限速值设置范围为 819200 - 838860800
// uint64_t traffic_limit = 0;
// req.SetTrafficLimit(traffic_limit);
qcloud_cos::PutObjectByStreamResp resp;
qcloud_cos::CosResult result = cos.PutObject(req, &resp);
std::cout << "===================PutObjectByStream=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
void PutDirectoryDemo(qcloud_cos::CosAPI& cos) {
std::string directory_name = "test_dir/"; // 目录名称,注意末尾需要有/
PutDirectoryReq req(bucket_name, directory_name);
PutDirectoryResp resp;
CosResult result = cos.PutDirectory(req, &resp);
std::cout << "=====================PutDirectory========================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
/*
* 该 Demo 示范如何上传本地文件夹到 cos
* 本示例会将本地 test_file 目录上传到 cos 的 test_dir下。
* 例如,本地当前路径的 test_file 目录下有 text1.txt 和 text2.txt 文件,上传后 cos 的路径为 test_dir/text1.txt 和 test_dir/text2.txt
*/
void PutObjectsFromDirectoryDemo(qcloud_cos::CosAPI& cos) {
std::string directory_name = "test_file"; // 目录名称,注意开头如果加./ 则上传后cos 的路径为 test_dir/test_file/text.txt
std::string cos_path = "test_dir/"; // 目录名称,注意末尾需要有/
PutObjectsByDirectoryReq req(bucket_name, directory_name);
req.SetCosPath(cos_path);
PutObjectsByDirectoryResp resp;
CosResult result = cos.PutObjects(req, &resp);
std::cout << "=====================PutDirectory========================" << std::endl;
if (result.IsSucc()) {
std::cout << "PutObjectsFromDirectory Succ." << std::endl;
for (auto& r : resp.m_succ_put_objs) {
std::cout << "file_name: " << r.m_file_name << "\nobject_name: " << r.m_object_name << "\nETag: " << r.m_cos_resp.GetEtag() << std::endl;
std::cout << "====================================" << std::endl;
}
} else {
std::cout << "PutObjectsFromDirectoryToCosPath Fail, ErrorMsg: "
<< result.GetErrorMsg() << std::endl;
}
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PutObjectByFileDemo(cos);
PutObjectByStreamDemo(cos);
PutDirectoryDemo(cos);
PutObjectsFromDirectoryDemo(cos);
}

View File

@@ -0,0 +1,71 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象的临时恢复操作
* 包括:恢复临时对象
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void PostObjectRestoreDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.txt";
qcloud_cos::PostObjectRestoreReq req(bucket_name, object_name); // 也可以传入第三个参数version_id
req.SetExiryDays(1);// 设置临时恢复的天数
qcloud_cos::PostObjectRestoreResp resp;
qcloud_cos::CosResult result = cos.PostObjectRestore(req, &resp);
std::cout << "===================PostObjectRestore=====================" << std::endl;
PrintResult(result, resp);
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
PostObjectRestoreDemo(cos);
}

View File

@@ -0,0 +1,77 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
/**
* 本样例演示了如何使用 COS C++ SDK 进行对象检索
* 包括:对象检索
*/
using namespace qcloud_cos;
uint64_t appid = 12500000000;
std::string tmp_secret_id = "AKIDXXXXXXXX";
std::string tmp_secret_key = "1A2Z3YYYYYYYYYY";
std::string region = "ap-guangzhou";
std::string bucket_name = "examplebucket-12500000000";
std::string tmp_token = "token";
/*
* 本方法包含调用是否正常的判断,和请求结果的输出
* 可通过本方法判断是否请求成功,并输出结果信息
*/
void PrintResult(const qcloud_cos::CosResult& result, const qcloud_cos::BaseResp& resp) {
if (result.IsSucc()) {
std::cout << "Request Succ." << std::endl;
std::cout << resp.DebugString() << std::endl;
} else {
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
}
}
/*
* 通过参数形式初始化 CosAPI 对象
*/
qcloud_cos::CosAPI InitCosAPI() {
qcloud_cos::CosConfig config(appid, tmp_secret_id, tmp_secret_key, region);
config.SetTmpToken(tmp_token); // 推荐使用临时密钥初始化 CosAPI 对象, 如果您使用永久密钥初始化 CosAPI 对象,请注释
qcloud_cos::CosAPI cos_tmp(config);
return cos_tmp;
}
void SelectObjectContentDemo(qcloud_cos::CosAPI& cos) {
std::string object_name = "test.csv.gz";
int input_file_type = CSV; // 待检索对象的格式为CSV或者JSON
int input_compress_type = COMPRESS_GZIP; // 压缩类型COMPRESS_NONE, COMPRESS_GZIP, COMPRESS_BZIP2
int out_file_type = CSV; // 输出格式为CSV或者JSON
qcloud_cos::SelectObjectContentReq req(bucket_name, object_name, input_file_type, input_compress_type, out_file_type);
req.SetSqlExpression("Select * from COSObject");
qcloud_cos::SelectObjectContentResp resp;
qcloud_cos::CosResult result = cos.SelectObjectContent(req, &resp);
std::cout << "=====================IsObjectExist=======================" << std::endl;
PrintResult(result, resp);
// 支持打印最终结果至终端或写入本地文件
// resp.WriteResultToLocalFile("file_name");
resp.PrintResult();
std::cout << "=========================================================" << std::endl;
}
int main() {
qcloud_cos::CosAPI cos = InitCosAPI();
CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR);
SelectObjectContentDemo(cos);
}

394
demo/stable_test.cpp Normal file
View File

@@ -0,0 +1,394 @@
// Copyright (c) 2022, Tencent Inc.
// All rights reserved.
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#include "cos_api.h"
#include "cos_sys_config.h"
#include "util/auth_tool.h"
#include "util/test_utils.h"
using namespace qcloud_cos;
static void PrintResult(const qcloud_cos::CosResult& result) {
std::stringstream oss;
oss << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
oss << "HttpStatus=" << result.GetHttpStatus() << std::endl;
oss << "ErrorCode=" << result.GetErrorCode() << std::endl;
oss << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
oss << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
oss << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
oss << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
SDK_LOG_INFO("%s", oss.str().c_str());
}
enum PutOpType { SIMPLE_PUT = 1, MULTI_PUT, ASYNC_PUT, ASYNC_MULTI_PUT };
enum GetOpType { SIMPLE_GET = 6, MULTI_GET, ASYNC_GET, ASYNC_MULTI_GET };
#define GENERATE_LOCAL_FILE(size) \
std::string object_name = "stable_test_size_" + std::to_string(size); \
std::string local_file = "./" + object_name; \
SDK_LOG_INFO("generate local file: %s", local_file.c_str()); \
TestUtils::WriteRandomDatatoFile(local_file, file_size); \
uint64_t file_crc64_origin = FileUtil::GetFileCrc64(local_file); \
std::string file_md5_origin = FileUtil::GetFileMd5(local_file); \
SDK_LOG_INFO("file_crc64_origin: %lu", file_crc64_origin); \
SDK_LOG_INFO("file_md5_origin: %s", file_md5_origin.c_str());
#define CHECK_COMMON_RESULT(result) \
assert(result.IsSucc()); \
assert(!result.GetXCosRequestId().empty()); \
assert(result.GetHttpStatus() >= 200 && result.GetHttpStatus() < 300);
#define CHECK_COMMON_RESP(resp) \
assert(resp.GetServer() == "tencent-cos"); \
assert(!resp.GetDate().empty()); \
assert(!resp.GetConnection().empty()); \
assert(!resp.GetXCosRequestId().empty());
#define CHECK_PUT_RESP(resp, op_type) \
assert(resp.GetXCosHashCrc64Ecma() == std::to_string(file_crc64_origin)); \
if (op_type == MULTI_PUT || op_type == ASYNC_MULTI_PUT) { \
assert(!resp.GetContentType().empty()); \
assert(resp.GetEtag() != file_md5_origin); \
} else { \
assert(resp.GetEtag() == file_md5_origin); \
}
#define CHECK_HEAD_RESP(resp) \
assert(resp.GetXCosHashCrc64Ecma() == std::to_string(file_crc64_origin)); \
assert(resp.GetContentLength() == file_size); \
assert(!resp.GetLastModified().empty());
#define CHECK_GET_RESP(resp, op_type) \
assert(resp.GetXCosHashCrc64Ecma() == std::to_string(file_crc64_origin)); \
assert(!resp.GetLastModified().empty()); \
std::string file_md5_download = TestUtils::CalcFileMd5(local_file_download); \
assert(file_md5_download == file_md5_origin); \
if (op_type == SIMPLE_GET || op_type == ASYNC_GET) { \
assert(resp.GetContentLength() == file_size); \
}
class TestStatistics {
public:
TestStatistics()
: put_object_succ(0),
put_object_fail(0),
multi_put_object_succ(0),
multi_put_object_fail(0),
async_put_object_succ(0),
async_put_object_fail(0),
async_multi_put_object_succ(0),
async_multi_put_object_fail(0),
get_object_succ(0),
get_object_fail(0),
multi_get_object_succ(0),
multi_get_object_fail(0),
async_get_object_succ(0),
async_get_object_fail(0),
async_multi_get_object_succ(0),
async_multi_get_object_fail(0),
head_object_succ(0),
head_object_fail(0),
delete_object_succ(0),
delete_object_fail(0) {}
int put_object_succ;
int put_object_fail;
int multi_put_object_succ;
int multi_put_object_fail;
int async_put_object_succ;
int async_put_object_fail;
int async_multi_put_object_succ;
int async_multi_put_object_fail;
int get_object_succ;
int get_object_fail;
int multi_get_object_succ;
int multi_get_object_fail;
int async_get_object_succ;
int async_get_object_fail;
int async_multi_get_object_succ;
int async_multi_get_object_fail;
int head_object_succ;
int head_object_fail;
int delete_object_succ;
int delete_object_fail;
void UpdataStat(bool succ, int op_type) {
switch (op_type) {
case SIMPLE_PUT:
succ ? put_object_succ++ : put_object_fail++;
case MULTI_PUT:
succ ? multi_put_object_succ++ : multi_put_object_fail++;
case ASYNC_PUT:
succ ? async_put_object_succ++ : async_put_object_fail++;
case ASYNC_MULTI_PUT:
succ ? async_multi_put_object_succ++ : async_multi_put_object_fail++;
case SIMPLE_GET:
succ ? get_object_succ++ : get_object_fail++;
case MULTI_GET:
succ ? multi_get_object_succ++ : multi_get_object_fail++;
case ASYNC_GET:
succ ? async_get_object_succ++ : async_get_object_fail++;
case ASYNC_MULTI_GET:
succ ? async_multi_get_object_succ++ : async_multi_get_object_fail++;
}
}
void PrintStat() {
std::stringstream oss;
oss << std::endl;
oss << "put_object_succ:" << put_object_succ << std::endl;
oss << "put_object_fail:" << put_object_fail << std::endl;
oss << "multi_put_object_succ:" << put_object_succ << std::endl;
oss << "multi_put_object_fail:" << put_object_fail << std::endl;
oss << "async_put_object_succ:" << put_object_succ << std::endl;
oss << "async_put_object_fail:" << put_object_fail << std::endl;
oss << "async_multi_put_object_succ:" << put_object_succ << std::endl;
oss << "async_multi_put_object_fail:" << put_object_fail << std::endl;
oss << "get_object_succ:" << put_object_succ << std::endl;
oss << "get_object_fail:" << put_object_fail << std::endl;
oss << "multi_get_object_succ:" << put_object_succ << std::endl;
oss << "multi_get_object_fail:" << put_object_fail << std::endl;
oss << "async_get_object_succ:" << put_object_succ << std::endl;
oss << "async_get_object_fail:" << put_object_fail << std::endl;
oss << "async_multi_get_object_succ:" << put_object_succ << std::endl;
oss << "async_multi_get_object_fail:" << put_object_fail << std::endl;
oss << "head_object_succ:" << put_object_succ << std::endl;
oss << "head_object_fail:" << put_object_fail << std::endl;
oss << "delete_object_succ:" << put_object_succ << std::endl;
oss << "delete_object_fail:" << put_object_fail << std::endl;
SDK_LOG_INFO("%s", oss.str().c_str());
}
};
void TestLogCallback(const std::string& log) {
std::ofstream ofs;
ofs.open("./stable_test.log", std::ios_base::app);
ofs << log;
ofs.close();
}
int main(int argc, char** argv) {
UNUSED_PARAM(argc)
UNUSED_PARAM(argv)
qcloud_cos::CosConfig config("./config.json");
config.SetLogCallback(&TestLogCallback);
qcloud_cos::CosAPI cos(config);
TestStatistics stat;
std::string bucket_name = "test-12345678";
size_t max_file_size = 100 * 1024 * 1024;
while (true) {
std::vector<int> put_op_type_v = {SIMPLE_PUT, MULTI_PUT, ASYNC_PUT,
ASYNC_MULTI_PUT};
for (auto& op_type : put_op_type_v) {
size_t file_size = rand() % max_file_size;
GENERATE_LOCAL_FILE(file_size)
bool done = false;
std::mutex mutex;
std::condition_variable cond;
auto put_done_cb = [file_crc64_origin, file_md5_origin, &done, &mutex,
&cond, &stat](const SharedAsyncContext& context,
void* user_data) {
int op_type = (*reinterpret_cast<int*>(user_data));
CHECK_COMMON_RESULT(context->GetResult())
if (context->GetResult().IsSucc()) {
stat.UpdataStat(true, op_type);
} else {
stat.UpdataStat(false, op_type);
}
AsyncResp resp = context->GetAsyncResp();
CHECK_COMMON_RESP(resp)
CHECK_PUT_RESP(resp, op_type)
done = true;
std::unique_lock<std::mutex> lock(mutex);
cond.notify_one();
};
// put object
CosResult result;
PutObjectByFileResp resp1;
MultiPutObjectResp resp2;
if (op_type == SIMPLE_PUT) {
SDK_LOG_INFO("put object, object_name: %s", object_name.c_str());
PutObjectByFileReq req(bucket_name, object_name, local_file);
result = cos.PutObject(req, &resp1);
} else if (op_type == MULTI_PUT) {
SDK_LOG_INFO("multi put object, object_name: %s", object_name.c_str());
MultiPutObjectReq req(bucket_name, object_name, local_file);
result = cos.MultiPutObject(req, &resp2);
} else if (op_type == ASYNC_PUT) {
SDK_LOG_INFO("async put object, object_name: %s", object_name.c_str());
AsyncPutObjectReq req(bucket_name, object_name, local_file);
req.SetDoneCallback(put_done_cb);
req.SetUserData(reinterpret_cast<void*>(&op_type));
MultiPutObjectResp resp;
cos.AsyncPutObject(req);
} else if (op_type == ASYNC_MULTI_PUT) {
SDK_LOG_INFO("async multi put object, object_name: %s",
object_name.c_str());
AsyncMultiPutObjectReq req(bucket_name, object_name, local_file);
req.SetUserData(reinterpret_cast<void*>(&op_type));
req.SetDoneCallback(put_done_cb);
cos.AsyncMultiPutObject(req);
}
if (op_type == SIMPLE_PUT || op_type == MULTI_PUT) {
if (!result.IsSucc()) {
SDK_LOG_ERR("failed to put object, object_name: %s",
object_name.c_str());
PrintResult(result);
stat.UpdataStat(false, op_type);
} else {
stat.UpdataStat(true, op_type);
CHECK_COMMON_RESULT(result)
if (op_type == SIMPLE_PUT) {
CHECK_COMMON_RESP(resp1)
CHECK_PUT_RESP(resp1, op_type)
} else {
CHECK_COMMON_RESP(resp2)
CHECK_PUT_RESP(resp2, op_type)
}
}
} else {
while (!done) {
SDK_LOG_INFO("wait for put completing, object_name: %s",
object_name.c_str());
std::unique_lock<std::mutex> lock(mutex);
cond.wait_until(
lock, std::chrono::system_clock::now() + std::chrono::seconds(1));
}
}
// head object
HeadObjectReq head_req(bucket_name, object_name);
HeadObjectResp headresp;
SDK_LOG_INFO("head object, object_name: %s", object_name.c_str());
result = cos.HeadObject(head_req, &headresp);
if (!result.IsSucc()) {
SDK_LOG_ERR("failed to head object, object_name: %s",
object_name.c_str());
PrintResult(result);
stat.head_object_fail++;
} else {
stat.head_object_succ++;
CHECK_COMMON_RESULT(result)
CHECK_COMMON_RESP(headresp)
CHECK_HEAD_RESP(headresp)
}
// get object
// 使用多个接口下载同一个对象
done = false;
std::string local_file_download = local_file + "_download";
auto get_done_cb = [file_size, local_file_download, file_crc64_origin,
file_md5_origin, &done, &mutex, &cond,
&stat](const SharedAsyncContext& context,
void* user_data) {
int op_type = (*reinterpret_cast<int*>(user_data));
CHECK_COMMON_RESULT(context->GetResult())
if (context->GetResult().IsSucc()) {
stat.UpdataStat(true, op_type);
} else {
stat.UpdataStat(false, op_type);
}
AsyncResp resp = context->GetAsyncResp();
CHECK_COMMON_RESP(resp)
CHECK_GET_RESP(resp, op_type)
done = true;
std::unique_lock<std::mutex> lock(mutex);
cond.notify_one();
};
std::vector<int> get_op_type_v = {SIMPLE_GET, MULTI_GET, ASYNC_GET,
ASYNC_MULTI_GET};
for (auto& op_type : get_op_type_v) {
GetObjectByFileResp resp1;
MultiGetObjectResp resp2;
if (op_type == SIMPLE_GET) {
SDK_LOG_INFO("get object, object_name: %s", object_name.c_str());
GetObjectByFileReq req(bucket_name, object_name, local_file_download);
result = cos.GetObject(req, &resp1);
} else if (op_type == MULTI_GET) {
SDK_LOG_INFO("multi get object, object_name: %s",
object_name.c_str());
MultiGetObjectReq req(bucket_name, object_name, local_file_download);
result = cos.MultiGetObject(req, &resp2);
} else if (op_type == ASYNC_GET) {
SDK_LOG_INFO("async get object, object_name: %s",
object_name.c_str());
AsyncGetObjectReq req(bucket_name, object_name, local_file_download);
req.SetDoneCallback(get_done_cb);
req.SetUserData(reinterpret_cast<void*>(&op_type));
cos.AsyncGetObject(req);
} else if (op_type == ASYNC_MULTI_GET) {
SDK_LOG_INFO("async multi get object, object_name: %s",
object_name.c_str());
AsyncMultiGetObjectReq req(bucket_name, object_name,
local_file_download);
req.SetUserData(reinterpret_cast<void*>(&op_type));
req.SetDoneCallback(get_done_cb);
cos.AsyncMultiGetObject(req);
}
if (op_type == SIMPLE_GET || op_type == MULTI_GET) {
if (!result.IsSucc()) {
SDK_LOG_ERR("failed to get object, object_name: %s",
object_name.c_str());
PrintResult(result);
stat.UpdataStat(false, op_type);
} else {
stat.UpdataStat(true, op_type);
CHECK_COMMON_RESULT(result)
if (op_type == SIMPLE_GET) {
CHECK_COMMON_RESP(resp1)
CHECK_GET_RESP(resp1, op_type)
} else {
CHECK_COMMON_RESP(resp2)
CHECK_GET_RESP(resp2, op_type)
}
}
} else {
while (!done) {
SDK_LOG_INFO("wait for get completing, object_name: %s",
object_name.c_str());
std::unique_lock<std::mutex> lock(mutex);
cond.wait_until(lock, std::chrono::system_clock::now() +
std::chrono::seconds(1));
}
done = false;
}
}
// delete object
SDK_LOG_INFO("delete object, object_name: %s", object_name.c_str());
qcloud_cos::DeleteObjectReq del_req(bucket_name, object_name);
qcloud_cos::DeleteObjectResp del_resp;
result = cos.DeleteObject(del_req, &del_resp);
if (!result.IsSucc()) {
SDK_LOG_ERR("failed to delete object, object_name: %s",
object_name.c_str());
PrintResult(result);
stat.delete_object_fail++;
} else {
stat.delete_object_succ++;
CHECK_COMMON_RESULT(result)
CHECK_COMMON_RESP(del_resp)
}
// delete local file
TestUtils::RemoveFile(local_file);
TestUtils::RemoveFile(local_file_download);
}
stat.PrintStat();
}
#if defined(_WIN32)
system("pause");
#endif
return 0;
}

BIN
demo/test_file/audio.mp3 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000000,
douyin-00000.ts
#EXT-X-ENDLIST

BIN
demo/test_file/test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

7
demo/test_file/test.srt Normal file
View File

@@ -0,0 +1,7 @@
1
00:00:04,160 --> 00:00:08,640
srt字幕啊我一杯品尝你的啡留下唇印的嘴。蝴蝶玫瑰名字写错谁告白节说风吹的对街微笑在脸上飞。哼和你说你有点难追想让我知难而退。礼物不屑掉最贵只要乡榭的落叶营造浪漫的约回不害怕留在一切拥有。
2
00:00:08,640 --> 00:00:12,680
你就拥有全世界。亲爱的,爱上你从那天起甜蜜的痕迹,亲爱的,别人性你的眼睛在说,我愿意咖啡,我说一杯品尝你的啡,留下唇印的嘴,蝴蝶,玫瑰。

BIN
demo/test_file/test.zip Normal file

Binary file not shown.

1
demo/test_file/text.txt Normal file
View File

@@ -0,0 +1 @@
texttest

BIN
demo/test_file/video.mp4 Normal file

Binary file not shown.

50
gen_lcov.sh Normal file
View File

@@ -0,0 +1,50 @@
#!/bin/sh
workspace=`pwd`
EXTRACT="${workspace}/*/op/* ${workspace}/*/util/* ${workspace}/*/request/* ${workspace}/*/response/* ${workspace}/*/trsf/* ${workspace}/include/* ${workspace}/src/*"
# clear
rm UTReport -rf
rm UTResport.tar
mkdir -p build
cd build
cmake -DENABLE_COVERAGE=ON -DBUILD_UNITTEST=ON -DUSE_OPENSSL_MD5=ON ..
gmake all -j 4
# init
cd ..
lcov -d build -z
lcov -d build -b . --no-external --initial -c -o sevenyou_init.info
# run
cd build/bin
./all-test
#./async-op-test
#./bucket-op-test
#./live-channel-test
#./object-op-test
#./object-request-test
#./object-response-test
#./util-test
# second
cd ../..
lcov -d build -b . --no-external -c -o sevenyou.info
# filt
lcov --extract sevenyou_init.info ${EXTRACT} -o sevenyou_init_filted.info
lcov --extract sevenyou.info ${EXTRACT} -o sevenyou_filted.info
lcov --remove sevenyou.info "${workspace}/third_party/*" -o sevenyou_rm_third_party.info
rm sevenyou.info
mv sevenyou_rm_third_party.info sevenyou.info
# genhtml and zip
genhtml -o UTReport --prefix=`pwd` sevenyou_init_filted.info sevenyou_filted.info
tar -cvf UTReport.tar UTReport
# rm sevenyou_init.info
# rm sevenyou_init_filted.info
# rm sevenyou.info
# rm sevenyou_filted.info
rm UTReport -rf

1041
include/cos_api.h Normal file

File diff suppressed because it is too large Load Diff

254
include/cos_config.h Normal file
View File

@@ -0,0 +1,254 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_COS_CONFIG_H_
#define COS_CPP_SDK_V5_INCLUDE_COS_CONFIG_H_
#include <stdint.h>
#include <memory>
#include <mutex>
#include <string>
#include "Poco/JSON/Parser.h"
#include "util/log_util.h"
namespace qcloud_cos {
#define COS_DEFAULT_MAX_RETRY_TIMES 3
#define COS_DEFAULT_RETRY_INTERVAL_MS 100
class CosConfig {
public:
/// \brief CosConfig构造函数
///
/// \param config_file 配置文件所在路径
explicit CosConfig(const std::string& config_file);
/// \brief CosConfig构造函数
CosConfig()
: m_app_id(0),
m_access_key(""),
m_secret_key(""),
m_region(""),
m_tmp_token(""),
m_set_intranet_once(false),
m_is_use_intranet(false),
m_intranet_addr(""),
m_dest_domain(""),
m_is_domain_same_to_host(false),
m_is_domain_same_to_host_enable(false),
m_config_parsed(false),
m_max_retry_times(COS_DEFAULT_MAX_RETRY_TIMES),
m_retry_interval_ms(COS_DEFAULT_RETRY_INTERVAL_MS) {}
/// \brief CosConfig构造函数
///
/// \param appid 开发者访问 COS
/// 服务时拥有的用户维度唯一资源标识,用以标识资源 \param access_key
/// 开发者拥有的项目身份识别 ID用以身份认证 \param secret_key
/// 开发者拥有的项目身份密钥
CosConfig(uint64_t appid, const std::string& access_key,
const std::string& secret_key, const std::string& region)
: m_app_id(appid),
m_access_key(access_key),
m_secret_key(secret_key),
m_region(region),
m_tmp_token(""),
m_set_intranet_once(false),
m_is_use_intranet(false),
m_intranet_addr(""),
m_dest_domain(""),
m_is_domain_same_to_host(false),
m_is_domain_same_to_host_enable(false),
m_config_parsed(false),
m_max_retry_times(COS_DEFAULT_MAX_RETRY_TIMES),
m_retry_interval_ms(COS_DEFAULT_RETRY_INTERVAL_MS) {}
/// \brief CosConfig构造函数
///
/// \param appid 开发者访问 COS
/// 服务时拥有的用户维度唯一资源标识,用以标识资源 \param access_key
/// 开发者拥有的项目身份识别 ID用以身份认证 \param secret_key
/// 开发者拥有的项目身份密钥
CosConfig(uint64_t appid, const std::string& access_key,
const std::string& secret_key, const std::string& region,
const std::string& tmp_token)
: m_app_id(appid),
m_access_key(access_key),
m_secret_key(secret_key),
m_region(region),
m_tmp_token(tmp_token),
m_set_intranet_once(false),
m_is_use_intranet(false),
m_intranet_addr(""),
m_dest_domain(""),
m_is_domain_same_to_host(false),
m_is_domain_same_to_host_enable(false),
m_config_parsed(false),
m_max_retry_times(COS_DEFAULT_MAX_RETRY_TIMES),
m_retry_interval_ms(COS_DEFAULT_RETRY_INTERVAL_MS) {}
/// \brief CosConfig复制构造函数
///
/// \param config
CosConfig(const CosConfig& config) {
m_app_id = config.m_app_id;
m_access_key = config.m_access_key;
m_secret_key = config.m_secret_key;
m_region = config.m_region;
m_tmp_token = config.m_tmp_token;
m_set_intranet_once = config.m_set_intranet_once;
m_is_use_intranet = config.m_is_use_intranet;
m_intranet_addr = config.m_intranet_addr;
m_dest_domain = config.m_dest_domain;
m_is_domain_same_to_host = config.m_is_domain_same_to_host;
m_is_domain_same_to_host_enable = config.m_is_domain_same_to_host;
m_config_parsed = config.m_config_parsed;
m_max_retry_times = config.m_max_retry_times;
m_retry_interval_ms = config.m_retry_interval_ms;
}
/// \brief CosConfig赋值构造函数
///
/// \param config
CosConfig& operator=(const CosConfig& config) {
m_app_id = config.m_app_id;
m_access_key = config.m_access_key;
m_secret_key = config.m_secret_key;
m_region = config.m_region;
m_tmp_token = config.m_tmp_token;
m_set_intranet_once = config.m_set_intranet_once;
m_is_use_intranet = config.m_is_use_intranet;
m_intranet_addr = config.m_intranet_addr;
m_dest_domain = config.m_dest_domain;
m_is_domain_same_to_host = config.m_is_domain_same_to_host;
m_is_domain_same_to_host_enable = config.m_is_domain_same_to_host;
m_config_parsed = config.m_config_parsed;
m_max_retry_times = config.m_max_retry_times;
m_retry_interval_ms = config.m_retry_interval_ms;
return *this;
}
/// \brief 根据配置文件进行初始化
///
/// \param config_file 配置文件所在路径
///
/// \return 初始化成功则返回true否则返回false
bool InitConf(const std::string& config_file);
/// \brief 获取AppID
///
/// \return appid
uint64_t GetAppId() const;
/// \brief 获取AccessKey
///
/// \return access_key
std::string GetAccessKey() const;
/// \brief 获取SecretKey
///
/// \return secret_key
std::string GetSecretKey() const;
/// \brief 操作的Region
/// region的有效值参见https://cloud.tencent.com/document/product/436/6224
///
/// \return region
std::string GetRegion() const;
/// \brief 获取临时密钥
std::string GetTmpToken() const;
/// \brief 设置AppID
void SetAppId(uint64_t app_id) { m_app_id = app_id; }
/// \brief 设置AccessKey
void SetAccessKey(const std::string& access_key) {
m_access_key = access_key;
}
/// \brief 设置SecreteKey
void SetSecretKey(const std::string& secret_key) {
m_secret_key = secret_key;
}
/// \brief 设置操作的Region
/// region的有效值参见https://cloud.tencent.com/document/product/436/6224
void SetRegion(const std::string& region) { m_region = region; }
/// \brief 设置临时密钥
void SetTmpToken(const std::string& tmp_token) { m_tmp_token = tmp_token; }
/// \brief 更新临时密钥
void SetConfigCredentail(const std::string& access_key,
const std::string& secret_key,
const std::string& tmp_token);
/// \brief 设置是否使用自定义ip和端口号
void SetIsUseIntranetAddr(bool is_use_intranet);
bool IsUseIntranet();
/// \berief 设置自定义ip和端口号
void SetIntranetAddr(const std::string& intranet_addr);
std::string GetIntranetAddr();
bool GetSetIntranetOnce() const {return m_set_intranet_once;}
void SetDestDomain(const std::string& domain);
const std::string& GetDestDomain() const;
bool IsDomainSameToHost() const;
void SetDomainSameToHost(bool is_domain_same_to_host);
bool IsDomainSameToHostEnable() const;
bool CheckRegion();
// void SetDomainSameToHostEnable(bool is_domain_same_to_host_enable);
/// \brief 设置日志回调
void SetLogCallback(const LogCallback log_callback);
uint64_t GetMaxRetryTimes() const;
void SetMaxRetryTimes(uint64_t max_retry_times);
uint64_t GetRetryIntervalMs() const;
void SetRetryIntervalMs(uint64_t retry_interval_ms);
static bool JsonObjectGetStringValue(
const Poco::JSON::Object::Ptr& json_object, const std::string& key,
std::string* value);
static bool JsonObjectGetIntegerValue(
const Poco::JSON::Object::Ptr& json_object, const std::string& key,
uint64_t* value);
static bool JsonObjectGetBoolValue(const Poco::JSON::Object::Ptr& json_object,
const std::string& key, bool* value);
private:
mutable std::mutex m_lock;
uint64_t m_app_id;
std::string m_access_key;
std::string m_secret_key;
std::string m_region;
std::string m_tmp_token;
bool m_set_intranet_once;
bool m_is_use_intranet;
std::string m_intranet_addr;
std::string m_dest_domain;
bool m_is_domain_same_to_host;
bool m_is_domain_same_to_host_enable;
bool m_config_parsed;
uint64_t m_max_retry_times;
uint64_t m_retry_interval_ms;
};
typedef std::shared_ptr<CosConfig> SharedConfig;
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_COS_CONFIG_H_

1243
include/cos_defines.h Normal file

File diff suppressed because it is too large Load Diff

176
include/cos_params.h Normal file
View File

@@ -0,0 +1,176 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_COS_PARAMS_H_
#define COS_CPP_SDK_V5_INCLUDE_COS_PARAMS_H_
#include <string>
namespace qcloud_cos {
/// http header中的Authorization字段
const char kHttpHeaderAuthorizatio[] = "Authorization";
//const std::string kParaCustomHeaders = "custom_headers";
const char kHttpHeaderCacheControl[] = "Cache-Control";
const char kHttpHeaderContentType[] = "Content-Type";
const char kHttpHeaderContentLength[] = "Content-Length";
const char kHttpHeaderContentDisposition[] = "Content-Disposition";
const char kHttpHeaderContentLanguage[] = "Content-Language";
const char kHttpHeaderContentEncoding[] = "Content-Encoding";
const char kHttpHeaderContentRange[] = "Content-Range";
const char kHttpHeaderExpires[] = "Expires";
const char kHttpHeaderLastModified[] = "Last-Modified";
const char kHttpHeaderConnection[] = "Connection";
const char kHttpHeaderDate[] = "Date";
const char kHttpHeaderServer[] = "Server";
const char kHttpHeaderEtag[] = "ETag";
const char kHttpHeaderLowerCaseEtag[] = "Etag";
const char kParaXCosMetaPrefix[] = "x-cos-meta-";
const char kParaMoveDstFileid[] = "dest_fileid";
const char kParaMoveOverWrite[] = "to_over_write";
const char kParaListNum[] = "num";
const char kParaListFlag[] = "list_flag";
const char kParaListContext[] = "context";
// const std::string kParaErrorDesc = "parameter error";
// const std::string kNetworkErrorDesc = "network error";
// const std::string kLocalFileNotExistDesc = "local file not exist";
// const std::string kParaPathIleagel = "path ileagel error";
// const std::string kCanNotOpRootPath = "can not operator root folder";
// x-cos-meta-前缀
const char kXCosMetaPrefix[] = "x-cos-meta-";
// Request Header
const char kReqHeaderEtag[] = "ETag";
const char kReqHeaderLowerCaseEtag[] = "Etag";
const char kReqHeaderContentLen[] = "Content-Length";
const char kReqHeaderContentType[] = "Content-Type";
const char kReqHeaderConnection[] = "Connection";
const char kReqHeaderDate[] = "Date";
const char kReqHeaderServer[] = "Server";
const char kReqHeaderXCosReqId[] = "x-cos-request-id";
const char kReqHeaderXCosTraceId[] = "x-cos-trace-id";
const char kReqHeaderXCosSdkRetry[] = "x-cos-sdk-retry";
// Response Header
const char kRespHeaderLastModified[] = "Last-Modified";
const char kRespHeaderXCosObjectType[] = "x-cos-object-type";
const char kRespHeaderXCosStorageClass[] = "x-cos-storage-class";
const char kRespHeaderXCosHashCrc64Ecma[] = "x-cos-hash-crc64ecma";
const char kRespHeaderXCosStorageTier[] = "x-cos-storage-tier";
const char kRespHeaderXCosReqId[] = "x-cos-request-id";
const char kRespHeaderXCosTraceId[] = "x-cos-trace-id";
const char kRespHeaderXCosNextAppendPosition[] = "x-cos-next-append-position";
const char kRespHeaderXCosContentSha1[] = "x-cos-content-sha1";
const char kRespHeaderXCosTaggingCount[] = "x-cos-tagging-count";
// doc preview response header
const char kRespHeaderXTotalPage[] = "X-Total-Page";
const char kRespHeaderXErrNo[] = "X-ErrNo";
const char kRespHeaderXTotalSheet[] = "X-Total-Sheet";
const char kRespHeaderXSheetName[] = "X-Sheet-Name";
// V5 返回错误信息的xml node名
const char kErrorRoot[] = "Error";
const char kErrorCode[] = "Code";
const char kErrorMessage[] = "Message";
const char kErrorResource[] = "Resource";
const char kErrorTraceId[] = "TraceId";
const char kErrorRequestId[] = "RequestId";
const char kErrorServerTime[] = "ServerTime";
// GetBucketResponse XML node
const char kGetBucketRoot[] = "ListBucketResult";
const char kGetBucketName[] = "Name";
const char kGetBucketDelimiter[] = "Delimiter";
const char kGetBucketEncodingType[] = "EncodingType";
const char kGetBucketNextMarker[] = "NextMarker";
const char kGetBucketPrefix[] = "Prefix";
const char kGetBucketMarker[] = "Marker";
const char kGetBucketMaxKeys[] = "MaxKeys";
const char kGetBucketIsTruncated[] = "IsTruncated";
const char kGetBucketCommonPrefixes[] = "CommonPrefixes";
const char kGetBucketContents[] = "Contents";
const char kGetBucketContentsKey[] = "Key";
const char kGetBucketContentsLastModified[] = "LastModified";
const char kGetBucketContentsETag[] = "ETag";
const char kGetBucketContentsSize[] = "Size";
const char kGetBucketContentsStorageClass[] = "StorageClass";
const char kGetBucketContentsOwner[] = "Owner";
const char kGetBucketContentsOwnerID[] = "ID";
// ListMultipartUpload XML node
const char kListMultipartUploadRoot[] = "ListMultipartUploadsResult";
const char kListMultipartUploadBucket[] = "Bucket";
const char kListMultipartUploadMarker[] = "KeyMarker";
const char kListMultipartUploadIdMarker[] = "UploadIdMarker";
const char kListMultipartUploadNextKeyMarker[] = "NextKeyMarker";
const char kListMultipartUploadNextUploadIdMarker[] = "NextUploadIdMarker";
const char kListMultipartUploadMaxUploads[] = "MaxUploads";
const char kListMultipartUploadUpload[] = "Upload";
const char kListMultipartUploadKey[] = "Key";
const char kListMultipartUploadId[] = "UploadId";
const char kListMultipartUploadStorageClass[] = "StorageClass";
const char kListMultipartUploadInitiator[] = "Initiator";
const char kListMultipartUploadOwner[] = "Owner";
const char kListMultipartUploadInitiated[] = "Initiated";
const char kListMultipartUploadID[] = "ID";
const char kListMultipartUploadDisplayName[] = "DisplayName";
// BucketReplicationResponse XML node
const char kBucketReplicationRoot[] = "ReplicationConfiguration";
const char kBucketReplicationRule[] = "Rule";
const char kBucketReplicationID[] = "ID";
const char kBucketReplicationRole[] = "Role";
const char kBucketReplicationPrefix[] = "Prefix";
const char kBucketReplicationStatus[] = "Status";
const char kBucketReplicationDestination[] = "Destination";
const char kBucketReplicationBucket[] = "Bucket";
const char kBucketReplicationStorageClass[] = "StorageClass";
// InitMultiUploadResp XML node
const char kInitiateMultipartUploadRoot[] = "InitiateMultipartUploadResult";
const char kInitiateMultipartUploadBucket[] = "Bucket";
const char kInitiateMultipartUploadKey[] = "Key";
const char kInitiateMultipartUploadId[] = "UploadId";
// CompleteMultiUploadResp XML node
const char kCompleteMultiUploadRoot[] = "CompleteMultipartUploadResult";
const char kCompleteMultiUploadLocation[] = "Location";
const char kCompleteMultiUploadBucket[] = "Bucket";
const char kCompleteMultiUploadKey[] = "Key";
const char kCompleteMultiUploadETag[] = "ETag";
// StorageClass
const char kStorageClassStandard[] = "STANDARD";
const char kStorageClassStandardIA[] = "STANDARD_IA";
const char kStorageClassMAZStandard[] = "MAZ_STANDARD";
const char kStorageClassMAZStandardIA[] = "MAZ_STANDARD_IA";
const char kStorageClassIntelligentTiering[] = "INTELLIGENT_TIERING";
const char kStorageClassArchive[] = "ARCHIVE";
const char kStorageClassDeepArchive[] = "DEEP_ARCHIVE";
// Resumable download
const char kResumableDownloadTaskFileSuffix[] = ".cosresumabletask";
const char kResumableDownloadFileName[] = "fileName";
const char kResumableDownloadTaskLastModified[] = "lastModified";
const char kResumableDownloadTaskContentLength[] = "contentLength";
const char kResumableDownloadTaskEtag[] = "eTag";
const char kResumableDownloadTaskCrc64ecma[] = "crc64ecma";
const char kResumableDownloadResumeOffset[] = "resumeOffset";
// 预设ACL
const char kAclDefault[] = "default";
const char kAclPrivate[] = "private";
const char kAclPublicRead[] = "public-read";
const char kAclPublicReadWrite[] = "public-read-write";
const char kAclAuthenticatedRead[] = "authenticated-read";
const char kAclBucketOwnerRead[] = "bucket-owner-read";
// object type
const char kObjectTypeAppendable[] = "appendable";
const char kObjectTypeNormal[] = "normal";
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_COS_PARAMS_H_

227
include/cos_sys_config.h Normal file
View File

@@ -0,0 +1,227 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_COS_SYS_CONFIG_H_
#define COS_CPP_SDK_V5_INCLUDE_COS_SYS_CONFIG_H_
#include <stdint.h>
#include "cos_defines.h"
#include "util/log_util.h"
namespace qcloud_cos {
class CosSysConfig {
public:
/// \brief 设置签名超时时间,单位:秒
static void SetAuthExpiredTime(uint64_t time);
/// \brief 设置本地时间与网络时间差值
static void SetTimeStampDelta(int64_t dela);
/// \brief 设置连接超时时间,单位:毫秒
static void SetConnTimeoutInms(uint64_t time);
/// \brief 设置接收超时时间,单位:毫秒
static void SetRecvTimeoutInms(uint64_t time);
/// \brief 设置上传分片大小,单位:字节,默认:10M
static void SetUploadPartSize(uint64_t part_size);
/// \brief 获取上传复制分片大小,单位:字节,默认: 20M
static void SetUploadCopyPartSize(uint64_t part_size);
/// \brief 设置文件分片并发上传线程池大小,默认: 5
static void SetUploadThreadPoolSize(unsigned size);
/// \brief 设置异步上传下载线程池大小,默认: 2
static void SetAsynThreadPoolSize(unsigned size);
/// \brief 设置log输出,1:屏幕,2:syslog,3:不输出,默认:1
static void SetLogOutType(LOG_OUT_TYPE log);
/// \brief 设置log输出等级,COS_LOG_ERR/WRAN/INFO/DBG
static void SetLogLevel(LOG_LEVEL level);
/// \brief 设置下载线程池的大小
static void SetDownThreadPoolSize(unsigned size);
/// \brief 设置下载分片的大小
static void SetDownSliceSize(unsigned slice_size);
/// \brief 设置长连接的参数
static void SetKeepAlive(bool keepalive);
/// \brief 设置长连接的参数
static void SetKeepIdle(int64_t keepidle);
/// \brief 设置长连接的参数
static void SetKeepIntvl(int64_t keepintvl);
static void SetDestDomain(const std::string& dest_domain);
/// \brief 获取签名超时时间,单位秒
static uint64_t GetAuthExpiredTime();
/// \brief 获取本地时间与网络时间差值
static int64_t GetTimeStampDelta();
/// \brief 获取连接超时时间,单位:毫秒
static uint64_t GetConnTimeoutInms();
/// \brief 获取接收超时时间,单位:毫秒
static uint64_t GetRecvTimeoutInms();
/// \brief 获取上传分片大小,单位:字节
static uint64_t GetUploadPartSize();
/// \brief 获取上传复制分片大小,单位:字节
static uint64_t GetUploadCopyPartSize();
/// \brief 获取上传线程池大小
static unsigned GetUploadThreadPoolSize();
/// \brief 获取异步线程池大小
static unsigned GetAsynThreadPoolSize();
/// \brief 获取日志输出类型,默认输出到屏幕
static int GetLogOutType();
/// \brief 获取日志输出等级
static int GetLogLevel();
/// \brief 打印CosSysConfig的配置详情
static void PrintValue();
/// \brief 获取下载分片大小
static unsigned GetDownSliceSize();
/// \brief 获取下载线程池大小
static unsigned GetDownThreadPoolSize();
/// \brief 获取keepalive参数
static bool GetKeepAlive();
static int64_t GetKeepIdle();
static int64_t GetKeepIntvl();
/// \brief 下载过程中是否检查MD5
static bool IsCheckMd5();
/// \brief 设置下载过程中检查MD5
static void SetCheckMd5(bool is_check_md5);
static bool IsDomainSameToHost();
static void SetDomainSameToHost(bool is_domain_same_to_host);
/// \brief 根据传入appid、region、bucket_name返回对应的hostname
static std::string GetHost(uint64_t app_id, const std::string& region,
const std::string& bucket_name,
bool change_backup_domain = false);
/// \brief 获取CI域名
static std::string GetCIHost(const std::string& bucket_name,
const std::string& region);
/// \brief 获取PIC域名
static std::string GetPICHost(uint64_t app_id, const std::string& region,
const std::string& bucket_name);
static std::string GetDestDomain();
/// \brief 获取是否使用特定ip和端口号
static bool IsUseIntranet();
static void SetIsUseIntranet(bool is_use_interanet);
static void SetIntranetAddr(const std::string& intranet_addr);
/// \brief 获取特定ip和端口号
static std::string GetIntranetAddr();
/// \brief 获取日志回调函数
static LogCallback GetLogCallback();
/// \brief 设置日志回调
static void SetLogCallback(const LogCallback log_callback);
/// \brief 设置是否使用dns cache
static void SetUseDnsCache(bool is_use_dns_cache);
/// \brief 获取是否使用dns cache
static bool GetUseDnsCache();
/// \brief 设置dns cache过期时间
static void SetDnsCacheExpireSeconds(unsigned expire_secondes);
/// \brief 获取dns cache过期时间
static unsigned GetDnsCacheExpireSeconds();
/// \breif 设置dns cache大小
static void SetDnsCacheSize(unsigned cache_size);
/// \brief 获取dns cache大小
static unsigned GetDnsCacheSize();
static void SetRetryChangeDomain(bool retry_change_domain);
static bool GetRetryChangeDomain();
static void SetObjectKeySimplifyCheck(bool object_key_simplify_check);
static bool GetObjectKeySimplifyCheck();
private:
// 打印日志:0,不打印,1:打印到屏幕,2:打印到syslog
static LOG_OUT_TYPE m_log_outtype;
// 日志级别:1: ERR, 2: WARN, 3:INFO, 4:DBG
static LOG_LEVEL m_log_level;
// 上传分片大小
static uint64_t m_upload_part_size;
// 上传分片大小
static uint64_t m_upload_copy_part_size;
// 本地时间戳与网络时间服务器时间戳的差值,计算方法:
// delta = network_ts - local_ts
static int64_t m_timestamp_delta;
// 签名超时时间(秒)
static uint64_t m_sign_expire_in_s;
// Http连接超时时间(毫秒)
static uint64_t m_conn_timeout_in_ms;
// Http接收超时时间(毫秒)
static uint64_t m_recv_timeout_in_ms;
// 单文件分片并发上传线程池大小(每个文件一个)
static unsigned m_threadpool_size;
// 异步上传下载线程池大小(全局就一个)
static unsigned m_asyn_threadpool_size;
// 下载文件到本地线程池大小
static unsigned m_down_thread_pool_size;
// 下载文件到本地,每次下载字节数
static unsigned m_down_slice_size;
// 是否开启长连接
static bool m_keep_alive;
// 空闲多久后发送keepalive探针单位s
static int64_t m_keep_idle;
// 每个keepalive探针时间间隔单位s
static int64_t m_keep_intvl;
// 下载时是否检查md5
static bool m_is_check_md5;
static std::string m_dest_domain;
static bool m_is_domain_same_to_host;
static bool m_is_use_intranet;
static std::string m_intranet_addr;
// 日志回调
static LogCallback m_log_callback;
// 是否使用dns cache
static bool m_use_dns_cache;
// dns cache过期时间
static unsigned m_dns_cache_expire_seconds;
// dns cache大小
static unsigned m_dns_cache_size;
static bool m_retry_change_domain;
static bool m_object_key_simplify_check;
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_COS_SYS_CONFIG_H_

153
include/op/base_op.h Normal file
View File

@@ -0,0 +1,153 @@
#pragma once
#ifndef COS_CPP_SDK_V5_INCLUDE_OP_BASE_OP_H_
#define COS_CPP_SDK_V5_INCLUDE_OP_BASE_OP_H_
#include <stdint.h>
#include <map>
#include <string>
#include "cos_config.h"
#include "op/cos_result.h"
#include "trsf/transfer_handler.h"
#include "util/base_op_util.h"
namespace qcloud_cos {
class BaseReq;
class BaseResp;
class BaseOp {
public:
/// \brief BaseOp构造函数
///
/// \param cos_conf Cos配置
explicit BaseOp(const SharedConfig& cos_conf) : m_config(cos_conf), m_op_util(m_config) {}
BaseOp() {}
/// \brief BaseOp析构函数
~BaseOp() {}
/// \brief 获取Cos配置
CosConfig GetCosConfig() const;
/// \brief 获取AppID
uint64_t GetAppId() const;
/// \brief 获取Region
std::string GetRegion() const;
/// \brief 获取AccessKey
std::string GetAccessKey() const;
/// \brief 获取SecretKey
std::string GetSecretKey() const;
/// \brief 获取Token
std::string GetTmpToken() const;
std::string GetDestDomain() const;
bool IsDomainSameToHost() const;
bool IsDefaultHost(const std::string &host) const;
/// \brief 封装了cos Service/Bucket/Object 相关接口的通用操作,
/// 包括签名计算、请求发送、返回内容解析等
///
/// \param host 目标主机, 以http://开头
/// \param path http path
/// \param req http请求
/// \param req_body http request的body
/// \param resp http返回
/// \param is_ci_req 是否为万象域名请求
///
/// \return http调用情况(状态码等)
CosResult NormalAction(const std::string& host, const std::string& path,
const BaseReq& req, const std::string& req_body,
bool check_body, BaseResp* resp, bool is_ci_req = false);
/// \brief 封装了cos Service/Bucket/Object相关接口的通用操作,
/// 包括签名计算、请求发送、返回内容解析等
///
/// \param host 目标主机, 以http://开头
/// \param path http path
/// \param req http请求
/// \param additional_headers http请求需要所需的额外header
/// \param additional_params http请求需要所需的额外params
/// \param req_body http request的body
/// \param resp http返回
/// \param is_ci_req 是否为万象域名请求
///
/// \return http调用情况(状态码等)
CosResult NormalAction(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
const std::string& req_body, bool check_body, BaseResp* resp,
bool is_ci_req = false);
/// \brief 下载文件并输出到流中
///
/// \param host 目标主机, 以http://开头
/// \param path http path
/// \param req http请求
/// \param resp http返回
/// \param os 输出流
///
/// \return http调用情况(状态码等)
CosResult DownloadAction(const std::string& host, const std::string& path,
const BaseReq& req, BaseResp* resp, std::ostream& os,
const SharedTransferHandler& handler = nullptr);
/// \brief 支持从stream中读入数据并上传
///
/// \param host 目标主机, 以http://开头
/// \param path http path
/// \param req http请求
/// \param additional_headers http请求需要所需的额外header
/// \param additional_params http请求需要所需的额外params
/// \param is http request的body
/// \param resp http返回
///
/// \return http调用情况(状态码等)
CosResult UploadAction(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
std::istream& is, BaseResp* resp, const SharedTransferHandler& handler = nullptr);
std::string GetRealUrl(const std::string& host, const std::string& path,
bool is_https, bool is_generate_presigned_url = false);
protected:
bool CheckConfigValidation() const;
SharedConfig m_config;
BaseOpUtil m_op_util;
private:
CosResult NormalRequest(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
const std::string& req_body, bool check_body, BaseResp* resp,
const uint32_t &request_retry_num, bool is_ci_req = false);
CosResult DownloadRequest(const std::string& host, const std::string& path,
const BaseReq& req, BaseResp* resp, std::ostream& os,
const uint32_t &request_retry_num,
const SharedTransferHandler& handler = nullptr);
CosResult UploadRequest(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
std::istream& is, BaseResp* resp, const uint32_t &request_retry_num, const SharedTransferHandler& handler = nullptr);
bool NoNeedRetry(const CosResult &result);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_OP_BASE_OP_H_

711
include/op/bucket_op.h Normal file
View File

@@ -0,0 +1,711 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/13/17
// Description:
#pragma once
#include "cos_sys_config.h"
#include "op/base_op.h"
#include "op/cos_result.h"
#include "request/bucket_req.h"
#include "request/data_process_req.h"
#include "request/auditing_req.h"
#include "response/bucket_resp.h"
#include "response/data_process_resp.h"
#include "response/auditing_resp.h"
namespace qcloud_cos {
/// \brief 封装了Bucket相关的操作
class BucketOp : public BaseOp {
public:
/// \brief BucketOp构造函数
///
/// \param cos_conf Cos配置
explicit BucketOp(const SharedConfig& config) : BaseOp(config) {}
/// \brief BucketOp析构函数
virtual ~BucketOp() {}
/// \brief 判断bucket是否存在
bool IsBucketExist(const std::string& bucket_name);
/// \brief 获取Bucket所在Location
std::string GetBucketLocation(const std::string& bucket_name);
/// \brief 创建一个Bucket
/// (详见:https://www.qcloud.com/document/product/436/7738)
///
/// \param req PutBucket请求
/// \param resp PutBucket返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucket(const PutBucketReq& req, PutBucketResp* resp,
bool change_backup_domain = false);
/// \brief 确认Bucket是否存在
/// (详见:https://cloud.tencent.com/document/product/436/7735)
///
/// \param req HeadBucket请求
/// \param resp HeadBucket返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult HeadBucket(const HeadBucketReq& req, HeadBucketResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的部分或者全部Object
/// (详见:https://www.qcloud.com/document/product/436/7734)
///
/// \param req GetBucket请求
/// \param resp GetBucket返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucket(const GetBucketReq& req, GetBucketResp* resp,
bool change_backup_domain = false);
CosResult ListMultipartUpload(const ListMultipartUploadReq& req,
ListMultipartUploadResp* resp,
bool change_backup_domain = false);
/// \brief 删除Bucket
///
/// \param req DeleteBucket请求
/// \param resp DeleteBucket返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucket(const DeleteBucketReq& req, DeleteBucketResp* resp,
bool change_backup_domain = false);
/// \brief 获得存储桶的版本控制信息
/// (详见:https://cloud.tencent.com/document/product/436/8597)
///
/// \param req GetBucketVersioning请求
/// \param resp GetBucketVersioning返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketVersioning(const GetBucketVersioningReq& req,
GetBucketVersioningResp* resp,
bool change_backup_domain = false);
/// \brief 启用或者暂停存储桶的版本控制功能
/// (详见:https://cloud.tencent.com/document/product/436/8591)
///
/// \param req PutBucketVersioning请求
/// \param resp PutBucketVersioning返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketVersioning(const PutBucketVersioningReq& req,
PutBucketVersioningResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的跨域复制配置
///
/// \param req GetBucketReplication请求
/// \param resp GetBucketReplication返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketReplication(const GetBucketReplicationReq& req,
GetBucketReplicationResp* resp,
bool change_backup_domain = false);
/// \brief 增加/替换Bucket下的跨域复制配置
///
/// \param req PutBucketReplication请求
/// \param resp PutBucketReplication返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketReplication(const PutBucketReplicationReq& req,
PutBucketReplicationResp* resp,
bool change_backup_domain = false);
/// \brief 删除Bucket下的跨域复制配置
///
/// \param req DeleteBucketReplication请求
/// \param resp DeleteBucketReplication返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketReplication(const DeleteBucketReplicationReq& req,
DeleteBucketReplicationResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的生命周期配置
///
/// \param req GetBucketLifecycle请求
/// \param resp GetBucketLifecycle返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketLifecycle(const GetBucketLifecycleReq& req,
GetBucketLifecycleResp* resp,
bool change_backup_domain = false);
/// \brief 增加/替换Bucket下的生命周期配置
///
/// \param req PutBucketLifecycle请求
/// \param resp PutBucketLifecycle返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketLifecycle(const PutBucketLifecycleReq& req,
PutBucketLifecycleResp* resp,
bool change_backup_domain = false);
/// \brief 删除Bucket下的生命周期配置
///
/// \param req DeleteBucketLifecycle请求
/// \param resp DeleteBucketLifecycle返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketLifecycle(const DeleteBucketLifecycleReq& req,
DeleteBucketLifecycleResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的ACL
///
/// \param req GetBucketACL请求
/// \param resp GetBucketACL返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketACL(const GetBucketACLReq& req, GetBucketACLResp* resp,
bool change_backup_domain = false);
/// \brief 增加/替换Bucket下的ACL, 可以通过Header或者Body传入ACL信息
/// 注意Header 和 Body 只能选择其中一种,否则响应返回会冲突
///
/// \param req PutBucketACL请求
/// \param resp PutBucketACL返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketACL(const PutBucketACLReq& req, PutBucketACLResp* resp,
bool change_backup_domain = false);
/// \brief 获取Bucket的权限策略
///
/// \param req GetBucketPolicy请求
/// \param resp GetBucketPolicy返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketPolicy(const GetBucketPolicyReq& req, GetBucketPolicyResp* resp,
bool change_backup_domain = false);
/// \brief 写入/替换Bucket的权限策略通过Body传入
///
/// \param req PutBucketPolicy请求
/// \param resp PutBucketPolicy返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketPolicy(const PutBucketPolicyReq& req, PutBucketPolicyResp* resp,
bool change_backup_domain = false);
/// \brief 删除Bucket的权限策略
///
/// \param req DeleteBucketPolicy请求
/// \param resp DeleteBucketPolicy返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketPolicy(const DeleteBucketPolicyReq& req, DeleteBucketPolicyResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的CORS
///
/// \param req GetBucketCORS请求
/// \param resp GetBucketCORS返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketCORS(const GetBucketCORSReq& req, GetBucketCORSResp* resp,
bool change_backup_domain = false);
/// \brief 增加/替换Bucket下的CORS
///
/// \param req PutBucketCORS请求
/// \param resp PutBucketCORS返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketCORS(const PutBucketCORSReq& req, PutBucketCORSResp* resp,
bool change_backup_domain = false);
/// \brief 删除Bucket下的CORS
///
/// \param req DeleteBucketCORS请求
/// \param resp DeleteBucketCORS返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketCORS(const DeleteBucketCORSReq& req,
DeleteBucketCORSResp* resp,
bool change_backup_domain = false);
/// \brief 列出Bucket下的部分或者全部Object(包括多版本)
///
/// \param req GetBucketObjectVersions请求
/// \param resp GetBucketObjectVersions返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketObjectVersions(const GetBucketObjectVersionsReq& req,
GetBucketObjectVersionsResp* resp,
bool change_backup_domain = false);
/// \brief 获取Bucket所在Location
///
/// \param req GetBucketLocation请求
/// \param resp GetBucketLocation返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketLocation(const GetBucketLocationReq& req,
GetBucketLocationResp* resp,
bool change_backup_domain = false);
// TODO(sevenyou)
// std::string ListMultipartUploads();
/// \brief 为源存储桶开启日志记录
/// \brief https://cloud.tencent.com/document/product/436/17054
/// \param req PutBucketLogging请求
/// \param resp PutBucketLogging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketLogging(const PutBucketLoggingReq& req,
PutBucketLoggingResp* resp,
bool change_backup_domain = false);
/// \brief 用于获取源存储桶的日志配置信息
/// \brief https://cloud.tencent.com/document/product/436/17053
/// \param req GetBucketLogging请求
/// \param resp GetBucketLogging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketLogging(const GetBucketLoggingReq& req,
GetBucketLoggingResp* resp,
bool change_backup_domain = false);
/// \brief 用于存储桶绑定自定义域名
/// \brief
/// \param req PutBucketDomain请求
/// \param resp PutBucketDomain返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketDomain(const PutBucketDomainReq& req,
PutBucketDomainResp* resp,
bool change_backup_domain = false);
/// \brief 用于获取存储桶绑定自定义域名
/// \brief
/// \param req GetBucketDomain请求
/// \param resp GetBucketDomain返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketDomain(const GetBucketDomainReq& req,
GetBucketDomainResp* resp,
bool change_backup_domain = false);
/// \brief 存储桶配置静态网站,通过传入 XML
/// 格式的配置文件进行配置文件大小限制为64KB \brief
/// https://cloud.tencent.com/document/product/436/31930 \param req
/// PutBucketWebsite请求 \param resp PutBucketWebsite返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketWebsite(const PutBucketWebsiteReq& req,
PutBucketWebsiteResp* resp,
bool change_backup_domain = false);
/// \brief 获取与存储桶关联的静态网站配置信息.
/// \brief https://cloud.tencent.com/document/product/436/31929
/// \param req GetBucketWebsite请求
/// \param resp GetBucketWebsite返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketWebsite(const GetBucketWebsiteReq& req,
GetBucketWebsiteResp* resp,
bool change_backup_domain = false);
/// \brief 删除存储桶中的静态网站配置.
/// \brief https://cloud.tencent.com/document/product/436/31928
/// \param req DeleteBucketWebsite请求
/// \param resp DeleteBucketWebsite返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketWebsite(const DeleteBucketWebsiteReq& req,
DeleteBucketWebsiteResp* resp,
bool change_backup_domain = false);
/// \brief 为已存在的Bucket设置标签.
/// \brief https://cloud.tencent.com/document/product/436/34838
/// \param req PutBucketTagging请求
/// \param resp PutBucketTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketTagging(const PutBucketTaggingReq& req,
PutBucketTaggingResp* resp,
bool change_backup_domain = false);
/// \brief 查询指定存储桶下已有的存储桶标签.
/// \brief https://cloud.tencent.com/document/product/436/34837
/// \param req GetBucketTagging请求
/// \param resp GetBucketTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketTagging(const GetBucketTaggingReq& req,
GetBucketTaggingResp* resp,
bool change_backup_domain = false);
/// \brief 删除指定存储桶下已有的存储桶标签.
/// \brief https://cloud.tencent.com/document/product/436/34836
/// \param req DeleteBucketTagging请求
/// \param resp DeleteBucketTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketTagging(const DeleteBucketTaggingReq& req,
DeleteBucketTaggingResp* resp,
bool change_backup_domain = false);
/// \brief 用于在存储桶中创建清单任务.
/// \brief https://cloud.tencent.com/document/product/436/33707
/// \param req PutBucketinventory请求
/// \param resp PutBucketinventory返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketInventory(const PutBucketInventoryReq& req,
PutBucketInventoryResp* resp,
bool change_backup_domain = false);
/// \brief 查询存储桶中用户的清单任务信息.
/// \brief https://cloud.tencent.com/document/product/436/33705
/// \param req GetBucketinventory请求
/// \param resp GetBucketinventory返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketInventory(const GetBucketInventoryReq& req,
GetBucketInventoryResp* resp,
bool change_backup_domain = false);
/// \brief 请求返回一个存储桶中的所有清单任务.
/// \brief https://cloud.tencent.com/document/product/436/33706
/// \param req ListBucketInventoryConfigurations请求
/// \param resp ListBucketInventoryConfigurations返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult ListBucketInventoryConfigurations(
const ListBucketInventoryConfigurationsReq& req,
ListBucketInventoryConfigurationsResp* resp,
bool change_backup_domain = false);
/// \brief 用于删除存储桶中指定的清单任务.
/// \brief https://cloud.tencent.com/document/product/436/33704
/// \param req DeleteBucketinventory请求
/// \param resp DeleteBucketinventory返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteBucketInventory(const DeleteBucketInventoryReq& req,
DeleteBucketInventoryResp* resp,
bool change_backup_domain = false);
/// \brief 用于为存储桶设置 Referer 白名单或者黑名单.
/// \brief https://cloud.tencent.com/document/product/436/32492
/// \param req PutBucketReferer请求
/// \param resp PutBucketReferer响应
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketReferer(const PutBucketRefererReq& req,
PutBucketRefererResp* resp,
bool change_backup_domain = false);
/// \brief 读取存储桶 Referer 白名单或者黑名单.
/// \brief https://cloud.tencent.com/document/product/436/32493
/// \param req GetBucketReferer请求
/// \param resp GetBucketReferer响应
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketReferer(const GetBucketRefererReq& req,
GetBucketRefererResp* resp,
bool change_backup_domain = false);
/// \brief 列举直播通道
/// \param req ListLiveChannelReq请求
/// \param resp ListLiveChannelResp返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult ListLiveChannel(const ListLiveChannelReq& req,
ListLiveChannelResp* resp,
bool change_backup_domain = false);
/// \brief 配置存储桶智能分层
///
/// \param req PutBucketIntelligentTiering请求
/// \param resp PutBucketIntelligentTiering返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketIntelligentTiering(
const PutBucketIntelligentTieringReq& req,
PutBucketIntelligentTieringResp* resp,
bool change_backup_domain = false);
/// \brief 获取存储桶智能分层配置
///
/// \param req GetBucketIntelligentTiering请求
/// \param resp GetBucketIntelligentTiering返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetBucketIntelligentTiering(
const GetBucketIntelligentTieringReq& req,
GetBucketIntelligentTieringResp* resp,
bool change_backup_domain = false);
/// \brief 存储桶绑定ci
///
/// \param req PutBucketToCIReq请求
/// \param resp PutBucketToCIResp返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketToCI(const PutBucketToCIReq& req,
PutBucketToCIResp* resp);
/// \brief 开通文档预览
/// \param req CreateDocBucket请求
/// \param resp CreateDocBucket返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateDocBucket(const CreateDocBucketReq& req,
CreateDocBucketResp* resp);
/// \brief 提交文档转码任务
/// \brief https://cloud.tencent.com/document/product/436/54056
/// \param req CreateDocProcessJobs请求
/// \param resp CreateDocProcessJobs返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateDocProcessJobs(const CreateDocProcessJobsReq& req,
CreateDocProcessJobsResp* resp);
/// \brief 查询指定的文档转码任务
/// \brief https://cloud.tencent.com/document/product/436/54095
/// \param req DescribeDocProcessJob请求
/// \param resp DescribeDocProcessJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeDocProcessJob(const DescribeDocProcessJobReq& req,
DescribeDocProcessJobResp* resp);
/// \brief 拉取符合条件的的文档转码任务
/// \brief https://cloud.tencent.com/document/product/436/54096
/// \param req DescribeDocProcessJobs请求
/// \param resp DescribeDocProcessJobs返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeDocProcessJobs(const DescribeDocProcessJobsReq& req,
DescribeDocProcessJobsResp* resp);
/// \brief 查询文档转码队列
/// \brief https://cloud.tencent.com/document/product/436/54055
/// \param req DescribeDocProcessQueues请求
/// \param resp DescribeDocProcessQueues返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeDocProcessQueues(const DescribeDocProcessQueuesReq& req,
DescribeDocProcessQueuesResp* resp);
/// \brief 更新文档转码队列
/// \brief https://cloud.tencent.com/document/product/436/54094
/// \param req UpdateDocProcessQueue请求
/// \param resp UpdateDocProcessQueue返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult UpdateDocProcessQueue(const UpdateDocProcessQueueReq& req,
UpdateDocProcessQueueResp* resp);
/// \brief 查询媒体处理开通状态
/// \brief https://cloud.tencent.com/document/product/436/48988
/// \param req DescribeMediaBuckets请求
/// \param resp DescribeMediaBuckets返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
DescribeMediaBucketsResp* resp);
/// \brief 开通媒体处理
/// \brief https://cloud.tencent.com/document/product/436/72824
/// \param req CreateMediaBucketReq请求
/// \param resp CreateMediaBucketResp返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateMediaBucket(const CreateMediaBucketReq& req,
CreateMediaBucketResp* resp);
/// \brief 获取媒体文件信息
/// \brief https://cloud.tencent.com/document/product/436/55672
/// \param req GetMediainfo请求
/// \param resp GetMediainfo返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetMediainfo(const GetMediaInfoReq& req, GetMediaInfoResp* resp);
/// \brief 搜索媒体处理队列
/// \brief https://cloud.tencent.com/document/product/436/54045
/// \param req DescribeMediaQueues请求
/// \param resp DescribeMediaQueues返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeMediaQueues(const DescribeMediaQueuesReq& req, DescribeQueuesResp* resp);
/// \brief 更新媒体处理队列
/// \brief https://cloud.tencent.com/document/product/436/54046
/// \param req UpdateMediaQueue请求
/// \param resp UpdateMediaQueue返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult UpdateMediaQueue(const UpdateMediaQueueReq& req,
UpdateQueueResp* resp);
/// \brief 查询文件处理开通状态
/// \brief https://cloud.tencent.com/document/product/460/95747
/// \param req DescribeFileBuckets请求
/// \param resp DescribeFileBuckets返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeFileBuckets(const DescribeFileBucketsReq& req,
DescribeFileBucketsResp* resp);
/// \brief 开通文件处理
/// \brief https://cloud.tencent.com/document/product/460/86377
/// \param req CreateFileBucketReq请求
/// \param resp CreateFileBucketResp返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateFileBucket(const CreateFileBucketReq& req,
CreateFileBucketResp* resp);
/// \brief 提交数据处理任务
/// \brief https://cloud.tencent.com/document/product/436/83110
/// \param req CreateFileProcessJobs请求
/// \param resp CreateFileProcessJobs返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateDataProcessJobs(const CreateDataProcessJobsReq& req,
CreateDataProcessJobsResp* resp);
/// \brief 取消数据处理任务
/// \brief https://cloud.tencent.com/document/product/436/85082
/// \param req CancelFileProcessJobs请求
/// \param resp CancelFileProcessJobs返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CancelDataProcessJob(const CancelDataProcessJobReq& req,
CancelDataProcessJobResp* resp);
/// \brief 提交数据处理任务
/// \param req DescribeDataProcessJobs请求
/// \param resp DescribeDataProcessJobs返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeDataProcessJob(const DescribeDataProcessJobReq& req,
DescribeDataProcessJobResp* resp);
/// \brief 图片批量审核
/// \brief https://cloud.tencent.com/document/product/436/63593
/// \param req BatchImageAuditing请求
/// \param resp BatchImageAuditing返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult BatchImageAuditing(const BatchImageAuditingReq& req,
BatchImageAuditingResp* resp);
/// \brief 查询图片审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/68904
/// \param req DescribeImageAuditingJob请求
/// \param resp DescribeImageAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeImageAuditingJob(const DescribeImageAuditingJobReq& req,
DescribeImageAuditingJobResp* resp);
/// \brief 提交视频审核任务
/// \brief https://cloud.tencent.com/document/product/436/47316
/// \param req DescribeVideoAuditingJob请求
/// \param resp DescribeVideoAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateVideoAuditingJob(const CreateVideoAuditingJobReq& req,
CreateVideoAuditingJobResp* resp);
/// \brief 查询视频审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/47317
/// \param req DescribeVideoAuditingJob请求
/// \param resp DescribeVideoAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeVideoAuditingJob(const DescribeVideoAuditingJobReq& req,
DescribeVideoAuditingJobResp* resp);
/// \brief 提交音频审核任务
/// \brief https://cloud.tencent.com/document/product/436/54063
/// \param req DescribeAudioAuditingJob请求
/// \param resp DescribeAudioAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateAudioAuditingJob(const CreateAudioAuditingJobReq& req,
CreateAudioAuditingJobResp* resp);
/// \brief 查询音频审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/54064
/// \param req DescribeAudioAuditingJob请求
/// \param resp DescribeAudioAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeAudioAuditingJob(const DescribeAudioAuditingJobReq& req,
DescribeAudioAuditingJobResp* resp);
/// \brief 提交文本审核任务
/// \brief https://cloud.tencent.com/document/product/436/56289
/// \param req DescribeTextAuditingJob请求
/// \param resp DescribeTextAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateTextAuditingJob(const CreateTextAuditingJobReq& req,
CreateTextAuditingJobResp* resp);
/// \brief 查询文本审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/56288
/// \param req DescribeTextAuditingJob请求
/// \param resp DescribeTextAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeTextAuditingJob(const DescribeTextAuditingJobReq& req,
DescribeTextAuditingJobResp* resp);
/// \brief 提交文档审核任务
/// \brief https://cloud.tencent.com/document/product/436/59381
/// \param req DescribeDocumentAuditingJob请求
/// \param resp DescribeDocumentAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateDocumentAuditingJob(const CreateDocumentAuditingJobReq& req,
CreateDocumentAuditingJobResp* resp);
/// \brief 查询文档审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/59382
/// \param req DescribeDocumentAuditingJob请求
/// \param resp DescribeDocumentAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeDocumentAuditingJob(const DescribeDocumentAuditingJobReq& req,
DescribeDocumentAuditingJobResp* resp);
/// \brief 提交网页审核任务
/// \brief https://cloud.tencent.com/document/product/436/63958
/// \param req DescribeWebPageAuditingJob请求
/// \param resp DescribeWebPageAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult CreateWebPageAuditingJob(const CreateWebPageAuditingJobReq& req,
CreateWebPageAuditingJobResp* resp);
/// \brief 查询网页审核任务结果
/// \brief https://cloud.tencent.com/document/product/436/63959
/// \param req DescribeWebPageAuditingJob请求
/// \param resp DescribeWebPageAuditingJob返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DescribeWebPageAuditingJob(const DescribeWebPageAuditingJobReq& req,
DescribeWebPageAuditingJobResp* resp);
private:
/// \brief 处理CI请求
CosResult ProcessReq(const BucketReq& req, BaseResp* resp,
bool is_ci_req = false);
};
} // namespace qcloud_cos

125
include/op/cos_result.h Normal file
View File

@@ -0,0 +1,125 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/25/17
// Description:
#ifndef COS_RESULT_H
#define COS_RESULT_H
#pragma once
#include <map>
#include <string>
namespace qcloud_cos {
// 封装HTTP状态码3XX4XX5XX 的返回结果
// 详见官网链接: https://www.qcloud.com/document/product/436/7730
class CosResult {
public:
CosResult()
: m_is_succ(false),
m_http_status(-1),
m_err_code(""),
m_err_msg(""),
m_resource_addr(""),
m_x_cos_request_id(""),
m_x_cos_trace_id("") {}
~CosResult() {}
CosResult(const CosResult& other) {
m_is_succ = other.m_is_succ;
m_http_status = other.m_http_status;
m_err_code = other.m_err_code;
m_err_msg = other.m_err_msg;
m_resource_addr = other.m_resource_addr;
m_x_cos_request_id = other.m_x_cos_request_id;
m_x_cos_trace_id = other.m_x_cos_trace_id;
m_real_byte = other.m_real_byte;
}
CosResult& operator=(const CosResult& other) {
if (this != &other) {
m_is_succ = other.m_is_succ;
m_http_status = other.m_http_status;
m_err_code = other.m_err_code;
m_err_msg = other.m_err_msg;
m_resource_addr = other.m_resource_addr;
m_x_cos_request_id = other.m_x_cos_request_id;
m_x_cos_trace_id = other.m_x_cos_trace_id;
m_real_byte = other.m_real_byte;
}
return *this;
}
bool IsSucc() const { return m_is_succ; }
void SetSucc() { m_is_succ = true; }
void SetFail() { m_is_succ = false; }
void Clear() {
m_is_succ = false;
m_http_status = -1;
m_err_code = "";
m_err_msg = "";
m_resource_addr = "";
m_x_cos_request_id = "";
m_x_cos_trace_id = "";
}
// 解析xml string
bool ParseFromHttpResponse(const std::map<std::string, std::string>& headers,
const std::string& body);
// Getter
int GetHttpStatus() const { return m_http_status; }
std::string GetErrorCode() const { return m_err_code; }
std::string GetErrorMsg() const { return m_err_msg; }
std::string GetResourceAddr() const { return m_resource_addr; }
std::string GetXCosRequestId() const { return m_x_cos_request_id; }
std::string GetXCosTraceId() const { return m_x_cos_trace_id; }
std::string GetXCosServerTime() const { return m_x_cos_server_time; }
uint64_t GetRealByte() const { return m_real_byte; }
// Setter
void SetHttpStatus(int http_status) { m_http_status = http_status; }
void SetErrorCode(const std::string& err_code) { m_err_code = err_code; }
void SetErrorMsg(const std::string& err_msg) { m_err_msg = err_msg; }
void SetResourceAddr(const std::string& resource_addr) {
m_resource_addr = resource_addr;
}
void SetXCosRequestId(const std::string& x_cos_request_id) {
m_x_cos_request_id = x_cos_request_id;
}
void SetXCosTraceId(const std::string& x_cos_trace_id) {
m_x_cos_trace_id = x_cos_trace_id;
}
void SetRealByte(uint64_t real_byte) { m_real_byte = real_byte; }
/// \brief 输出Result的具体信息
std::string DebugString() const;
std::string GetInitMpRequestId() const { return m_init_mp_request_id; }
void SetInitMpRequestId(const std::string& request_id) {
m_init_mp_request_id = request_id;
}
private:
bool m_is_succ; // 标识HTTP调用是否成功
int m_http_status; // http状态码
// COS返回的错误信息
std::string m_err_code;
std::string m_err_msg;
std::string m_resource_addr;
std::string m_x_cos_request_id;
std::string m_x_cos_trace_id;
std::string m_x_cos_server_time;
uint64_t m_real_byte;
// MultiUploadObject接口中封装了init mp/upload part/complete该成员保存init
// mp的request id 如果是断点续传则该reqeust id为空
std::string m_init_mp_request_id;
};
} // namespace qcloud_cos
#endif // COS_RESULT_H

View File

@@ -0,0 +1,77 @@
#pragma once
#include <stdint.h>
#include <map>
#include <string>
#include "Poco/Runnable.h"
#include "cos_defines.h"
#include "util/base_op_util.h"
namespace qcloud_cos {
class FileCopyTask : public Poco::Runnable {
public:
FileCopyTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms);
~FileCopyTask() {}
void run();
void CopyTask();
bool IsTaskSuccess() const;
int GetHttpStatus() const;
std::string GetTaskResp() const;
std::map<std::string, std::string> GetRespHeaders() const;
void SetParams(const std::map<std::string, std::string>& params);
void SetHeaders(const std::map<std::string, std::string>& headers);
void SetVerifyCert(bool verify_cert);
void SetCaLocation(const std::string& ca_location);
void SetSslCtxCb(SSLCtxCallback cb, void *data);
std::string GetErrMsg() const { return m_err_msg; }
std::string GetEtag() const { return m_etag; }
std::string GetLastModified() const { return m_last_modified; }
private:
std::string m_host;
std::string m_path;
bool m_is_https;
std::map<std::string, std::string> m_headers;
std::map<std::string, std::string> m_params;
uint64_t m_conn_timeout_in_ms;
uint64_t m_recv_timeout_in_ms;
std::string m_resp;
bool m_is_task_success;
int m_http_status;
std::map<std::string, std::string> m_resp_headers;
std::string m_err_msg;
std::string m_etag;
std::string m_last_modified;
bool m_verify_cert;
std::string m_ca_location;
SSLCtxCallback m_ssl_ctx_cb;
void *m_user_data;
BaseOpUtil m_op_util;
void SendRequestOnce(std::string domain);
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/25/17
// Description:
#pragma once
#include <stdint.h>
#include <map>
#include <string>
#include "Poco/Runnable.h"
#include "cos_config.h"
#include "trsf/transfer_handler.h"
#include "util/base_op_util.h"
#include "util/semaphore.h"
#include "util/task.h"
namespace qcloud_cos {
class FileDownTask : public Poco::Runnable {
public:
FileDownTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms,
const SharedTransferHandler& handler = nullptr,
uint64_t offset = 0, unsigned char* pbuf = NULL,
const size_t data_len = 0,
bool verify_cert = true,
const std::string& ca_lication = "",
SSLCtxCallback ssl_ctx_cb = nullptr,
void *user_data = nullptr,
Semaphore* semaphore = nullptr);
~FileDownTask() {}
void run();
void DownTask();
void SetDownParams(unsigned char* pdatabuf, size_t datalen, uint64_t offset);
void SetVerifyCert(bool verify_cert);
void SetCaLocation(const std::string& ca_location);
void SetSslCtxCb(SSLCtxCallback cb, void *data);
// 设置信号量,用于任务完成时自动释放资源
void SetSemaphore(Semaphore* semaphore) { m_semaphore = semaphore; }
// 设置当前任务在下载序列中的顺序号
void SetSequence(uint64_t sequence) { m_task_info.sequence = sequence;}
// 重置任务状态为IDLE供主线程在处理完TASK_COMPLETED后调用以复用任务槽
void ResetTaskStatus() { m_task_info.status = TASK_IDLE; }
void SetTaskRunning() { m_task_info.status = TASK_RUNNING; }
TaskStatus GetTaskStatus() const { return m_task_info.status; }
std::string GetTaskResp() const { return m_resp; }
size_t GetDownLoadLen() const { return m_real_down_len; }
bool IsTaskSuccess() const { return m_is_task_success; }
uint64_t GetSequence() const { return m_task_info.sequence; }
int GetHttpStatus() const { return m_http_status; }
std::map<std::string, std::string> GetRespHeaders() const { return m_resp_headers; }
std::string GetErrMsg() const { return m_err_msg; }
private:
std::string m_host;
std::string m_path;
bool m_is_https;
BaseOpUtil m_op_util;
std::map<std::string, std::string> m_headers;
std::map<std::string, std::string> m_params;
uint64_t m_conn_timeout_in_ms;
uint64_t m_recv_timeout_in_ms;
SharedTransferHandler m_handler;
uint64_t m_offset;
unsigned char* m_data_buf_ptr;
size_t m_data_len;
std::string m_resp;
bool m_is_task_success;
size_t m_real_down_len;
int m_http_status;
std::map<std::string, std::string> m_resp_headers;
std::string m_err_msg;
bool m_verify_cert;
std::string m_ca_location;
SSLCtxCallback m_ssl_ctx_cb;
void *m_user_data;
// 信号量指针,用于任务完成时自动通知
Semaphore* m_semaphore;
TaskInfo m_task_info;
SharedConfig m_config;
void SendRequestOnce(std::string domain);
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,157 @@
#pragma once
#include <map>
#include <string>
#include "Poco/Runnable.h"
#include "request/object_req.h"
#include "trsf/transfer_handler.h"
#include "util/base_op_util.h"
#include "util/semaphore.h"
#include "util/task.h"
namespace qcloud_cos {
class FileUploadTask : public Poco::Runnable {
public:
FileUploadTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms, unsigned char* pbuf = NULL,
const size_t data_len = 0,
bool verify_cert = true,
const std::string& ca_location = "",
SSLCtxCallback ssl_ctx_cb = nullptr,
void *user_data = nullptr);
FileUploadTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms,
const SharedTransferHandler& handler,
bool verify_cert = true,
const std::string& ca_location = "",
SSLCtxCallback ssl_ctx_cb = nullptr,
void *user_data = nullptr);
FileUploadTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms,
unsigned char* pbuf = NULL, const size_t data_len = 0,
bool verify_cert = true,
const std::string& ca_location = "",
SSLCtxCallback ssl_ctx_cb = nullptr,
void *user_data = nullptr);
~FileUploadTask() {}
void run();
void UploadTask();
void SetUploadBuf(unsigned char* pdatabuf, size_t data_len);
std::string GetTaskResp() const;
bool IsTaskSuccess() const;
void SetTaskSuccess() { m_is_task_success = true; }
int GetHttpStatus() const;
std::map<std::string, std::string> GetRespHeaders() const;
void AddParams(const std::map<std::string, std::string>& params);
void SetParams(const std::map<std::string, std::string>& params);
void AddHeaders(const std::map<std::string, std::string>& headers);
void SetHeaders(const std::map<std::string, std::string>& headers);
std::string GetErrMsg() const { return m_err_msg; }
void SetResume(const bool is_resume) { m_is_resume = is_resume; }
bool IsResume() const { return m_is_resume; }
void SetResumeEtag(const std::string& etag) { m_resume_etag = etag; }
std::string GetResumeEtag() const { return m_resume_etag; }
void SetPartNumber(uint64_t part_number);
uint64_t GetPartNumber() const { return m_part_number; }
void SetVerifyCert(bool verify_cert);
void SetCaLocation(const std::string& ca_location);
void SetSslCtxCb(SSLCtxCallback cb, void *data);
void SetCheckCrc64(bool check_crc64) {
mb_check_crc64 = check_crc64;
}
// 设置信号量,用于任务完成时自动释放资源槽位
void SetSemaphore(Semaphore* semaphore) { m_semaphore = semaphore; }
// 设置当前任务在上传序列中的顺序号
void SetSequence(uint64_t sequence) { m_task_info.sequence = sequence; }
uint64_t GetCrc64Value() const {
return m_crc64_value;
}
// 获取任务序号
uint64_t GetSequence() const { return m_task_info.sequence; }
// 重置任务状态为IDLE供主线程在处理完TASK_COMPLETED后调用以复用任务槽
void ResetTaskStatus() { m_task_info.status = TASK_IDLE; }
void SetTaskRunning() { m_task_info.status = TASK_RUNNING; }
TaskStatus GetTaskStatus() const { return m_task_info.status; }
private:
std::string m_host;
std::string m_path;
bool m_is_https;
std::map<std::string, std::string> m_headers;
std::map<std::string, std::string> m_params;
uint64_t m_conn_timeout_in_ms;
uint64_t m_recv_timeout_in_ms;
unsigned char* m_data_buf_ptr;
size_t m_data_len;
std::string m_resp;
bool m_is_task_success;
int m_http_status;
std::map<std::string, std::string> m_resp_headers;
std::string m_err_msg;
bool m_is_resume;
std::string m_resume_etag;
uint64_t m_part_number;
SharedTransferHandler m_handler;
bool m_verify_cert;
std::string m_ca_location;
SSLCtxCallback m_ssl_ctx_cb;
void *m_user_data;
bool mb_check_crc64;
uint64_t m_crc64_value;
Semaphore* m_semaphore;
TaskInfo m_task_info;
BaseOpUtil m_op_util;
void SendRequestOnce(std::string domain, std::string md5_str);
};
} // namespace qcloud_cos

502
include/op/object_op.h Normal file
View File

@@ -0,0 +1,502 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#ifndef COS_CPP_SDK_V5_INCLUDE_OP_OBJECT_OP_H_
#define COS_CPP_SDK_V5_INCLUDE_OP_OBJECT_OP_H_
#include "op/base_op.h"
#include "op/cos_result.h"
#include "request/data_process_req.h"
#include "request/object_req.h"
#include "request/auditing_req.h"
#include "response/data_process_resp.h"
#include "response/object_resp.h"
#include "response/auditing_resp.h"
namespace qcloud_cos {
class PartBufInfo {
public:
unsigned char* buf;
size_t len;
public:
PartBufInfo() {
buf = nullptr;
len = 0;
}
};
class FileUploadTask;
class FileCopyTask;
/// \brief 封装了Object相关的操作
class ObjectOp : public BaseOp {
public:
/// \brief BucketOp构造函数
///
/// \param cos_conf Cos配置
explicit ObjectOp(const SharedConfig& config) : BaseOp(config) {}
ObjectOp() {}
/// \brief ObjectOP析构函数
virtual ~ObjectOp() {}
/// \brief 判断object是否存在
bool IsObjectExist(const std::string& bucket_name,
const std::string& object_name);
std::string GetResumableUploadID(const PutObjectByFileReq& originReq,
const std::string& bucket_name,
const std::string& object_name,
bool change_backup_domain = false);
bool CheckUploadPart(const PutObjectByFileReq& req,
const std::string& bucket_name,
const std::string& object_name,
const std::string& uploadid,
std::vector<std::string>& already_exist);
bool CheckSinglePart(const PutObjectByFileReq& req, uint64_t offset,
uint64_t local_part_size, uint64_t size,
const std::string& etag);
/// \brief 获取对应Object的meta信息数据
///
/// \param request HeadObject请求
/// \param response HeadObject返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult HeadObject(const HeadObjectReq& req, HeadObjectResp* resp, bool change_backup_domain = false);
/// \brief 下载Bucket中的一个文件至流中
///
/// \param request GetObjectByStream请求
/// \param response GetObjectByStream返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetObject(const GetObjectByStreamReq& req,
GetObjectByStreamResp* resp, bool change_backup_domain = false);
/// \brief 下载Bucket中的一个文件到本地
///
/// \param request GetObjectByFile请求
/// \param response GetObjectByFile返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetObject(const GetObjectByFileReq& req, GetObjectByFileResp* resp,
const SharedTransferHandler& handler = nullptr, bool change_backup_domain = false);
/// \brief 多线程下载Bucket中的一个文件到本地
///
/// \param request MultiGetObject请求
/// \param response MultiGetObject返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult MultiGetObject(const GetObjectByFileReq& req,
GetObjectByFileResp* resp);
/// \brief 将本地的文件上传至指定Bucket中
///
/// \param request PutObjectByFile请求
/// \param response PutObjectByFile返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PutObject(const PutObjectByFileReq& req, PutObjectByFileResp* resp,
const SharedTransferHandler& handler = nullptr, bool change_backup_domain = false);
/// \brief 将指定流上传至指定Bucket中
///
/// \param request PutObjectByStream请求
/// \param response PutObjectByStream返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PutObject(const PutObjectByStreamReq& req,
PutObjectByStreamResp* resp, const SharedTransferHandler& handler = nullptr, bool change_backup_domain = false);
/// \brief 删除Object
///
/// \param req DeleteObject请求
/// \param resp DeleteObject返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteObject(const DeleteObjectReq& req, DeleteObjectResp* resp, bool change_backup_domain = false);
/// \brief 批量删除Object
///
/// \param req DeleteObjects请求
/// \param resp DeleteObjects返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteObjects(const DeleteObjectsReq& req, DeleteObjectsResp* resp, bool change_backup_domain = false);
/// \brief
/// 请求实现初始化分片上传,成功执行此请求以后会返回UploadId用于后续的Upload
/// Part请求
///
/// \param request InitMultiUpload请求
/// \param response InitMultiUpload返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult InitMultiUpload(const InitMultiUploadReq& req,
InitMultiUploadResp* resp,
bool change_backup_domain = false);
/// \brief 初始化以后的分块上传,支持的块的数量为1到10000,块的大小为1MB到5GB
///
/// \param request UploadPartData请求
/// \param response UploadPartData返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult UploadPartData(const UploadPartDataReq& req,
UploadPartDataResp* resp,
bool change_backup_domain = false);
/// \brief
/// 初始化以后的分块复制,实现将一个文件的分块内容从源路径复制到目标路径。
/// 通过指定 x-cos-copy-source 来指定源文件x-cos-copy-source-range
/// 指定字节范围。 允许分块的大小为 5 MB - 5 GB。
///
/// \param request UploadPartCopyData请求
/// \param response UploadPartCopyData返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult UploadPartCopyData(const UploadPartCopyDataReq& req,
UploadPartCopyDataResp* resp,
bool change_backup_domain = false);
/// \brief 完成整个分块上传。当使用 Upload Parts 上传完所有块以后,
/// 必须调用该 API 来完成整个文件的分块上传
///
/// \param request CompleteMultiUpload请求
/// \param response CompleteMultiUpload返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult CompleteMultiUpload(const CompleteMultiUploadReq& req,
CompleteMultiUploadResp* resp,
bool change_backup_domain = false);
/// \brief 异步多线程上传
/// \param request MultiUploadObject请求
/// \param response MultiUploadObject返回
/// \param handler TransferHandler
///
/// \return result
CosResult MultiUploadObject(const PutObjectByFileReq& req,
MultiPutObjectResp* resp,
const SharedTransferHandler& handler = nullptr,
bool change_backup_domain = false);
/// \brief 单线程同步分块上传
///
/// \return result
CosResult UploadObjectResumableSingleThreadSync(const PutObjectByFileReq& req,
PutObjectResumableSingleSyncResp* resp);
/// \brief 舍弃一个分块上传并删除已上传的块
///
/// \param req AbortMultiUpload请求
/// \param resp AbortMultiUpload返回
///
/// \return
CosResult AbortMultiUpload(const AbortMultiUploadReq& req,
AbortMultiUploadResp* resp,
bool change_backup_domain = false);
/// \brief 查询特定分块上传中的已上传的块
///
/// \param req ListParts请求
/// \param resp ListParts返回
///
/// \return result
CosResult ListParts(const ListPartsReq& req, ListPartsResp* resp, bool change_backup_domain = false);
/// \brief 列出Object下的ACL
///
/// \param req GetObjectACL请求
/// \param resp GetObjectACL返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetObjectACL(const GetObjectACLReq& req, GetObjectACLResp* resp, bool change_backup_domain = false);
/// \brief 增加/替换Object下的ACL, 可以通过Header或者Body传入ACL信息
/// 注意Header 和 Body 只能选择其中一种,否则响应返回会冲突
///
/// \param req PutObjectACL请求
/// \param resp PutObjectACL返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutObjectACL(const PutObjectACLReq& req, PutObjectACLResp* resp, bool change_backup_domain = false);
/// \brief 已存在的Object设置标签.
///
/// \param req PutObjectTagging请求
/// \param resp PutObjectTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutObjectTagging(const PutObjectTaggingReq& req,
PutObjectTaggingResp* resp);
/// \brief 查询指定对象下已有的对象标签.
///
/// \param req GetObjectTagging请求
/// \param resp GetObjectTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetObjectTagging(const GetObjectTaggingReq& req,
GetObjectTaggingResp* resp);
/// \brief 删除指定对象下已有的对象标签.
///
/// \param req DeleteObjectTagging请求
/// \param resp DeleteObjectTagging返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult DeleteObjectTagging(const DeleteObjectTaggingReq& req,
DeleteObjectTaggingResp* resp);
/// \brief 复制Object
///
/// \param req PutObjectCopy请求
/// \param resp PutObjectCopy返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult PutObjectCopy(const PutObjectCopyReq& req, PutObjectCopyResp* resp, bool change_backup_domain = false);
/// \brief 复制文件,实现将一个文件的分块内容从源路径复制到目标路径。
/// 通过指定 x-cos-copy-source 来指定源文件x-cos-copy-source-range
/// 指定字节范围。
///
/// \param request Copy请求
/// \param response Copy返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult Copy(const CopyReq& req, CopyResp* resp, bool change_backup_domain = false);
/// \brief 对一个通过 COS 归档为 archive 类型的对象进行恢复
///
/// \param request PostObjectRestore请求
/// \param response PostObjectRestore返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PostObjectRestore(const PostObjectRestoreReq& req,
PostObjectRestoreResp* resp,
bool change_backup_domain = false);
std::string GeneratePresignedUrl(const GeneratePresignedUrlReq& req);
CosResult OptionsObject(const OptionsObjectReq& req, OptionsObjectResp* resp, bool change_backup_domain = false);
CosResult SelectObjectContent(const SelectObjectContentReq& req,
SelectObjectContentResp* resp,
bool change_backup_domain = false);
CosResult AppendObject(const AppendObjectReq& req, AppendObjectResp* resp);
/// \brief 创建推流通道
///
/// \param request PutLiveChannelReq请求
/// \param response PutLiveChannelResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PutLiveChannel(const PutLiveChannelReq& req,
PutLiveChannelResp* resp,
bool change_backup_domain = false);
/// \brief 启用或禁用通道
///
/// \param request PutLiveChannelSwitchReq请求
/// \param response PutLiveChannelSwitchResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PutLiveChannelSwitch(const PutLiveChannelSwitchReq& req,
PutLiveChannelSwitchResp* resp,
bool change_backup_domain = false);
/// \brief 获取直播通道配置
///
/// \param request GetLiveChannelReq请求
/// \param response GetLiveChannelResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetLiveChannel(const GetLiveChannelReq& req,
GetLiveChannelResp* resp,
bool change_backup_domain = false);
/// \brief 获取直播通道推流历史
///
/// \param request GetLiveChannelHistoryReq请求
/// \param response GetLiveChannelHistoryResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetLiveChannelHistory(const GetLiveChannelHistoryReq& req,
GetLiveChannelHistoryResp* resp,
bool change_backup_domain = false);
/// \brief 获取直播通道推流状态
///
/// \param request GetLiveChannelStatusReq请求
/// \param response GetLiveChannelStatusResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetLiveChannelStatus(const GetLiveChannelStatusReq& req,
GetLiveChannelStatusResp* resp,
bool change_backup_domain = false);
/// \brief 删除直播通
///
/// \param request DeleteLiveChannelReq请求
/// \param response DeleteLiveChannelResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult DeleteLiveChannel(const DeleteLiveChannelReq& req,
DeleteLiveChannelResp* resp,
bool change_backup_domain = false);
/// \brief 查询指定通道在指定时间段推流生成的播放列表
///
/// \param request GetLiveChannelVodPlaylistReq请求
/// \param response GetLiveChannelVodPlaylistResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult GetLiveChannelVodPlaylist(const GetLiveChannelVodPlaylistReq& req,
GetLiveChannelVodPlaylistResp* resp,
bool change_backup_domain = false);
/// \brief 指定通道生成一个可供点播例用的播放列表
///
/// \param request PostLiveChannelVodPlaylistReq请求
/// \param response GetLiveChannelVodPlaylistResp返回
///
/// \return 返回HTTP请求的状态码及错误信息
CosResult PostLiveChannelVodPlaylist(const PostLiveChannelVodPlaylistReq& req,
PostLiveChannelVodPlaylistResp* resp,
bool change_backup_domain = false);
/// \brief 异步多线程下载,handler处理回调
CosResult MultiThreadDownload(const GetObjectByFileReq& req,
GetObjectByFileResp* resp,
const SharedTransferHandler& handler = nullptr,
bool change_backup_domain = false);
/* Resumable接口 */
/// \brief 支持断点下载
CosResult ResumableGetObject(const GetObjectByFileReq& req,
GetObjectByFileResp* resp,
const SharedTransferHandler& handler = nullptr,
bool change_backup_domain = false);
/*批量及目录操作接口*/
CosResult PutObjects(const PutObjectsByDirectoryReq& req,
PutObjectsByDirectoryResp* resp,
bool change_backup_domain = false);
CosResult PutDirectory(const PutDirectoryReq& req, PutDirectoryResp* resp, bool change_backup_domain = false);
CosResult MoveObject(const MoveObjectReq& req, bool change_backup_domain = false);
/*数据处理接口*/
/**基础图片处理**/
/**图片持久化处理**/
/***上传时处理***/
CosResult PutImage(const PutImageByFileReq& req, PutImageByFileResp* resp);
/***云上数据处理***/
CosResult CloudImageProcess(const CloudImageProcessReq& req,
CloudImageProcessResp* resp);
/***下载图片时识别二维码***/
CosResult GetQRcode(const GetQRcodeReq& req, GetQRcodeResp* resp);
/*文档处理接口*/
/***查询已经开通文档预览功能的 Bucket***/
CosResult DescribeDocProcessBuckets(const DescribeDocProcessBucketsReq& req,
DescribeDocProcessBucketsResp* resp);
/***预览文档***/
CosResult DocPreview(const DocPreviewReq& req, DocPreviewResp* resp);
/***获取媒体文件的信息***/
CosResult GetMediaInfo(const GetMediaInfoReq& req, GetMediaInfoResp* resp);
CosResult GetImageAuditing(const GetImageAuditingReq& req, GetImageAuditingResp* resp);
private:
// 生成request body所需的xml字符串
bool GenerateCompleteMultiUploadReqBody(const CompleteMultiUploadReq& req,
std::string* req_body);
/// \brief 多线程上传,handler处理回调
CosResult
MultiThreadUpload(const PutObjectByFileReq& req, const std::string& upload_id,
const std::vector<std::string>& already_exist_parts,
bool resume_flag, std::vector<std::string>* etags_ptr,
std::vector<uint64_t>* part_numbers_ptr,
uint64_t& crc64_file,
const SharedTransferHandler& handler = nullptr,
bool change_backup_domain = false);
CosResult SingleThreadUpload(const PutObjectByFileReq& req, const std::string& upload_id,
const std::vector<std::string>& already_exist_parts,
bool resume_flag, std::vector<std::string>* etags_ptr,
std::vector<uint64_t>* part_numbers_ptr, PutObjectByFileResp* resp,
uint64_t& crc64);
/// \brief 读取文件内容, 并返回读取的长度
// uint64_t GetContent(const std::string& src, std::string* file_content) const;
void FillUploadTask(const std::string& upload_id, const std::string& host,
const std::string& path, unsigned char* file_content_buf,
uint64_t len, uint64_t part_number,
FileUploadTask* task_ptr, bool sign_header_host,
bool check_crc64);
void FillCopyTask(const std::string& upload_id, const std::string& host,
const std::string& path, uint64_t part_number,
const std::string& range,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
bool verify_cert, const std::string& ca_location,
SSLCtxCallback ssl_ctx_cb, void *user_data,
FileCopyTask* task, bool sign_header_host);
/// \brief 检查是否可以走断点下载
/// \param req PutObjectByFile请求
/// \param head_resp HeadObjectResp响应结果
/// \param last_offset 返回的上一次下载偏移量
/// \return true可以走断点下载,false表示不可以
bool CheckResumableDownloadTask(
const std::string& json_file,
const std::map<std::string, std::string>& element_map,
uint64_t* resume_offset);
/// \brief 更新断点下载json文件
/// \param json_file json文件名
/// \param element_map 检查的元素映射
/// \param last_offset 返回的上一次下载偏移量
/// \return true文件检查成功, 否则失败
void UpdateResumableDownloadTaskFile(
const std::string& json_file,
const std::map<std::string, std::string>& element_map,
uint64_t resume_offset);
void SetResultAndLogError(CosResult& result, const std::string& err_msg);
/// \brief 跨平台文件定位,失败时设置错误信息
/// \param fd 文件描述符
/// \param offset 目标偏移量
/// \param result 失败时写入错误信息的 CosResult
/// \return true 定位成功false 定位失败
bool SeekFile(int fd, uint64_t offset, CosResult& result);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_OP_OBJECT_OP_H_

42
include/op/service_op.h Normal file
View File

@@ -0,0 +1,42 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 11/14/17
// Description:
#ifndef SERVICEOP_H
#define SERVICEOP_H
#pragma once
#include "cos_sys_config.h"
#include "op/base_op.h"
#include "op/cos_result.h"
#include "request/service_req.h"
#include "response/service_resp.h"
namespace qcloud_cos {
/// \brief 封装了Service相关的操作
class ServiceOp : public BaseOp {
public:
/// \brief ServiceOp构造函数
///
/// \param cos_conf Cos配置
explicit ServiceOp(const SharedConfig& config) : BaseOp(config) {}
/// \brief ServiceOp析构函数
virtual ~ServiceOp() {}
/// \brief 获取请求者名下的所有存储空间列表Bucket list
/// (详见:https://cloud.tencent.com/document/api/436/8291)
///
/// \param req GetService请求
/// \param resp GetService返回
///
/// \return 本次请求的调用情况(如状态码等)
CosResult GetService(const GetServiceReq& req, GetServiceResp* resp);
};
} // namespace qcloud_cos
#endif // SERVICEOP_H

View File

@@ -0,0 +1,52 @@
Use of this software is granted under one of the following two licenses,
to be chosen freely by the user.
1. Boost Software License - Version 1.0 - August 17th, 2003
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
2. The MIT License
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
#define RAPIDXML_ITERATORS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
#include "rapidxml.hpp"
namespace rapidxml
{
//! Iterator of child nodes of xml_node
template<class Ch>
class node_iterator
{
public:
typedef typename xml_node<Ch> value_type;
typedef typename xml_node<Ch> &reference;
typedef typename xml_node<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
node_iterator()
: m_node(0)
{
}
node_iterator(xml_node<Ch> *node)
: m_node(node->first_node())
{
}
reference operator *() const
{
assert(m_node);
return *m_node;
}
pointer operator->() const
{
assert(m_node);
return m_node;
}
node_iterator& operator++()
{
assert(m_node);
m_node = m_node->next_sibling();
return *this;
}
node_iterator operator++(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
node_iterator& operator--()
{
assert(m_node && m_node->previous_sibling());
m_node = m_node->previous_sibling();
return *this;
}
node_iterator operator--(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const node_iterator<Ch> &rhs)
{
return m_node == rhs.m_node;
}
bool operator !=(const node_iterator<Ch> &rhs)
{
return m_node != rhs.m_node;
}
private:
xml_node<Ch> *m_node;
};
//! Iterator of child attributes of xml_node
template<class Ch>
class attribute_iterator
{
public:
typedef typename xml_attribute<Ch> value_type;
typedef typename xml_attribute<Ch> &reference;
typedef typename xml_attribute<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
attribute_iterator()
: m_attribute(0)
{
}
attribute_iterator(xml_node<Ch> *node)
: m_attribute(node->first_attribute())
{
}
reference operator *() const
{
assert(m_attribute);
return *m_attribute;
}
pointer operator->() const
{
assert(m_attribute);
return m_attribute;
}
attribute_iterator& operator++()
{
assert(m_attribute);
m_attribute = m_attribute->next_attribute();
return *this;
}
attribute_iterator operator++(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
attribute_iterator& operator--()
{
assert(m_attribute && m_attribute->previous_attribute());
m_attribute = m_attribute->previous_attribute();
return *this;
}
attribute_iterator operator--(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const attribute_iterator<Ch> &rhs)
{
return m_attribute == rhs.m_attribute;
}
bool operator !=(const attribute_iterator<Ch> &rhs)
{
return m_attribute != rhs.m_attribute;
}
private:
xml_attribute<Ch> *m_attribute;
};
}
#endif

View File

@@ -0,0 +1,449 @@
#ifndef RAPIDXML_PRINT_HPP_INCLUDED
#define RAPIDXML_PRINT_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation
#include "rapidxml.hpp"
// Only include streams if not disabled
#ifndef RAPIDXML_NO_STREAMS
#include <ostream>
#include <iterator>
#endif
namespace rapidxml
{
///////////////////////////////////////////////////////////////////////
// Printing flags
const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
///////////////////////////////////////////////////////////////////////
// Internal
//! \cond internal
namespace internal
{
///////////////////////////////////////////////////////////////////////////
// Internal character operations
// Copy characters from given range to given output iterator
template<class OutIt, class Ch>
inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
{
while (begin != end)
*out++ = *begin++;
return out;
}
// Copy characters from given range to given output iterator and expand
// characters into references (&lt; &gt; &apos; &quot; &amp;)
template<class OutIt, class Ch>
inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
{
while (begin != end)
{
if (*begin == noexpand)
{
*out++ = *begin; // No expansion, copy character
}
else
{
switch (*begin)
{
case Ch('<'):
*out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('>'):
*out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('\''):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
break;
case Ch('"'):
*out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('&'):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
break;
default:
*out++ = *begin; // No expansion, copy character
}
}
++begin; // Step to next character
}
return out;
}
// Fill given output iterator with repetitions of the same character
template<class OutIt, class Ch>
inline OutIt fill_chars(OutIt out, int n, Ch ch)
{
for (int i = 0; i < n; ++i)
*out++ = ch;
return out;
}
// Find character
template<class Ch, Ch ch>
inline bool find_char(const Ch *begin, const Ch *end)
{
while (begin != end)
if (*begin++ == ch)
return true;
return false;
}
///////////////////////////////////////////////////////////////////////////
// Internal printing operations
template<class OutIt, class Ch>
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags);
template<class OutIt, class Ch>
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
// Print node
template<class OutIt, class Ch>
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print proper node type
switch (node->type())
{
// Document
case node_document:
out = print_children(out, node, flags, indent);
break;
// Element
case node_element:
out = print_element_node(out, node, flags, indent);
break;
// Data
case node_data:
out = print_data_node(out, node, flags, indent);
break;
// CDATA
case node_cdata:
out = print_cdata_node(out, node, flags, indent);
break;
// Declaration
case node_declaration:
out = print_declaration_node(out, node, flags, indent);
break;
// Comment
case node_comment:
out = print_comment_node(out, node, flags, indent);
break;
// Doctype
case node_doctype:
out = print_doctype_node(out, node, flags, indent);
break;
// Pi
case node_pi:
out = print_pi_node(out, node, flags, indent);
break;
// Unknown
default:
assert(0);
break;
}
// If indenting not disabled, add line break after node
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
// Return modified iterator
return out;
}
// Print children of the node
template<class OutIt, class Ch>
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
out = print_node(out, child, flags, indent);
return out;
}
// Print attributes of the node
template<class OutIt, class Ch>
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
{
(void)(flags); // 避免告警
for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
{
if (attribute->name() && attribute->value())
{
// Print attribute name
*out = Ch(' '), ++out;
out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
*out = Ch('='), ++out;
// Print attribute value using appropriate quote type
if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
{
*out = Ch('\''), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
*out = Ch('\''), ++out;
}
else
{
*out = Ch('"'), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
*out = Ch('"'), ++out;
}
}
}
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_data);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_cdata);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'); ++out;
*out = Ch('!'); ++out;
*out = Ch('['); ++out;
*out = Ch('C'); ++out;
*out = Ch('D'); ++out;
*out = Ch('A'); ++out;
*out = Ch('T'); ++out;
*out = Ch('A'); ++out;
*out = Ch('['); ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch(']'); ++out;
*out = Ch(']'); ++out;
*out = Ch('>'); ++out;
return out;
}
// Print element node
template<class OutIt, class Ch>
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_element);
// Print element name and attributes, if any
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
out = print_attributes(out, node, flags);
// If node is childless
if (node->value_size() == 0 && !node->first_node())
{
// Print childless node tag ending
*out = Ch('/'), ++out;
*out = Ch('>'), ++out;
}
else
{
// Print normal node tag ending
*out = Ch('>'), ++out;
// Test if node contains a single data node only (and no other nodes)
xml_node<Ch> *child = node->first_node();
if (!child)
{
// If node has no children, only print its value without indenting
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
}
else if (child->next_sibling() == 0 && child->type() == node_data)
{
// If node has a sole data child, only print its value without indenting
out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
}
else
{
// Print all children with full indenting
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
out = print_children(out, node, flags, indent + 1);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
}
// Print node end
*out = Ch('<'), ++out;
*out = Ch('/'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch('>'), ++out;
}
return out;
}
// Print declaration node
template<class OutIt, class Ch>
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print declaration start
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
*out = Ch('x'), ++out;
*out = Ch('m'), ++out;
*out = Ch('l'), ++out;
// Print attributes
out = print_attributes(out, node, flags);
// Print declaration end
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print comment node
template<class OutIt, class Ch>
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_comment);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print doctype node
template<class OutIt, class Ch>
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_doctype);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('D'), ++out;
*out = Ch('O'), ++out;
*out = Ch('C'), ++out;
*out = Ch('T'), ++out;
*out = Ch('Y'), ++out;
*out = Ch('P'), ++out;
*out = Ch('E'), ++out;
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('>'), ++out;
return out;
}
// Print pi node
template<class OutIt, class Ch>
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_pi);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
}
//! \endcond
///////////////////////////////////////////////////////////////////////////
// Printing
//! Prints XML to given output iterator.
//! \param out Output iterator to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output iterator pointing to position immediately after last character of printed text.
template<class OutIt, class Ch>
inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
{
return internal::print_node(out, &node, flags, 0);
}
#ifndef RAPIDXML_NO_STREAMS
//! Prints XML to given output stream.
//! \param out Output stream to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
{
print(std::ostream_iterator<Ch>(out), node, flags);
return out;
}
//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
//! \param out Output stream to print to.
//! \param node Node to be printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
{
return print(out, node);
}
#endif
}
#endif

View File

@@ -0,0 +1,122 @@
#ifndef RAPIDXML_UTILS_HPP_INCLUDED
#define RAPIDXML_UTILS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful
//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.
#include "rapidxml.hpp"
#include <vector>
#include <string>
#include <fstream>
#include <stdexcept>
namespace rapidxml
{
//! Represents data loaded from a file
template<class Ch = char>
class file
{
public:
//! Loads file into the memory. Data will be automatically destroyed by the destructor.
//! \param filename Filename to load.
file(const char *filename)
{
using namespace std;
// Open stream
basic_ifstream<Ch> stream(filename, ios::binary);
if (!stream)
throw runtime_error(string("cannot open file ") + filename);
stream.unsetf(ios::skipws);
// Determine stream size
stream.seekg(0, ios::end);
size_t size = stream.tellg();
stream.seekg(0);
// Load data and add terminating 0
m_data.resize(size + 1);
stream.read(&m_data.front(), static_cast<streamsize>(size));
m_data[size] = 0;
}
//! Loads file into the memory. Data will be automatically destroyed by the destructor
//! \param stream Stream to load from
file(std::basic_istream<Ch> &stream)
{
using namespace std;
// Load data and add terminating 0
stream.unsetf(ios::skipws);
m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>());
if (stream.fail() || stream.bad())
throw runtime_error("error reading stream");
m_data.push_back(0);
}
//! Gets file data.
//! \return Pointer to data of file.
Ch *data()
{
return &m_data.front();
}
//! Gets file data.
//! \return Pointer to data of file.
const Ch *data() const
{
return &m_data.front();
}
//! Gets file data size.
//! \return Size of file data, in characters.
std::size_t size() const
{
return m_data.size();
}
private:
std::vector<Ch> m_data; // File data
};
//! Counts children of node. Time complexity is O(n).
//! \return Number of children of node
template<class Ch>
inline std::size_t count_children(xml_node<Ch> *node)
{
xml_node<Ch> *child = node->first_node();
std::size_t count = 0;
while (child)
{
++count;
child = child->next_sibling();
}
return count;
}
//! Counts attributes of node. Time complexity is O(n).
//! \return Number of attributes of node
template<class Ch>
inline std::size_t count_attributes(xml_node<Ch> *node)
{
xml_attribute<Ch> *attr = node->first_attribute();
std::size_t count = 0;
while (attr)
{
++count;
attr = attr->next_attribute();
}
return count;
}
}
#endif

File diff suppressed because it is too large Load Diff

143
include/request/base_req.h Normal file
View File

@@ -0,0 +1,143 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/15/17
// Description:
#pragma once
#include <stdint.h>
#include <map>
#include <string>
#include "util/string_util.h"
namespace qcloud_cos {
/// \brief 封装Http请求
class BaseReq {
public:
typedef std::map<std::string, std::string> Str2StrMap;
public:
BaseReq();
virtual ~BaseReq() {}
/// \brief 设置请求头部
void AddHeader(const std::string& key, const std::string& value);
void AddHeaders(const Str2StrMap& user_headers);
/// \brief 获取请求头部
std::string GetHeader(const std::string& key) const;
const Str2StrMap& GetHeaders() const { return m_headers_map; }
/// \brief 清空请求头部
void ClearHeaders() { m_headers_map.clear(); }
/// \brief 设置请求参数
void AddParam(const std::string& key, const std::string& value);
void AddParams(const Str2StrMap& user_params);
/// \brief 获取请求参数
std::string GetParam(const std::string& key) const;
const Str2StrMap& GetParams() const { return m_params_map; };
/// \brief 清空请求参数
void ClearParams() { m_params_map.clear(); }
/// \brief 获取请求的http方法
std::string GetMethod() const { return m_method; }
/// \brief 设置请求的http方法
void SetMethod(const std::string& method) {
m_method = StringUtil::StringToUpper(method);
}
/// \brief 获取请求的body
std::string GetBody() const { return m_body; }
/// \brief 设置请求的body
void SetBody(const std::string& body) { m_body = body; }
/// \brief 获取Path
std::string GetPath() const { return m_path; }
/// \brief 设置Path
void SetPath(const std::string& path) { m_path = path; }
void SetConnTimeoutInms(uint64_t conn_timeout_in_ms) {
m_conn_timeout_in_ms = conn_timeout_in_ms;
}
uint64_t GetConnTimeoutInms() const { return m_conn_timeout_in_ms; }
void SetRecvTimeoutInms(uint64_t recv_timeout_in_ms) {
m_recv_timeout_in_ms = recv_timeout_in_ms;
}
uint64_t GetRecvTimeoutInms() const { return m_recv_timeout_in_ms; }
/// \brief 设置当前请求是否使用https
void SetHttps() { m_is_https = true; }
bool IsHttps() const { return m_is_https; }
void SetSSLCtxCallback(const SSLCtxCallback& ssl_ctx_cb, void *user_data) {
m_ssl_ctx_cb = ssl_ctx_cb;
m_user_data = user_data;
}
const SSLCtxCallback& GetSSLCtxCallback() const { return m_ssl_ctx_cb; }
void *GetSSLCtxCbData() const { return m_user_data; }
/// \brief set whether check content md5 each request, used for close range
/// download check
void SetCheckMD5(bool check_md5) { mb_check_md5 = check_md5; }
bool CheckMD5() const { return mb_check_md5; }
void SetCheckCRC64(bool check_crc64) { mb_check_crc64 = check_crc64; }
bool CheckCRC64() const { return mb_check_crc64; }
void SetCaLocation(const std::string& ca_location) { m_ca_location = ca_location; }
const std::string& GetCaLocation() const { return m_ca_location; }
void SetVerifyCert(bool verify_cert) { mb_verify_cert = verify_cert; }
bool GetVerifyCert() const { return mb_verify_cert; }
/// \brief 输出请求的header和param信息
std::string DebugString() const;
/// \brief 是否生成对header host
/// 是否对host进行签名默认为true您也可以选择不签入host
/// 但可能导致请求失败或安全漏洞
void SetSignHeaderHost(bool sign_header_host) {
m_sign_header_host = sign_header_host;
}
bool SignHeaderHost() const { return m_sign_header_host; }
protected:
// acl相关的请求供PutObjectACL和PutBucketACL使用
bool GenerateAclRequestBody(const Owner& owner, const std::vector<Grant>& acl,
std::string* body) const;
protected:
Str2StrMap m_headers_map;
Str2StrMap m_params_map;
std::string m_path;
std::string m_method;
std::string m_body;
uint64_t m_conn_timeout_in_ms;
uint64_t m_recv_timeout_in_ms;
bool m_is_https;
bool mb_check_md5; // default is true
bool mb_check_crc64; // default is false
bool mb_verify_cert; // default is true
bool m_sign_header_host; // 是否对header host进行签名
std::string m_ca_location;
SSLCtxCallback m_ssl_ctx_cb;
void* m_user_data;
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,929 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#ifndef BUCKET_REQ_H
#define BUCKET_REQ_H
#pragma once
#include "cos_defines.h"
#include "request/base_req.h"
#include "util/string_util.h"
#include "util/illegal_intercept.h"
namespace qcloud_cos {
class BucketReq : public BaseReq {
public:
BucketReq() : m_bucket_name("") {}
explicit BucketReq(const std::string& bucket_name) : m_bucket_name(bucket_name) {
if (!IllegalIntercept::CheckBucket(bucket_name)) {
throw std::invalid_argument("Invalid bucket_name argument :" + bucket_name);
}
}
virtual ~BucketReq() {}
// getter and setter
std::string GetBucketName() const { return m_bucket_name; }
void SetBucketName(const std::string& bucket_name) {
if (!IllegalIntercept::CheckBucket(bucket_name)) {
throw std::invalid_argument("Invalid bucket_name argument :" + bucket_name);
}
m_bucket_name = bucket_name;
}
virtual bool GenerateRequestBody(std::string* body) const { UNUSED_PARAM(body); return true; }
private:
std::string m_bucket_name;
};
class HeadBucketReq : public BucketReq {
public:
explicit HeadBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) {
m_method = "HEAD";
}
virtual ~HeadBucketReq() {}
};
class PutBucketReq : public BucketReq {
public:
explicit PutBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
}
virtual ~PutBucketReq() {}
/// 定义Bucket的ACL属性,有效值private,public-read-write,public-read
/// 默认值private
void SetXCosAcl(const std::string& str) { AddHeader("x-cos-acl", str); }
/// 赋予被授权者读的权限.格式x-cos-grant-read: id=" ",id=" ".
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>"
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantRead(const std::string& str) {
AddHeader("x-cos-grant-read", str);
}
/// 赋予被授权者写的权限,格式x-cos-grant-write: id=" ",id=" "./
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>",
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantWrite(const std::string& str) {
AddHeader("x-cos-grant-write", str);
}
/// 赋予被授权者读写权限.格式x-cos-grant-full-control: id=" ",id=" ".
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>",
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantFullControl(const std::string& str) {
AddHeader("x-cos-grant-full-control", str);
}
//设置桶为多az存储桶
void SetMAZBucket() {
std::string maz = "<CreateBucketConfiguration>";
maz += " <BucketAZConfig>MAZ</BucketAZConfig>";
maz += "</CreateBucketConfiguration>";
SetBody(maz);
}
};
class GetBucketReq : public BucketReq {
public:
explicit GetBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
}
virtual ~GetBucketReq() {}
/// \@brief 设置前缀,用来规定返回的文件前缀地址
void SetPrefix(const std::string& prefix) { AddParam("prefix", prefix); }
/// \brief 设置定界符,如果有 Prefix则将 Prefix 到 delimiter
/// 之间的相同路径归为一类,
/// 定义为 Common Prefix然后列出所有 Common Prefix。如果没有
/// Prefix则从路径起点开始
void SetDelimiter(const std::string& delimiter) {
AddParam("delimiter", delimiter);
}
/// \brief 规定返回值的编码方式可选值url
void SetEncodingType(const std::string& encoding_type) {
AddParam("encoding-type", encoding_type);
}
/// \brief 默认以 UTF-8 二进制顺序列出条目所有列出条目从marker开始
void SetMarker(const std::string& marker) { AddParam("marker", marker); }
/// \brief 单次返回最大的条目数量默认1000
void SetMaxKeys(uint64_t max_keys) {
AddParam("max-keys", StringUtil::Uint64ToString(max_keys));
}
};
class ListMultipartUploadReq : public BucketReq {
public:
explicit ListMultipartUploadReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("uploads", "");
}
virtual ~ListMultipartUploadReq() {}
void SetPrefix(const std::string& prefix) { AddParam("prefix", prefix); }
void SetDelimiter(const std::string& delimiter) {
AddParam("delimiter", delimiter);
}
void SetEncodingType(const std::string& encoding_type) {
AddParam("encoding-type", encoding_type);
}
void SetKeyMarker(const std::string& marker) {
AddParam("key-marker", marker);
}
void SetMaxUploads(const std::string& max_uploads) {
AddParam("max-uploads", max_uploads);
}
void SetUploadIdMarker(const std::string& upload_id_marker) {
AddParam("upload-id-marker", upload_id_marker);
}
};
class DeleteBucketReq : public BucketReq {
public:
explicit DeleteBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("DELETE");
}
~DeleteBucketReq() {}
};
class GetBucketVersioningReq : public BucketReq {
public:
explicit GetBucketVersioningReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("versioning", "");
}
virtual ~GetBucketVersioningReq() {}
};
class PutBucketVersioningReq : public BucketReq {
public:
explicit PutBucketVersioningReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_status(true) {
SetMethod("PUT");
SetPath("/");
AddParam("versioning", "");
}
virtual ~PutBucketVersioningReq() {}
/// \brief 版本是否开启
void SetStatus(bool is_enable) { m_status = is_enable; }
bool GetStatus() const { return m_status; }
bool GenerateRequestBody(std::string* body) const;
private:
bool m_status;
};
class GetBucketReplicationReq : public BucketReq {
public:
explicit GetBucketReplicationReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("replication", "");
}
virtual ~GetBucketReplicationReq() {}
};
class PutBucketReplicationReq : public BucketReq {
public:
explicit PutBucketReplicationReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("replication", "");
}
virtual ~PutBucketReplicationReq() {}
void SetRole(const std::string& role) { m_role = role; }
void AddReplicationRule(const ReplicationRule& rule) {
m_rules.push_back(rule);
}
void SetReplicationRule(const std::vector<ReplicationRule>& rules) {
m_rules = rules;
}
bool GenerateRequestBody(std::string* body) const;
private:
std::string m_role;
std::vector<ReplicationRule> m_rules;
};
class DeleteBucketReplicationReq : public BucketReq {
public:
explicit DeleteBucketReplicationReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("Delete");
SetPath("/");
AddParam("replication", "");
}
virtual ~DeleteBucketReplicationReq() {}
};
class GetBucketLifecycleReq : public BucketReq {
public:
explicit GetBucketLifecycleReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("lifecycle", "");
}
virtual ~GetBucketLifecycleReq() {}
};
class PutBucketLifecycleReq : public BucketReq {
public:
explicit PutBucketLifecycleReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("lifecycle", "");
}
virtual ~PutBucketLifecycleReq() {}
void AddRule(const LifecycleRule& rule) { m_rules.push_back(rule); }
void SetRule(const std::vector<LifecycleRule>& rules) { m_rules = rules; }
bool GenerateRequestBody(std::string* body) const;
private:
std::vector<LifecycleRule> m_rules;
};
class DeleteBucketLifecycleReq : public BucketReq {
public:
explicit DeleteBucketLifecycleReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("DELETE");
SetPath("/");
AddParam("lifecycle", "");
}
virtual ~DeleteBucketLifecycleReq() {}
};
class GetBucketACLReq : public BucketReq {
public:
explicit GetBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("acl", "");
}
virtual ~GetBucketACLReq() {}
};
class PutBucketACLReq : public BucketReq {
public:
explicit PutBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("acl", "");
}
virtual ~PutBucketACLReq() {}
/// 定义Bucket的ACL属性,有效值private,public-read-write,public-read
/// 默认值private
void SetXCosAcl(const std::string& str) { AddHeader("x-cos-acl", str); }
/// 赋予被授权者读的权限.格式x-cos-grant-read: id=" ",id=" ".
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>"
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantRead(const std::string& str) {
AddHeader("x-cos-grant-read", str);
}
/// 赋予被授权者写的权限,格式x-cos-grant-write: id=" ",id=" "./
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>",
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantWrite(const std::string& str) {
AddHeader("x-cos-grant-write", str);
}
/// 赋予被授权者读写权限.格式x-cos-grant-full-control: id=" ",id=" ".
/// 当需要给子账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<SubUin>",
/// 当需要给根账户授权时,id="qcs::cam::uin/<OwnerUin>:uin/<OwnerUin>"
void SetXCosGrantFullControl(const std::string& str) {
AddHeader("x-cos-grant-full-control", str);
}
/// Bucket 持有者 ID
void SetOwner(const Owner& owner) { m_owner = owner; }
/// 设置被授权者信息与权限信息
void SetAccessControlList(const std::vector<Grant>& grants) {
m_acl = grants;
}
/// 添加单个 Bucket 的授权信息
void AddAccessControlList(const Grant& grant) { m_acl.push_back(grant); }
/// 清空权限信息
void ClearAccessControlList() {
std::vector<Grant> tmp;
m_acl.swap(tmp);
}
bool GenerateRequestBody(std::string* body) const;
private:
Owner m_owner;
std::vector<Grant> m_acl;
};
class GetBucketPolicyReq : public BucketReq {
public:
explicit GetBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("policy", "");
}
virtual ~GetBucketPolicyReq() {}
};
class PutBucketPolicyReq : public BucketReq {
public:
explicit PutBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("policy", "");
}
virtual ~PutBucketPolicyReq() {}
};
class DeleteBucketPolicyReq : public BucketReq {
public:
explicit DeleteBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("DELETE");
SetPath("/");
AddParam("policy", "");
}
virtual ~DeleteBucketPolicyReq() {}
};
class DeleteBucketACLReq : public BucketReq {
public:
explicit DeleteBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("DELETE");
}
virtual ~DeleteBucketACLReq() {}
};
class GetBucketCORSReq : public BucketReq {
public:
explicit GetBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("cors", "");
}
virtual ~GetBucketCORSReq() {}
};
class PutBucketCORSReq : public BucketReq {
public:
explicit PutBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("cors", "");
AddHeader("Content-Type", "application/xml");
}
virtual ~PutBucketCORSReq() {}
bool GenerateRequestBody(std::string* body) const;
void AddRule(const CORSRule& rule) { m_rules.push_back(rule); }
void SetRules(const std::vector<CORSRule>& rules) { m_rules = rules; }
private:
std::vector<CORSRule> m_rules;
};
class DeleteBucketCORSReq : public BucketReq {
public:
explicit DeleteBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("DELETE");
SetPath("/");
AddParam("cors", "");
}
virtual ~DeleteBucketCORSReq() {}
};
class GetBucketLocationReq : public BucketReq {
public:
explicit GetBucketLocationReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("location", "");
}
virtual ~GetBucketLocationReq() {}
};
class GetBucketObjectVersionsReq : public BucketReq {
public:
explicit GetBucketObjectVersionsReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("versions", "");
}
virtual ~GetBucketObjectVersionsReq() {}
/// \@brief 设置前缀,用来规定返回的文件前缀地址
void SetPrefix(const std::string& prefix) { AddParam("prefix", prefix); }
/// \brief 设置定界符,如果有 Prefix则将 Prefix 到 delimiter
/// 之间的相同路径归为一类,
/// 定义为 Common Prefix然后列出所有 Common Prefix。如果没有
/// Prefix则从路径起点开始
void SetDelimiter(const std::string& delimiter) {
AddParam("delimiter", delimiter);
}
/// \brief 规定返回值的编码方式可选值url
void SetEncodingType(const std::string& encoding_type) {
AddParam("encoding-type", encoding_type);
}
/// \brief 默认以 UTF-8 二进制顺序列出条目所有列出条目从marker开始
void SetKeyMarker(const std::string& marker) {
AddParam("key-marker", marker);
}
/// \brief 单次返回最大的条目数量默认1000
void SetMaxKeys(uint64_t max_keys) {
AddParam("max-keys", StringUtil::Uint64ToString(max_keys));
}
void SetVersionIdMarker(const std::string& version_id_marker) {
AddParam("version-id-marker", version_id_marker);
}
};
class PutBucketLoggingReq : public BucketReq {
public:
explicit PutBucketLoggingReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_mask(0x00000000u) {
SetMethod("PUT");
SetPath("/");
AddParam("logging", "");
}
virtual ~PutBucketLoggingReq() {}
void SetLoggingEnabled(const LoggingEnabled& rules) {
m_mask = m_mask | 0x00000001u;
m_rules = rules;
}
bool HasLoggingEnabled() const { return (m_mask & 0x00000001u) != 0; }
bool GenerateRequestBody(std::string* body) const;
private:
uint64_t m_mask;
LoggingEnabled m_rules;
};
class GetBucketLoggingReq : public BucketReq {
public:
explicit GetBucketLoggingReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("logging", "");
}
virtual ~GetBucketLoggingReq() {}
};
class PutBucketDomainReq : public BucketReq {
public:
explicit PutBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("domain", "");
}
virtual ~PutBucketDomainReq() {}
void SetDomainRule(const DomainRule& rules) { m_rules = rules; }
bool GenerateRequestBody(std::string* body) const;
private:
DomainRule m_rules;
};
class GetBucketDomainReq : public BucketReq {
public:
explicit GetBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("domain", "");
}
virtual ~GetBucketDomainReq() {}
};
class PutBucketWebsiteReq : public BucketReq {
public:
explicit PutBucketWebsiteReq(const std::string& bucket_name)
: BucketReq(bucket_name),
m_mask(0x00000000u),
m_suffix(""),
m_protocol(""),
m_key("") {
SetMethod("PUT");
SetPath("/");
AddParam("website", "");
}
virtual ~PutBucketWebsiteReq() {}
void SetSuffix(const std::string& suffix) {
m_mask = m_mask | 0x00000001u;
m_suffix = suffix;
}
void SetProtocol(const std::string& protocol) {
m_mask = m_mask | 0x00000002u;
m_protocol = protocol;
}
void SetKey(const std::string& key) {
m_mask = m_mask | 0x00000004u;
m_key = key;
}
std::string GetSuffix() const { return m_suffix; }
std::string GetProtocol() const { return m_protocol; }
std::string GetKey() const { return m_key; }
bool HasSuffix() const { return (m_mask & 0x00000001u) != 0; }
bool HasProtocol() const { return (m_mask & 0x00000002u) != 0; }
bool HasKey() const { return (m_mask & 0x00000004u) != 0; }
bool HasRoutingRules() const { return !m_routingrules.empty(); }
/// 设置重定向规则
void SetRoutingRules(const std::vector<RoutingRule>& routingrules) {
m_routingrules = routingrules;
}
/// 添加单个rule
void AddRoutingRule(const RoutingRule& routingrule) {
m_routingrules.push_back(routingrule);
}
/// 清空重定向规则
void ClearRoutingRules() {
std::vector<RoutingRule> tmp;
m_routingrules.swap(tmp);
}
bool GenerateRequestBody(std::string* body) const;
private:
uint64_t m_mask;
std::string m_suffix;
std::string m_protocol;
std::string m_key;
std::vector<RoutingRule> m_routingrules;
};
class GetBucketWebsiteReq : public BucketReq {
public:
explicit GetBucketWebsiteReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("Get");
SetPath("/");
AddParam("website", "");
}
virtual ~GetBucketWebsiteReq() {}
};
class DeleteBucketWebsiteReq : public BucketReq {
public:
explicit DeleteBucketWebsiteReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("DELETE");
SetPath("/");
AddParam("website", "");
}
virtual ~DeleteBucketWebsiteReq() {}
};
class PutBucketTaggingReq : public BucketReq {
public:
explicit PutBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("tagging", "");
}
void SetTagSet(std::vector<Tag>& tagset) { m_tagset = tagset; }
std::vector<Tag> GetTagSet() { return m_tagset; }
//清除tag规则.
void ClearTagSet() {
std::vector<Tag> temp;
m_tagset.swap(temp);
}
/// 添加单个tag.
void AddTag(const Tag& tag) { m_tagset.push_back(tag); }
bool GenerateRequestBody(std::string* body) const;
virtual ~PutBucketTaggingReq() {}
private:
std::vector<Tag> m_tagset;
};
class GetBucketTaggingReq : public BucketReq {
public:
explicit GetBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("tagging", "");
}
virtual ~GetBucketTaggingReq() {}
};
class DeleteBucketTaggingReq : public BucketReq {
public:
explicit DeleteBucketTaggingReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("DELETE");
SetPath("/");
AddParam("tagging", "");
}
virtual ~DeleteBucketTaggingReq() {}
};
class PutBucketInventoryReq : public BucketReq {
public:
explicit PutBucketInventoryReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_mask(0x00000000u) {
SetMethod("PUT");
SetPath("/");
AddParam("inventory", "");
}
void SetInventory(Inventory& inventory) {
m_mask = m_mask | 0x00000001u;
m_inventory = inventory;
}
bool HasInventory() const { return (m_mask & 0x00000001u) != 0; }
const Inventory& GetInventory() const { return m_inventory; }
void SetId(const std::string id) {
m_mask = m_mask | 0x00000001u;
m_id = id;
AddParam("id", m_id);
}
std::string GetId() const { return m_id; }
bool HasId() const { return (m_mask & 0x00000001u) != 0; }
bool GenerateRequestBody(std::string* body) const;
virtual ~PutBucketInventoryReq() {}
private:
uint64_t m_mask;
std::string m_id;
Inventory m_inventory;
};
class GetBucketInventoryReq : public BucketReq {
public:
explicit GetBucketInventoryReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_mask(0x00000000u) {
SetMethod("GET");
SetPath("/");
AddParam("inventory", "");
}
void SetId(const std::string id) {
m_mask = m_mask | 0x00000001u;
m_id = id;
AddParam("id", m_id);
}
std::string GetId() const { return m_id; }
bool HasId() const { return (m_mask & 0x00000001u) != 0; }
virtual ~GetBucketInventoryReq() {}
private:
uint64_t m_mask;
std::string m_id;
};
class ListBucketInventoryConfigurationsReq : public BucketReq {
public:
explicit ListBucketInventoryConfigurationsReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_mask(0x00000000u) {
SetMethod("GET");
SetPath("/");
AddParam("inventory", "");
}
void SetContinuationToken(const std::string continuation_token) {
m_mask = m_mask | 0x00000001u;
m_continuation_token = continuation_token;
AddParam("continuation-token", m_continuation_token);
}
std::string GetContinuationToken() const { return m_continuation_token; }
bool HasContinuationToken() const { return (m_mask & 0x00000001u) != 0; }
virtual ~ListBucketInventoryConfigurationsReq() {}
private:
uint64_t m_mask;
std::string m_continuation_token;
};
class DeleteBucketInventoryReq : public BucketReq {
public:
explicit DeleteBucketInventoryReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_mask(0x00000000u), m_id("") {
SetMethod("DELETE");
SetPath("/");
AddParam("inventory", "");
}
void SetId(const std::string id) {
m_mask = m_mask | 0x00000001u;
m_id = id;
AddParam("id", m_id);
}
std::string GetId() const { return m_id; }
bool HasId() const { return (m_mask & 0x00000001u) != 0; }
virtual ~DeleteBucketInventoryReq() {}
private:
uint64_t m_mask;
std::string m_id;
};
/// \brief: 列举直播通道请求
class ListLiveChannelReq : public BucketReq {
public:
explicit ListLiveChannelReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("live", "");
}
void SetMaxKeys(uint32_t max_keys) {
AddParam("max-keys", StringUtil::IntToString(max_keys));
}
void SetMarker(const std::string& marker) { AddParam("marker", marker); }
void SetPrefix(const std::string& prefix) { AddParam("prefix", prefix); }
virtual ~ListLiveChannelReq() {}
};
/// \brief: 配置存储桶智能分层特性
class PutBucketIntelligentTieringReq : public BucketReq {
public:
explicit PutBucketIntelligentTieringReq(const std::string& bucket_name)
: BucketReq(bucket_name), m_status(false), m_days(30) {
SetMethod("PUT");
SetPath("/");
AddParam("intelligenttiering", "");
}
virtual ~PutBucketIntelligentTieringReq() {}
/// \brief 设置智能分层的状态true表示Enabledfalse表示Suspended
void SetStatus(bool is_enable) { m_status = is_enable; }
/// \brief
/// 指定智能分层存储配置中标准层数据转换为低频层数据的天数限制默认值为30天
void SetDays(uint32_t days) { m_days = days; }
bool GenerateRequestBody(std::string* body) const;
private:
bool m_status;
uint32_t m_days;
};
/// \brief: 获取存储桶智能分层配置
class GetBucketIntelligentTieringReq : public BucketReq {
public:
explicit GetBucketIntelligentTieringReq(const std::string& bucket_name)
: BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("intelligenttiering", "");
}
virtual ~GetBucketIntelligentTieringReq() {}
};
class PutBucketRefererReq : public BucketReq {
public:
explicit PutBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("PUT");
SetPath("/");
AddParam("referer", "");
}
/// \brief 是否开启防盗链枚举值Enabled、Disabled
void SetStatus(const std::string& status) { m_status = status; }
/// \brief 防盗链类型枚举值Black-List、White-List
void SetRefererType(const std::string& referer_type) {
m_referer_type = referer_type;
}
/// \brief 生效域名列表, 支持多个域名且为前缀匹配, 支持带端口的域名和 IP
/// 支持通配符*,做二级域名或多级域名的通配
void AddDomain(const std::string& domain) { m_domain_list.push_back(domain); }
/// \brief 是否允许空 Referer 访问枚举值Allow、Deny默认值为 Deny
void SetEmptyReferConfig(const std::string& empty_refer_conf) {
m_empty_refer_conf = empty_refer_conf;
}
bool GenerateRequestBody(std::string* body) const;
virtual ~PutBucketRefererReq() {}
private:
std::string m_status;
std::string m_referer_type;
std::vector<std::string> m_domain_list;
std::string m_empty_refer_conf;
};
class GetBucketRefererReq : public BucketReq {
public:
explicit GetBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) {
SetMethod("GET");
SetPath("/");
AddParam("referer", "");
}
virtual ~GetBucketRefererReq() {}
};
} // namespace qcloud_cos
#endif // BUCKET_REQ_H

File diff suppressed because it is too large Load Diff

1947
include/request/object_req.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 11/14/17
// Description:
#ifndef SERVICE_REQ_H
#define SERVICE_REQ_H
#pragma once
#include "cos_defines.h"
#include "request/base_req.h"
#include "util/string_util.h"
namespace qcloud_cos {
class GetServiceReq : public BaseReq {
public:
GetServiceReq() {
SetMethod("GET");
SetPath("/");
}
virtual ~GetServiceReq() {}
};
} // namespace qcloud_cos
#endif // SERVICE_REQ_H

View File

@@ -0,0 +1,216 @@
#pragma once
#include <sstream>
#include <string>
#include <vector>
#include "rapidxml/1.13/rapidxml.hpp"
#include "rapidxml/1.13/rapidxml_print.hpp"
#include "rapidxml/1.13/rapidxml_utils.hpp"
#include "request/auditing_req.h"
#include "response/object_resp.h"
namespace qcloud_cos {
class AuditingResp: public BaseResp {
public:
AuditingResp() {}
virtual ~AuditingResp() {}
virtual bool ParseFromXmlString(const std::string& body) { UNUSED_PARAM(body); return true;};
protected:
static bool ParseSceneResultInfo(rapidxml::xml_node<>* root, SceneResultInfo& scene_result_info);
static bool ParseOcrResultInfo(rapidxml::xml_node<>* root, OcrResult& ocr_results);
static bool ParseLocation(rapidxml::xml_node<>* root, Location& location);
static bool ParseUserInfo(rapidxml::xml_node<>* root, UserInfo& user_info);
static bool ParseSegmentResult(rapidxml::xml_node<>* root, SegmentResult& segment_result);
static bool ParseResults(rapidxml::xml_node<>* root, Result& result);
static bool ParseObjectResults(rapidxml::xml_node<>* root, ObjectResults& object_results);
static bool ParseRecognitionResult(rapidxml::xml_node<>* root, RecognitionResult& result);
static bool ParseListInfo(rapidxml::xml_node<>* root, ListInfo& list_info);
};
class AuditingJobResp : public AuditingResp {
public:
AuditingJobResp() {}
virtual ~AuditingJobResp() {}
virtual bool ParseFromXmlString(const std::string& body);
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root) { UNUSED_PARAM(root); return true;};
std::string GetRequestId() const { return m_request_id; }
protected:
std::string m_request_id;
};
class ImageAuditingResp : public AuditingJobResp {
public:
ImageAuditingResp() {}
virtual ~ImageAuditingResp() {}
virtual bool ParseFromXmlString(const std::string& body) { UNUSED_PARAM(body); return true; }
static bool ParseImageAuditingJobsDetail(rapidxml::xml_node<>* root, ImageAuditingJobsDetail& jobs_detail);
};
class GetImageAuditingResp : public ImageAuditingResp {
public:
GetImageAuditingResp() {}
virtual ~GetImageAuditingResp() {}
virtual bool ParseFromXmlString(const std::string& body);
ImageAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
private:
ImageAuditingJobsDetail m_jobs_detail;
};
class BatchImageAuditingResp : public ImageAuditingResp {
public:
BatchImageAuditingResp() {}
virtual ~BatchImageAuditingResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::vector<ImageAuditingJobsDetail> GetJobsDetails() const { return m_jobs_details; }
private:
std::vector<ImageAuditingJobsDetail> m_jobs_details;
};
class DescribeImageAuditingJobResp : public ImageAuditingResp {
public:
DescribeImageAuditingJobResp() {}
virtual ~DescribeImageAuditingJobResp() {}
virtual bool ParseFromXmlString(const std::string& body);
ImageAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
private:
ImageAuditingJobsDetail m_jobs_detail;
std::string m_request_id;
};
class VideoAuditingResp : public AuditingJobResp {
public:
VideoAuditingResp() {}
virtual ~VideoAuditingResp() {}
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root);
VideoAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
VideoAuditingJobsDetail m_jobs_detail;
};
class CreateVideoAuditingJobResp : public VideoAuditingResp {
public:
CreateVideoAuditingJobResp() {}
virtual ~CreateVideoAuditingJobResp() {}
};
class DescribeVideoAuditingJobResp : public VideoAuditingResp {
public:
DescribeVideoAuditingJobResp() {}
virtual ~DescribeVideoAuditingJobResp() {}
};
class AudioAuditingResp : public AuditingJobResp {
public:
AudioAuditingResp() {}
virtual ~AudioAuditingResp() {}
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root);
AudioAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
AudioAuditingJobsDetail m_jobs_detail;
};
class CreateAudioAuditingJobResp : public AudioAuditingResp {
public:
CreateAudioAuditingJobResp() {}
virtual ~CreateAudioAuditingJobResp() {}
};
class DescribeAudioAuditingJobResp : public AudioAuditingResp {
public:
DescribeAudioAuditingJobResp() {}
virtual ~DescribeAudioAuditingJobResp() {}
};
class TextAuditingResp : public AuditingJobResp {
public:
TextAuditingResp() {}
virtual ~TextAuditingResp() {}
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root);
TextAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
TextAuditingJobsDetail m_jobs_detail;
};
class CreateTextAuditingJobResp : public TextAuditingResp {
public:
CreateTextAuditingJobResp() {}
virtual ~CreateTextAuditingJobResp() {}
};
class DescribeTextAuditingJobResp : public TextAuditingResp {
public:
DescribeTextAuditingJobResp() {}
virtual ~DescribeTextAuditingJobResp() {}
};
class DocumentAuditingResp : public AuditingJobResp {
public:
DocumentAuditingResp() {}
virtual ~DocumentAuditingResp() {}
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root);
DocumentAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
DocumentAuditingJobsDetail m_jobs_detail;
};
class CreateDocumentAuditingJobResp : public DocumentAuditingResp {
public:
CreateDocumentAuditingJobResp() {}
virtual ~CreateDocumentAuditingJobResp() {}
};
class DescribeDocumentAuditingJobResp : public DocumentAuditingResp {
public:
DescribeDocumentAuditingJobResp() {}
virtual ~DescribeDocumentAuditingJobResp() {}
};
class WebPageAuditingResp : public AuditingJobResp {
public:
WebPageAuditingResp() {}
virtual ~WebPageAuditingResp() {}
virtual bool ParseJobsDetail(rapidxml::xml_node<>* root);
WebPageAuditingJobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
WebPageAuditingJobsDetail m_jobs_detail;
};
class CreateWebPageAuditingJobResp : public WebPageAuditingResp {
public:
CreateWebPageAuditingJobResp() {}
virtual ~CreateWebPageAuditingJobResp() {}
};
class DescribeWebPageAuditingJobResp : public WebPageAuditingResp {
public:
DescribeWebPageAuditingJobResp() {}
virtual ~DescribeWebPageAuditingJobResp() {}
};
}

View File

@@ -0,0 +1,233 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/18/17
// Description:
#ifndef BASERESP_H
#define BASERESP_H
#pragma once
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include "cos_defines.h"
#include "cos_params.h"
#include "util/string_util.h"
namespace qcloud_cos {
typedef std::map<std::string, std::string> StringMap;
typedef StringMap::const_iterator citerator;
// 封装HTTP调用成功时的返回信息, 包括header和body
// CosResult::IsSucc返回true时, 调用其子类的Get方法获取具体字段
class BaseResp {
public:
BaseResp()
: m_content_length(0), m_x_cos_storage_class(kStorageClassStandard) {}
BaseResp(const BaseResp& rhs) { InternalCopyFrom(rhs); }
BaseResp& operator=(const BaseResp& rhs) {
if (&rhs != this) {
InternalCopyFrom(rhs);
}
return *this;
}
virtual ~BaseResp() {}
// debug使用
virtual std::string DebugString() const {
std::string ret;
for (std::map<std::string, std::string>::const_iterator c_itr =
m_headers.begin();
c_itr != m_headers.end(); ++c_itr) {
ret += c_itr->first + " = " + c_itr->second + "\n";
}
ret += m_body_str;
return ret;
}
std::string GetHeader(const std::string& key) const;
std::map<std::string, std::string> GetHeaders() const { return m_headers; }
std::map<std::string, std::string>* GetHeadersPtr() { return &m_headers; }
void SetHeaders(const std::map<std::string, std::string>& headers) {
m_headers = headers;
}
// ==========================头部相关==============================
// TODO 头部可以不需要解析
virtual void ParseFromHeaders(
const std::map<std::string, std::string>& headers);
uint64_t GetContentLength() const {
citerator cit = m_headers.find(kHttpHeaderContentLength);
if (m_headers.end() != cit) {
return StringUtil::StringToUint64(cit->second);
} else {
return 0;
}
}
std::string GetContentRange() const {
return GetHeader(kHttpHeaderContentRange);
}
std::string GetContentType() const {
return GetHeader(kHttpHeaderContentType);
}
std::string GetEtag() const {
std::string etag;
citerator cit = m_headers.find(kHttpHeaderEtag);
if (m_headers.end() != cit) {
etag = StringUtil::Trim(cit->second, "\"");
} else {
// 某些代理软件可能会修改HTTP Header比如把ETag改成Etag
// 此处找不到ETag再尝试查找Etag
cit = m_headers.find(kHttpHeaderLowerCaseEtag);
if (m_headers.end() != cit) {
etag = StringUtil::Trim(cit->second, "\"");
}
}
return etag;
}
std::string GetConnection() const { return GetHeader(kHttpHeaderConnection); }
std::string GetDate() const { return GetHeader(kHttpHeaderDate); }
std::string GetServer() const { return GetHeader(kHttpHeaderServer); }
std::string GetXCosTaggingCount() const {
return GetHeader(kRespHeaderXCosTaggingCount);
}
std::string GetContentDisposition() const {
return GetHeader(kHttpHeaderContentDisposition);
}
std::string GetContentEncoding() const {
return GetHeader(kHttpHeaderContentEncoding);
}
std::string GetCacheControl() const {
return GetHeader(kHttpHeaderCacheControl);
}
std::string GetExpires() const { return GetHeader(kHttpHeaderExpires); }
std::string GetXCosRequestId() const {
return GetHeader(kRespHeaderXCosReqId);
}
std::string GetXCosTraceId() const {
return GetHeader(kRespHeaderXCosTraceId);
}
std::string GetXCosStorageTier() const {
return GetHeader(kRespHeaderXCosStorageTier);
}
/// \brief 获取Object 的存储类型
/// 枚举值MAZ_STANDARDMAZ_STANDARD_IAINTELLIGENT_TIERINGMAZ_INTELLIGENT_TIERINGSTANDARD_IAARCHIVEDEEP_ARCHIVE
std::string GetXCosStorageClass() const {
return GetHeader(kRespHeaderXCosStorageClass);
}
std::string GetXCosHashCrc64Ecma() const {
return GetHeader(kRespHeaderXCosHashCrc64Ecma);
}
/// \brief 获取object最后被修改的时间, 字符串格式Date, 类似"Wed, 28 Oct 2014
/// 20:30:00 GMT"
std::string GetLastModified() const {
return GetHeader(kRespHeaderLastModified);
}
void SetContentLength(uint64_t content_length) {
m_headers[kHttpHeaderContentLength] =
StringUtil::Uint64ToString(content_length);
}
void SetContentType(const std::string& content_type) {
m_headers[kHttpHeaderContentType] = content_type;
}
void SetEtag(const std::string& etag) { m_headers[kHttpHeaderEtag] = etag; }
void SetConnection(const std::string& conn) {
m_headers[kHttpHeaderConnection] = conn;
}
void SetDate(const std::string& date) { m_headers[kHttpHeaderDate] = date; }
void SetServer(const std::string& server) {
m_headers[kHttpHeaderServer] = server;
}
void SetContentDisposition(const std::string& content_disposition) {
m_headers[kHttpHeaderContentDisposition] = content_disposition;
}
void SetContentEncoding(const std::string& content_encoding) {
m_headers[kHttpHeaderContentEncoding] = content_encoding;
}
void SetCacheControl(const std::string& cache_control) {
m_headers[kHttpHeaderCacheControl] = cache_control;
}
void SetExpires(const std::string& expires) {
m_headers[kHttpHeaderExpires] = expires;
}
void SetXCosTraceId(const std::string& trace_id) {
m_headers[kRespHeaderXCosTraceId] = trace_id;
}
void SetXCosRequestId(const std::string& request_id) {
m_headers[kRespHeaderXCosReqId] = request_id;
}
void SetXCosStorageTier(const std::string& storage_tier) {
m_headers[kRespHeaderXCosStorageTier] = storage_tier;
}
void SetXCosStorageClass(const std::string& storage_class) {
m_headers[kRespHeaderXCosStorageClass] = storage_class;
}
void SetXCosHashCrc64Ecma(const std::string& crc64) {
m_headers[kRespHeaderXCosHashCrc64Ecma] = crc64;
}
void SetLastModified(const std::string& last_modified) {
m_headers[kRespHeaderLastModified] = last_modified;
}
// ==========================响应体================================
// 解析响应体的XML字符串
virtual bool ParseFromXmlString(const std::string& body) {
m_body_str = body;
return true;
}
void SetBody(const std::string& body) { m_body_str = body; }
const std::string& GetBody() const { return m_body_str; }
std::string* GetBodyPtr() { return &m_body_str; }
void CopyFrom(const BaseResp& resp) { InternalCopyFrom(resp); }
protected:
std::string GetHeader(const std::string& key) {
citerator cit = m_headers.find(key);
if (m_headers.end() != cit) {
return cit->second;
}
return "";
}
bool ParseFromACLXMLString(const std::string& body, std::string* owner_id,
std::string* owner_display_name,
std::vector<Grant>* acl);
void InternalCopyFrom(const BaseResp& resp);
private:
std::map<std::string, std::string> m_headers;
std::string m_body_str;
// 公共头部字段
uint64_t m_content_length;
std::string m_content_range;
std::string m_content_type;
std::string m_etag;
std::string m_connection;
std::string m_date;
std::string m_server;
std::string m_content_disposition;
std::string m_content_encoding;
std::string m_cache_control;
std::string m_expires;
std::string m_last_modified;
// cos响应头部
std::string m_x_cos_request_id;
std::string m_x_cos_trace_id;
std::string m_x_cos_storage_tier;
std::string m_x_cos_storage_class;
std::string m_x_cos_hash_crc64ecma;
};
} // namespace qcloud_cos
#endif // BASERESP_H

View File

@@ -0,0 +1,646 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#ifndef BUCKET_RESP_H
#define BUCKET_RESP_H
#pragma once
#include <vector>
#include "cos_config.h"
#include "cos_defines.h"
#include "rapidxml/1.13/rapidxml.hpp"
#include "rapidxml/1.13/rapidxml_print.hpp"
#include "rapidxml/1.13/rapidxml_utils.hpp"
#include "response/base_resp.h"
namespace qcloud_cos {
class PutBucketResp : public BaseResp {
public:
PutBucketResp() {}
virtual ~PutBucketResp() {}
};
class HeadBucketResp : public BaseResp {
public:
HeadBucketResp() {}
virtual ~HeadBucketResp() {}
};
class GetBucketResp : public BaseResp {
public:
GetBucketResp() {}
virtual ~GetBucketResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 获取Bucket中Object对应的元信息
std::vector<Content> GetContents() const { return m_contents; }
/// \brief Bucket名称
std::string GetName() const { return m_name; }
/// \brief 获取定界符
std::string GetDelimiter() const { return m_delimiter; }
/// \brief 编码格式
std::string GetEncodingType() const { return m_encoding_type; }
/// \brief 返回的文件前缀
std::string GetPrefix() const { return m_prefix; }
/// \brief 默认以UTF-8二进制顺序列出条目所有列出条目从marker开始
std::string GetMarker() const { return m_marker; }
/// \brief 单次响应请求内返回结果的最大的条目数量
uint64_t GetMaxKeys() const { return m_max_keys; }
/// \brief 响应请求条目是否被截断布尔值truefalse
bool IsTruncated() const { return m_is_truncated; }
/// \brief 假如返回条目被截断,则返回 NextMarker 就是下一个条目的起点
std::string GetNextMarker() const { return m_next_marker; }
/// \brief 将 Prefix 到 delimiter 之间的相同路径归为一类,定义为 Common Prefix
std::vector<std::string> GetCommonPrefixes() const {
return m_common_prefixes;
}
private:
std::vector<Content> m_contents;
std::string m_name;
std::string m_encoding_type;
std::string m_delimiter;
std::string m_prefix;
std::string m_marker;
uint64_t m_max_keys;
bool m_is_truncated;
std::string m_next_marker;
std::vector<std::string> m_common_prefixes;
};
class DeleteBucketResp : public BaseResp {
public:
DeleteBucketResp() {}
virtual ~DeleteBucketResp() {}
};
class GetBucketVersioningResp : public BaseResp {
public:
GetBucketVersioningResp() : m_status(0) {}
virtual ~GetBucketVersioningResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 返回bucket的版本状态,0: 从未开启版本管理, 1: 版本管理生效中, 2:
/// 暂停 区别于PutBucketVersioning, 一个Bucket可能处于三种状态
int GetStatus() const { return m_status; }
private:
int m_status;
};
class PutBucketVersioningResp : public BaseResp {
public:
PutBucketVersioningResp() {}
virtual ~PutBucketVersioningResp() {}
};
class GetBucketReplicationResp : public BaseResp {
public:
GetBucketReplicationResp() {}
virtual ~GetBucketReplicationResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetRole() const { return m_role; }
std::vector<ReplicationRule> GetRules() const { return m_rules; }
private:
std::string m_role;
std::vector<ReplicationRule> m_rules;
};
class PutBucketReplicationResp : public BaseResp {
public:
PutBucketReplicationResp() {}
virtual ~PutBucketReplicationResp() {}
};
class DeleteBucketReplicationResp : public BaseResp {
public:
DeleteBucketReplicationResp() {}
virtual ~DeleteBucketReplicationResp() {}
};
class GetBucketLifecycleResp : public BaseResp {
public:
GetBucketLifecycleResp() {}
virtual ~GetBucketLifecycleResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::vector<LifecycleRule> GetRules() const { return m_rules; }
private:
std::vector<LifecycleRule> m_rules;
};
class PutBucketLifecycleResp : public BaseResp {
public:
PutBucketLifecycleResp() {}
virtual ~PutBucketLifecycleResp() {}
};
class DeleteBucketLifecycleResp : public BaseResp {
public:
DeleteBucketLifecycleResp() {}
virtual ~DeleteBucketLifecycleResp() {}
};
class GetBucketACLResp : public BaseResp {
public:
GetBucketACLResp() {}
virtual ~GetBucketACLResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetOwnerID() const { return m_owner_id; }
std::string GetOwnerDisplayName() const { return m_owner_display_name; }
std::vector<Grant> GetAccessControlList() const { return m_acl; }
private:
std::string m_owner_id;
std::string m_owner_display_name;
std::vector<Grant> m_acl;
};
// TODO
class ListMultipartUploadResp : public BaseResp {
public:
ListMultipartUploadResp() {}
virtual ~ListMultipartUploadResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 获取Bucket中Object对应的元信息
std::vector<Upload> GetUpload() const { return m_upload; }
/// \brief Bucket名称
std::string GetName() const { return m_name; }
/// \brief 编码格式
std::string GetEncodingType() const { return m_encoding_type; }
/// \brief 默认以UTF-8二进制顺序列出条目所有列出条目从marker开始
std::string GetMarker() const { return m_marker; }
std::string GetUploadIdMarker() const { return m_uploadid_marker; }
std::string GetNextKeyMarker() const { return m_nextkey_marker; }
std::string GetNextUploadIdMarker() const { return m_nextuploadid_marker; }
std::string GetMaxUploads() const { return m_max_uploads; }
/// \brief 响应请求条目是否被截断布尔值truefalse
bool IsTruncated() const { return m_is_truncated; }
/// \brief 返回的文件前缀
std::string GetPrefix() const { return m_prefix; }
/// \brief 获取定界符
std::string GetDelimiter() const { return m_delimiter; }
/// \brief 将 Prefix 到 delimiter 之间的相同路径归为一类,定义为 Common Prefix
std::vector<std::string> GetCommonPrefixes() const {
return m_common_prefixes;
}
private:
std::vector<Upload> m_upload;
std::string m_name;
std::string m_encoding_type;
std::string m_delimiter;
std::string m_prefix;
std::string m_marker;
std::string m_uploadid_marker;
std::string m_nextkey_marker;
std::string m_nextuploadid_marker;
std::string m_max_uploads;
bool m_is_truncated;
std::vector<std::string> m_common_prefixes;
};
class PutBucketACLResp : public BaseResp {
public:
PutBucketACLResp() {}
virtual ~PutBucketACLResp() {}
};
class GetBucketPolicyResp : public BaseResp {
public:
GetBucketPolicyResp() {}
virtual ~GetBucketPolicyResp() {}
std::string GetPolicy() const { return GetBody(); }
};
class PutBucketPolicyResp : public BaseResp {
public:
PutBucketPolicyResp() {}
virtual ~PutBucketPolicyResp() {}
};
class DeleteBucketPolicyResp : public BaseResp {
public:
DeleteBucketPolicyResp() {}
virtual ~DeleteBucketPolicyResp() {}
};
class GetBucketCORSResp : public BaseResp {
public:
GetBucketCORSResp() {}
virtual ~GetBucketCORSResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::vector<CORSRule> GetCORSRules() const { return m_rules; }
private:
std::vector<CORSRule> m_rules;
};
class PutBucketCORSResp : public BaseResp {
public:
PutBucketCORSResp() {}
virtual ~PutBucketCORSResp() {}
};
class DeleteBucketCORSResp : public BaseResp {
public:
DeleteBucketCORSResp() {}
virtual ~DeleteBucketCORSResp() {}
};
class GetBucketLocationResp : public BaseResp {
public:
GetBucketLocationResp() {}
virtual ~GetBucketLocationResp() {}
std::string GetLocation() const { return m_location; }
virtual bool ParseFromXmlString(const std::string& body);
private:
std::string m_location;
};
class GetBucketObjectVersionsResp : public BaseResp {
public:
GetBucketObjectVersionsResp() {}
virtual ~GetBucketObjectVersionsResp() {}
/// \brief 编码格式
std::string GetEncodingType() const { return m_encoding_type; }
/// \brief 返回的文件前缀
std::string GetPrefix() const { return m_prefix; }
/// \brief 单次响应请求内返回结果的最大的条目数量
uint64_t GetMaxKeys() const { return m_max_keys; }
/// \brief 响应请求条目是否被截断布尔值truefalse
bool IsTruncated() const { return m_is_truncated; }
/// \brief 假如返回条目被截断,则返回 NextKeyMarker 就是下一个条目的起点
std::string GetNextKeyMarker() const { return m_next_key_marker; }
std::string GetKeyMarker() const { return m_key_marker; }
std::string GetBucketName() const { return m_bucket_name; }
std::string GetVersionIdMarker() const { return m_version_id_marker; }
std::vector<COSVersionSummary> GetVersionSummary() const {
return m_summaries;
}
virtual bool ParseFromXmlString(const std::string& body);
private:
std::vector<COSVersionSummary> m_summaries;
std::string m_encoding_type;
bool m_is_truncated;
uint64_t m_max_keys;
std::string m_bucket_name;
std::string m_key_marker;
std::string m_prefix;
std::string m_version_id_marker;
std::string m_next_key_marker;
std::string m_next_version_id_marker;
};
class PutBucketLoggingResp : public BaseResp {
public:
PutBucketLoggingResp() {}
virtual ~PutBucketLoggingResp() {}
};
class GetBucketLoggingResp : public BaseResp {
public:
GetBucketLoggingResp() {}
virtual ~GetBucketLoggingResp() {}
virtual bool ParseFromXmlString(const std::string& body);
LoggingEnabled GetLoggingEnabled() const { return m_rules; }
private:
LoggingEnabled m_rules;
};
class PutBucketDomainResp : public BaseResp {
public:
PutBucketDomainResp() {}
virtual ~PutBucketDomainResp() {}
virtual bool ParseFromXmlString(const std::string& body);
DomainErrorMsg GetDomainErrorMsg() const { return m_rules; }
private:
DomainErrorMsg m_rules;
};
class GetBucketDomainResp : public BaseResp {
public:
GetBucketDomainResp() {}
virtual ~GetBucketDomainResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetStatus() const { return m_status; }
std::string GetName() const { return m_name; }
std::string GetType() const { return m_type; }
void SetStatus(const std::string& status) { m_status = status; }
void SetName(const std::string& name) { m_name = name; }
void SetType(const std::string& type) { m_type = type; }
private:
std::string m_status;
std::string m_name;
std::string m_type;
};
class PutBucketWebsiteResp : public BaseResp {
public:
PutBucketWebsiteResp() {}
virtual ~PutBucketWebsiteResp() {}
};
class GetBucketWebsiteResp : public BaseResp {
public:
GetBucketWebsiteResp() {}
virtual ~GetBucketWebsiteResp() {}
virtual bool ParseFromXmlString(const std::string& body);
bool ParseFromXmlRoutingRule(rapidxml::xml_node<>* node,
RoutingRule& tmp_routingrule);
void SetSuffix(const std::string& suffix) { m_suffix = suffix; }
void SetProtocol(const std::string& protocol) { m_protocol = protocol; }
void SetKey(const std::string& key) { m_key = key; }
std::string GetSuffix() const { return m_suffix; }
std::string GetProtocol() const { return m_protocol; }
std::string GetKey() const { return m_key; }
/// 设置重定向规则
void SetRoutingRules(const std::vector<RoutingRule>& routingrules) {
m_routingrules = routingrules;
}
std::vector<RoutingRule> GetRoutingRules() const { return m_routingrules; }
/// 添加单个rule
void AddRoutingRule(const RoutingRule& routingrule) {
m_routingrules.push_back(routingrule);
}
/// 清空重定向规则
void ClearRoutingRule() {
std::vector<RoutingRule> tmp;
m_routingrules.swap(tmp);
}
private:
std::string m_suffix;
std::string m_protocol;
std::string m_key;
std::vector<RoutingRule> m_routingrules;
};
class DeleteBucketWebsiteResp : public BaseResp {
public:
DeleteBucketWebsiteResp() {}
virtual ~DeleteBucketWebsiteResp() {}
};
class PutBucketTaggingResp : public BaseResp {
public:
PutBucketTaggingResp() {}
virtual ~PutBucketTaggingResp() {}
};
class GetBucketTaggingResp : public BaseResp {
public:
GetBucketTaggingResp() {}
void SetTagSet(std::vector<Tag>& tagset) { m_tagset = tagset; }
std::vector<Tag> GetTagSet() const { return m_tagset; }
//清除tag规则.
void ClearTagSet() {
std::vector<Tag> temp;
m_tagset.swap(temp);
}
/// 添加单个tag.
void AddTag(const Tag& tag) { m_tagset.push_back(tag); }
virtual bool ParseFromXmlString(const std::string& body);
virtual ~GetBucketTaggingResp() {}
private:
std::vector<Tag> m_tagset;
};
class DeleteBucketTaggingResp : public BaseResp {
public:
DeleteBucketTaggingResp() {}
virtual ~DeleteBucketTaggingResp() {}
};
class PutBucketInventoryResp : public BaseResp {
public:
PutBucketInventoryResp() {}
virtual ~PutBucketInventoryResp() {}
};
class GetBucketInventoryResp : public BaseResp {
public:
GetBucketInventoryResp() : m_mask(0x00000001u) {}
void SetInventory(const Inventory& inventory) {
m_mask = m_mask | 0x00000001u;
m_inventory = inventory;
}
bool HasInventory() const { return (m_mask & 0x00000001u) != 0; }
const Inventory& GetInventory() const { return m_inventory; }
bool ParseFromXmlOptionalFields(rapidxml::xml_node<>* node,
Inventory& temp_inventory);
bool ParseFromXmlCOSBucketDestination(rapidxml::xml_node<>* node,
Inventory& temp_inventory);
bool ParseFromXmlInventoryConfiguration(rapidxml::xml_node<>* node,
Inventory& temp_inventory);
virtual bool ParseFromXmlString(const std::string& body);
virtual ~GetBucketInventoryResp() {}
private:
uint64_t m_mask;
Inventory m_inventory;
};
class ListBucketInventoryConfigurationsResp : public GetBucketInventoryResp {
public:
ListBucketInventoryConfigurationsResp()
: m_is_truncated(false),
m_continuation_token(""),
m_next_continuation_token("") {}
virtual bool ParseFromXmlString(const std::string& body);
virtual ~ListBucketInventoryConfigurationsResp() {}
/// 添加单个Inventory.
void AddInventory(const Inventory& inventory) {
m_inventory_vec.push_back(inventory);
}
void SetInventoryVec(std::vector<Inventory>& inventory_vec) {
m_inventory_vec = inventory_vec;
}
void SetIsTruncated(bool is_truncated) { m_is_truncated = is_truncated; }
void SetContinuationToken(std::string continuation_token) {
m_continuation_token = continuation_token;
}
void SetNextContinuationToken(std::string next_continuation_token) {
m_next_continuation_token = next_continuation_token;
}
std::vector<Inventory> GetInventory() const { return m_inventory_vec; }
bool GetIsTruncated() const { return m_is_truncated; }
std::string GetContinuationToken() const { return m_continuation_token; }
std::string GetNextContinuationToken() const {
return m_next_continuation_token;
}
private:
std::vector<Inventory> m_inventory_vec;
bool m_is_truncated;
std::string m_continuation_token;
std::string m_next_continuation_token;
};
class DeleteBucketInventoryResp : public BaseResp {
public:
DeleteBucketInventoryResp() {}
virtual ~DeleteBucketInventoryResp() {}
};
/// \brief: 列举直播通道响应
class ListLiveChannelResp : public BaseResp {
public:
ListLiveChannelResp() {}
virtual ~ListLiveChannelResp() {}
virtual bool ParseFromXmlString(const std::string& body);
const ListLiveChannelResult& GetListResult() const { return result; }
void ClearResult() { result.Clear(); }
private:
ListLiveChannelResult result;
};
/// \brief: 配置存储桶智能分层的响应
class PutBucketIntelligentTieringResp : public BaseResp {
public:
PutBucketIntelligentTieringResp() {}
virtual ~PutBucketIntelligentTieringResp() {}
};
/// \brief: 获取配置存储桶智能分层配置的响应
class GetBucketIntelligentTieringResp : public BaseResp {
public:
GetBucketIntelligentTieringResp() {}
virtual ~GetBucketIntelligentTieringResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetStatus() const { return m_status; }
uint32_t GetDays() const { return m_days; }
uint32_t GetRequestFrequent() const { return m_freq; }
private:
std::string m_status;
int m_days;
int m_freq;
};
/// \brief: 配置存储桶Referer响应
class PutBucketRefererResp : public BaseResp {
public:
PutBucketRefererResp() {}
virtual ~PutBucketRefererResp() {}
};
/// \brief: 获取存储桶Referer响应
class GetBucketRefererResp : public BaseResp {
public:
GetBucketRefererResp() {}
virtual ~GetBucketRefererResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetStatus() const { return m_status; }
std::string GetRefererType() const { return m_referer_type; }
std::vector<std::string> GetDomainList() const { return m_domain_list; }
std::string GetEmptyReferConf() const { return m_empty_refer_conf; }
std::string GetVerifySignatureUrl() const {return m_verify_signature_url; }
private:
std::string m_status;
std::string m_referer_type;
std::vector<std::string> m_domain_list;
std::string m_empty_refer_conf;
std::string m_verify_signature_url;
};
} // namespace qcloud_cos
#endif // BUCKET_RESP_H

View File

@@ -0,0 +1,379 @@
#pragma once
#include <sstream>
#include <string>
#include <vector>
#include "rapidxml/1.13/rapidxml.hpp"
#include "rapidxml/1.13/rapidxml_print.hpp"
#include "rapidxml/1.13/rapidxml_utils.hpp"
#include "request/data_process_req.h"
#include "response/object_resp.h"
namespace qcloud_cos {
class ImageRespBase : virtual public BaseResp {
public:
ImageRespBase() {}
virtual ~ImageRespBase() {}
virtual bool ParseFromXmlString(const std::string& body);
UploadResult GetUploadResult() const { return m_upload_result; }
static bool ParseObject(rapidxml::xml_node<>* root, Object& object);
static bool ParseQRcodeInfo(rapidxml::xml_node<>* root, QRcodeInfo& qr_code);
protected:
bool ParseOriginalInfo(rapidxml::xml_node<>* root);
UploadResult m_upload_result;
};
class PutImageByFileResp : public ImageRespBase, public PutObjectByFileResp {
public:
PutImageByFileResp() {}
virtual ~PutImageByFileResp() {}
};
class CloudImageProcessResp : public ImageRespBase {
public:
CloudImageProcessResp() {}
virtual ~CloudImageProcessResp() {}
};
class GetQRcodeResp : public BaseResp {
public:
GetQRcodeResp() {}
virtual ~GetQRcodeResp() {}
virtual bool ParseFromXmlString(const std::string& body);
GetQRcodeResult GetResult() const { return m_result; }
private:
GetQRcodeResult m_result;
};
class DescribeDocProcessBucketsResp : public BaseResp {
public:
DescribeDocProcessBucketsResp() {}
virtual ~DescribeDocProcessBucketsResp() {}
virtual bool ParseFromXmlString(const std::string& body);
DocBucketResponse GetResult() const { return m_result; }
static bool ParseBucketInfo(rapidxml::xml_node<>* root,
BucketInfo& bucket_info);
private:
DocBucketResponse m_result;
};
class DocPreviewResp : public GetObjectByFileResp {
public:
DocPreviewResp() {}
virtual ~DocPreviewResp() {}
void ParseFromHeaders(const std::map<std::string, std::string>& headers);
// 返回文档总页数(表格文件表示当前 sheet 转换后的总图片数),异常时为空
unsigned GetTotalPage() const { return m_x_total_page; }
// 当异常时返回错误码
std::string GetErrNo() const { return m_x_errno; }
// 返回文档中总表数
unsigned GetTotalSheet() const { return m_x_total_sheet; }
// 返回当前 sheet 名
std::string GetSheetName() const { return m_sheet_name; }
private:
unsigned m_x_total_page;
std::string m_x_errno;
unsigned m_x_total_sheet;
std::string m_sheet_name;
};
class DocProcessJobBase : public BaseResp {
public:
DocProcessJobBase() {}
virtual ~DocProcessJobBase() {}
virtual bool ParseFromXmlString(const std::string& body);
JobsDetail GetJobsDetail() const { return m_jobs_detail; }
protected:
bool ParseJobsDetail(rapidxml::xml_node<>* root, JobsDetail& jobs_detail);
bool ParseOperation(rapidxml::xml_node<>* root, Operation& operation);
bool ParseDocProcess(rapidxml::xml_node<>* root, DocProcess& doc_process);
bool ParseDocProcessResult(rapidxml::xml_node<>* root,
DocProcessResult& doc_process_result);
private:
JobsDetail m_jobs_detail;
};
class CreateDocProcessJobsResp : public DocProcessJobBase {
public:
CreateDocProcessJobsResp() {}
virtual ~CreateDocProcessJobsResp() {}
};
class DescribeDocProcessJobResp : public DocProcessJobBase {
public:
DescribeDocProcessJobResp() {}
virtual ~DescribeDocProcessJobResp() {}
};
class DescribeDocProcessJobsResp : public DocProcessJobBase {
public:
DescribeDocProcessJobsResp() {}
virtual ~DescribeDocProcessJobsResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::vector<JobsDetail> GetJobsDetails() const { return m_jobs_details; }
std::string GetNextToken() const { return m_next_token; }
private:
std::vector<JobsDetail> m_jobs_details;
std::string m_next_token;
};
class QueuesBase : public BaseResp {
public:
QueuesBase() {}
virtual ~QueuesBase() {}
protected:
bool ParseNonExistPIDs(rapidxml::xml_node<>* root,
NonExistPIDs& non_exist_pids);
bool ParseQueueList(rapidxml::xml_node<>* root, QueueList& queue_list);
};
class DescribeQueuesResp : public QueuesBase {
public:
DescribeQueuesResp() {}
virtual ~DescribeQueuesResp() {}
virtual bool ParseFromXmlString(const std::string& body);
int GetTotalCount() const { return m_total_count; }
std::string GetRequestId() const { return m_request_id; }
int GetPageNumber() const { return m_page_number; }
int GetPageSize() const { return m_page_size; }
QueueList GetQueueList() const { return m_queue_list; }
NonExistPIDs GetNonExistPIDs() const { return m_non_exist_pids; }
private:
int m_total_count;
std::string m_request_id;
int m_page_number;
int m_page_size;
QueueList m_queue_list;
NonExistPIDs m_non_exist_pids;
};
class UpdateQueueResp : public QueuesBase {
public:
UpdateQueueResp() {}
virtual ~UpdateQueueResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetRequestId() const { return m_request_id; }
QueueList GetQueueList() const { return m_queue; }
private:
std::string m_request_id;
QueueList m_queue;
};
class DescribeDocProcessQueuesResp : public DescribeQueuesResp {
public:
DescribeDocProcessQueuesResp() {}
virtual ~DescribeDocProcessQueuesResp() {}
// virtual bool ParseFromXmlString(const std::string& body);
// int GetTotalCount() const { return m_total_count; }
// std::string GetRequestId() const { return m_request_id; }
// int GetPageNumber() const { return m_page_number; }
// int GetPageSize() const { return m_page_size; }
// QueueList GetQueueList() const { return m_queue_list; }
// NonExistPIDs GetNonExistPIDs() const { return m_non_exist_pids; }
// private:
// int m_total_count;
// std::string m_request_id;
// int m_page_number;
// int m_page_size;
// QueueList m_queue_list;
// NonExistPIDs m_non_exist_pids;
};
class UpdateDocProcessQueueResp : public UpdateQueueResp {
public:
UpdateDocProcessQueueResp() {}
virtual ~UpdateDocProcessQueueResp() {}
// virtual bool ParseFromXmlString(const std::string& body);
// std::string GetRequestId() const { return m_request_id; }
// QueueList GetQueueList() const { return m_queue; }
// private:
// std::string m_request_id;
// QueueList m_queue;
};
class DescribeMediaBucketsResp : public BaseResp {
public:
DescribeMediaBucketsResp() {}
virtual ~DescribeMediaBucketsResp() {}
virtual bool ParseFromXmlString(const std::string& body);
DescribeMediaBucketsResult GetResult() const { return m_result; }
private:
DescribeMediaBucketsResult m_result;
};
class PutBucketToCIResp : public BaseResp {
public:
PutBucketToCIResp() {}
virtual ~PutBucketToCIResp() {}
};
class CreateDocBucketResp : public BaseResp {
public:
CreateDocBucketResp() {}
virtual ~CreateDocBucketResp() {}
virtual bool ParseFromXmlString(const std::string& body);
CreateDocBucketResult GetResult() const { return m_result; }
private:
CreateDocBucketResult m_result;
};
class CreateMediaBucketResp : public BaseResp {
public:
CreateMediaBucketResp() {}
virtual ~CreateMediaBucketResp() {}
virtual bool ParseFromXmlString(const std::string& body);
CreateMediaBucketResult GetResult() const { return m_result; }
private:
CreateMediaBucketResult m_result;
};
class GetSnapshotResp : public GetObjectByFileResp {
public:
GetSnapshotResp() {}
virtual ~GetSnapshotResp() {}
};
class GetMediaInfoResp : public BaseResp {
public:
GetMediaInfoResp() {}
virtual ~GetMediaInfoResp() {}
virtual bool ParseFromXmlString(const std::string& body);
GetMediaInfoResult GetResult() const { return m_result; }
private:
bool ParseVideo(rapidxml::xml_node<>* root, VideoInfo& video_info);
bool ParseAudio(rapidxml::xml_node<>* root, AudioInfo& audio_info);
bool ParseSubtitle(rapidxml::xml_node<>* root, SubtitleInfo& subtitle_info);
bool ParseFormat(rapidxml::xml_node<>* root, FormatInfo& format_info);
GetMediaInfoResult m_result;
};
class GetPm3u8Resp : public GetObjectByFileResp {
public:
GetPm3u8Resp() {}
virtual ~GetPm3u8Resp() {}
};
class CreateFileBucketResp : public BaseResp {
public:
CreateFileBucketResp() {}
virtual ~CreateFileBucketResp() {}
virtual bool ParseFromXmlString(const std::string& body);
CreateFileBucketResult GetResult() const { return m_result; }
private:
CreateFileBucketResult m_result;
};
class DescribeFileBucketsResp : public BaseResp {
public:
DescribeFileBucketsResp() {}
virtual ~DescribeFileBucketsResp() {}
virtual bool ParseFromXmlString(const std::string& body);
DescribeFileBucketsResult GetResult() const { return m_result; }
private:
DescribeFileBucketsResult m_result;
};
class DataProcessJobBase : public BaseResp {
public:
DataProcessJobBase() {}
virtual ~DataProcessJobBase() {}
virtual bool ParseFromXmlString(const std::string& body);
JobsDetails GetJobsDetail() const { return m_jobs_detail; }
protected:
static bool ParseTranscode(rapidxml::xml_node<>* root, Transcode& transcode);
static bool ParseAudioMix(rapidxml::xml_node<>* root, AudioMix& audio_mix);
static bool ParseVideo(rapidxml::xml_node<>* root, Video& video);
static bool ParseTimeInterval(rapidxml::xml_node<>* root, TimeInterval& time_interval);
static bool ParseContainer(rapidxml::xml_node<>* root, Container& container);
static bool ParseAudio(rapidxml::xml_node<>* root, Audio& audio);
static bool ParseTransConfig(rapidxml::xml_node<>* root, TransConfig& trans_config);
static bool ParseSnapshot(rapidxml::xml_node<>* root, Snapshot& snapshot);
static bool ParseWatermark(rapidxml::xml_node<>* root, Watermark& watermark);
static bool ParseMediaResult(rapidxml::xml_node<>* root, MediaResult& media_result);
static bool ParseOutput(rapidxml::xml_node<>* root, Output& output);
static bool ParseRemoveWatermark(rapidxml::xml_node<>* root, RemoveWatermark& remove_watermark);
static bool ParseSubtitles(rapidxml::xml_node<>* root, Subtitles& subtitles);
static bool ParseFileUncompressConfig(rapidxml::xml_node<>* root, FileUncompressConfig& file_uncompress_config);
static bool ParseFileUncompressResult(rapidxml::xml_node<>* root, FileUncompressResult& file_uncompress_result);
static bool ParseAnimation(rapidxml::xml_node<>* root, Animation& animation);
static bool ParseInput(rapidxml::xml_node<>* root, Input& input);
static bool ParseSmartCover(rapidxml::xml_node<>* root, SmartCover& smartcover);
static bool ParseConcat(rapidxml::xml_node<>* root, Concat& concat);
static bool ParseConcatFragment(rapidxml::xml_node<>* root, ConcatFragment& concat_fragment);
static bool ParseDigitalWatermark(rapidxml::xml_node<>* root, DigitalWatermark& digital_watermark);
static bool ParseExtractDigitalWatermark(rapidxml::xml_node<>* root, ExtractDigitalWatermark& extract_digital_watermark);
static bool ParseVideoMontage(rapidxml::xml_node<>* root, VideoMontage& video_montage);
static bool ParseVoiceSeparate(rapidxml::xml_node<>* root, VoiceSeparate& voice_separate);
static bool ParseSegment(rapidxml::xml_node<>* root, Segment& segment);
private:
JobsDetails m_jobs_detail;
};
class CreateDataProcessJobsResp : public DataProcessJobBase {
public:
CreateDataProcessJobsResp() {}
virtual ~CreateDataProcessJobsResp() {}
// virtual bool ParseFromXmlString(const std::string& body);
};
class DescribeDataProcessJobResp : public DataProcessJobBase {
public:
DescribeDataProcessJobResp() {}
virtual ~DescribeDataProcessJobResp() {}
};
class CancelDataProcessJobResp : public BaseResp {
public:
CancelDataProcessJobResp() {}
virtual ~CancelDataProcessJobResp() {}
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,763 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#ifndef OBJECT_RESP_H
#define OBJECT_RESP_H
#pragma once
#include <iostream>
#include <vector>
#include "cos_config.h"
#include "cos_params.h"
#include "response/base_resp.h"
namespace qcloud_cos {
class GetObjectResp : public BaseResp {
public:
/// \brief 获取object type, 表示object是否可以被追加上传枚举值normal 或者
/// appendable
std::string GetXCosObjectType() const { return m_x_cos_object_type; }
void SetXCosObjectType(const std::string& x_cos_object_type) {
m_x_cos_object_type = x_cos_object_type;
}
/// \brief 获取自定义的元数据
std::map<std::string, std::string> GetXCosMetas() const {
return m_x_cos_metas;
}
/// \brief 获取自定义的元数据
std::string GetXCosMeta(const std::string& key) const {
std::map<std::string, std::string>::const_iterator itr =
m_x_cos_metas.find(key);
if (itr != m_x_cos_metas.end()) {
return itr->second;
}
return "";
}
void SetXCosMeta(const std::string& key, const std::string& value) {
m_x_cos_metas[key] = value;
}
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
void ParseFromHeaders(const std::map<std::string, std::string>& headers);
protected:
GetObjectResp() {}
GetObjectResp(const GetObjectResp& rhs)
: BaseResp(rhs),
m_x_cos_object_type(rhs.m_x_cos_object_type),
m_x_cos_metas(rhs.m_x_cos_metas) {}
GetObjectResp& operator=(const GetObjectResp& rhs) {
if (&rhs != this) {
BaseResp::operator=(rhs);
m_x_cos_object_type = rhs.m_x_cos_object_type;
m_x_cos_metas = rhs.m_x_cos_metas;
}
return *this;
}
virtual ~GetObjectResp() {}
private:
std::string m_x_cos_object_type;
std::map<std::string, std::string> m_x_cos_metas;
};
class GetObjectByStreamResp : public GetObjectResp {
public:
GetObjectByStreamResp() {}
virtual ~GetObjectByStreamResp() {}
};
class GetObjectByFileResp : public GetObjectResp {
public:
GetObjectByFileResp() {}
virtual ~GetObjectByFileResp() {}
};
class PutObjectResp : virtual public BaseResp {
protected:
PutObjectResp() {}
virtual ~PutObjectResp() {}
public:
/// 获取Object的版本号, 如果Bucket未开启多版本, 返回空字符串
std::string GetVersionId() const { return GetHeader("x-cos-version-id"); }
/// Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
};
class PutObjectByStreamResp : public PutObjectResp {
public:
PutObjectByStreamResp() {}
virtual ~PutObjectByStreamResp() {}
};
class PutObjectByFileResp : public PutObjectResp {
public:
PutObjectByFileResp() {}
virtual ~PutObjectByFileResp() {}
};
class DeleteObjectResp : public BaseResp {
public:
DeleteObjectResp() {}
virtual ~DeleteObjectResp() {}
};
class DeleteObjectsResp : public BaseResp {
public:
DeleteObjectsResp() {}
virtual ~DeleteObjectsResp() {}
std::vector<DeletedInfo> GetDeletedInfos() const { return m_deleted_infos; }
std::vector<ErrorInfo> GetErrorMsgs() const { return m_error_infos; }
virtual bool ParseFromXmlString(const std::string& body);
private:
std::vector<DeletedInfo> m_deleted_infos;
std::vector<ErrorInfo> m_error_infos;
};
class HeadObjectResp : public BaseResp {
public:
HeadObjectResp() {}
virtual ~HeadObjectResp() {}
/// \brief 获取object type, 表示object是否可以被追加上传枚举值normal 或者
/// appendable
std::string GetXCosObjectType() const { return m_x_cos_object_type; }
void SetXCosObjectType(const std::string& x_cos_object_type) {
m_x_cos_object_type = x_cos_object_type;
}
/// \brief 获取自定义的元数据
std::map<std::string, std::string> GetXCosMetas() const {
return m_x_cos_metas;
}
/// \brief 获取自定义的元数据
std::string GetXCosMeta(const std::string& key) const {
std::map<std::string, std::string>::const_iterator itr =
m_x_cos_metas.find(key);
if (itr != m_x_cos_metas.end()) {
return itr->second;
}
return "";
}
void SetXCosMeta(const std::string& key, const std::string& value) {
m_x_cos_metas[key] = value;
}
/// \brief 获得 archive 类型对象的当前恢复状态
std::string GetXCosRestore() const { return GetHeader("x-cos-restore"); }
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
void ParseFromHeaders(const std::map<std::string, std::string>& headers);
private:
std::string m_x_cos_object_type;
std::map<std::string, std::string> m_x_cos_metas;
};
class InitMultiUploadResp : public BaseResp {
public:
InitMultiUploadResp() {}
virtual ~InitMultiUploadResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 获取uploadId, 用于后续上传
std::string GetUploadId() const { return m_upload_id; }
/// \brief 获取Object的名称
std::string GetKey() const { return m_key; }
/// \brief 分片上传的目标Bucket
std::string GetBucket() const { return m_bucket; }
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_bucket;
std::string m_key; // object名称
std::string m_upload_id;
};
class UploadPartDataResp : public BaseResp {
public:
UploadPartDataResp() {}
virtual ~UploadPartDataResp() {}
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
};
class UploadPartCopyDataResp : public BaseResp {
public:
UploadPartCopyDataResp() {}
virtual ~UploadPartCopyDataResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 获取返回文件的MD5算法校验值。
/// ETag 的值可以用于检查 Object 的内容是否发生变化。
std::string GetEtag() const { return m_etag; }
/// \brief 返回文件最后修改时间GMT 格式
std::string GetLastModified() const { return m_last_modified; }
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_etag;
std::string m_last_modified;
};
class CompleteMultiUploadResp : public BaseResp {
public:
CompleteMultiUploadResp() {}
virtual ~CompleteMultiUploadResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetLocation() const { return m_location; }
std::string GetKey() const { return m_key; }
std::string GetBucket() const { return m_bucket; }
std::string GetVersionId() const { return GetHeader("x-cos-version-id"); }
std::string GetEtag() const { return m_etag; }
void SetEtag(const std::string& etag) { m_etag = etag;}
void AddEtagToHeader() { BaseResp::SetEtag(m_etag); }
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_location; // Object的外网访问域名
std::string m_bucket;
std::string m_key;
std::string m_etag;
};
class AbortMultiUploadResp : public BaseResp {
public:
AbortMultiUploadResp() {}
virtual ~AbortMultiUploadResp() {}
};
class ListPartsResp : public BaseResp {
public:
ListPartsResp()
: m_bucket(""),
m_encoding_type(""),
m_key(""),
m_upload_id(""),
m_part_number_marker(0),
m_parts(0),
m_next_part_number_marker(0),
m_storage_class(""),
m_max_parts(1000),
m_is_truncated(false) {}
virtual ~ListPartsResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetBucket() const { return m_bucket; }
std::string GetEncodingType() const { return m_encoding_type; }
std::string GetKey() const { return m_key; }
std::string GetUploadId() const { return m_upload_id; }
Initiator GetInitiator() const { return m_initiator; }
Owner GetOwner() const { return m_owner; }
uint64_t GetPartNumberMarker() const { return m_part_number_marker; }
std::vector<Part> GetParts() const { return m_parts; }
uint64_t GetNextPartNumberMarker() const { return m_next_part_number_marker; }
std::string GetStorageClass() const { return m_storage_class; }
uint64_t GetMaxParts() const { return m_max_parts; }
bool IsTruncated() const { return m_is_truncated; }
private:
std::string m_bucket;
std::string m_encoding_type;
std::string m_key;
std::string m_upload_id;
Initiator m_initiator;
Owner m_owner;
uint64_t m_part_number_marker;
std::vector<Part> m_parts;
uint64_t m_next_part_number_marker;
std::string m_storage_class;
uint64_t m_max_parts;
bool m_is_truncated;
};
class GetObjectACLResp : public BaseResp {
public:
GetObjectACLResp() {}
virtual ~GetObjectACLResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetOwnerID() const { return m_owner_id; }
std::string GetOwnerDisplayName() const { return m_owner_display_name; }
std::vector<Grant> GetAccessControlList() const { return m_acl; }
private:
std::string m_owner_id;
std::string m_owner_display_name;
std::vector<Grant> m_acl;
};
class PutObjectACLResp : public BaseResp {
public:
PutObjectACLResp() {}
virtual ~PutObjectACLResp() {}
};
class PutObjectTaggingResp : public BaseResp {
public:
PutObjectTaggingResp() {}
virtual ~PutObjectTaggingResp() {}
};
class GetObjectTaggingResp : public BaseResp {
public:
GetObjectTaggingResp() {}
void SetTagSet(std::vector<Tag>& tagset) { m_tagset = tagset; }
std::vector<Tag> GetTagSet() const { return m_tagset; }
//清除tag规则.
void ClearTagSet() {
std::vector<Tag> temp;
m_tagset.swap(temp);
}
/// 添加单个tag.
void AddTag(const Tag& tag) { m_tagset.push_back(tag); }
virtual bool ParseFromXmlString(const std::string& body);
virtual ~GetObjectTaggingResp() {}
private:
std::vector<Tag> m_tagset;
};
class DeleteObjectTaggingResp : public BaseResp {
public:
DeleteObjectTaggingResp() {}
virtual ~DeleteObjectTaggingResp() {}
};
class PutObjectCopyResp : public BaseResp {
public:
PutObjectCopyResp() {}
virtual ~PutObjectCopyResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetEtag() const { return m_etag; }
std::string GetLastModified() const { return m_last_modified; }
std::string GetVersionId() const { return m_version_id; }
std::string GetCrc64() const { return m_crc64; }
/// Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_etag;
std::string m_last_modified;
std::string m_version_id;
std::string m_crc64;
};
class CopyResp : public BaseResp {
public:
CopyResp()
: m_location(""),
m_bucket(""),
m_key(""),
m_etag(""),
m_last_modified(""),
m_version_id(""),
m_resp_tag("") {}
virtual ~CopyResp() {}
void CopyFrom(const PutObjectCopyResp& resp);
void CopyFrom(const CompleteMultiUploadResp& resp);
void Clear() {
m_location = "";
m_bucket = "";
m_key = "";
m_etag = "";
m_last_modified = "";
m_version_id = "";
m_resp_tag = "";
}
std::string GetLocation() const { return m_location; }
std::string GetKey() const { return m_key; }
std::string GetBucket() const { return m_bucket; }
std::string GetEtag() const { return m_etag; }
std::string GetLastModified() const { return m_last_modified; }
std::string GetVersionId() const { return m_version_id; }
std::string GetRespTag() { return m_resp_tag; }
private:
std::string m_location; // Object的外网访问域名
std::string m_bucket;
std::string m_key;
std::string m_etag;
std::string m_last_modified;
std::string m_version_id;
std::string m_resp_tag; // 用于区分是哪一种response
};
class PostObjectRestoreResp : public BaseResp {
public:
PostObjectRestoreResp() {}
~PostObjectRestoreResp() {}
};
class OptionsObjectResp : public BaseResp {
public:
OptionsObjectResp() {}
~OptionsObjectResp() {}
/// \brief 获取模拟跨域访问的请求来源域名当来源不允许的时候此Header不返回
std::string GetAccessControAllowOrigin() const {
return GetHeader("Access-Control-Allow-Origin");
}
/// \brief 获取模拟跨域访问的请求 HTTP
/// 方法当请求方法不允许的时候此Header不返回
std::string GetAccessControlAllowMethods() const {
return GetHeader("Access-Control-Allow-Methods");
}
/// \brief
/// 获取模拟跨域访问的请求头部当模拟任何请求头部不允许的时候此Header不返回该请求头部
std::string GetAccessControlAllowHeaders() const {
return GetHeader("Access-Control-Allow-Headers");
}
/// \brief 获取模拟跨域访问的请求 HTTP
/// 方法当请求方法不允许的时候此Header不返回
std::string GetAccessControlExposeHeaders() const {
return GetHeader("Access-Control-Expose-Headers");
}
/// \brief 获取OPTIONS请求得到结果的有效期
std::string GetAccessControlMaxAge() const {
return GetHeader("Access-Control-Max-Age");
}
};
class SelectObjectContentResp : public BaseResp {
public:
SelectObjectContentResp() { resp_data.reserve(10); }
~SelectObjectContentResp() {}
/// \brief 将响应结果写入本地文件
int WriteResultToLocalFile(const std::string& file);
bool ParseFromXmlString(const std::string& body);
// bool ParseFromStringStream(const std::ostringstream& os);
/// \brief 打印最终结果至终端
void PrintResult() const;
private:
// void ParseStatsEvent(const std::string& stat_str);
// void ParseProgressEvent(const std::string& prog_str);
std::vector<SelectMessage> resp_data;
std::string error_message;
std::string error_code;
};
class AppendObjectResp : public PutObjectByStreamResp {
public:
AppendObjectResp() {}
~AppendObjectResp() {}
/// \brief 获取下一次追加操作的起始点,单位:字节
std::string GetNextPosition() const {
return GetHeader(kRespHeaderXCosNextAppendPosition);
}
/// \brief 获取服务端返回的本次append内容的md5
std::string GetXCosContentSha1() const {
return GetHeader(kRespHeaderXCosContentSha1);
}
};
/// \brief: 创建直播通道的响应
class PutLiveChannelResp : public BaseResp {
public:
PutLiveChannelResp() {}
virtual ~PutLiveChannelResp() {}
virtual bool ParseFromXmlString(const std::string& body);
const std::string GetPublishUrl() const { return m_publish_url; }
std::string& GetPublishUrl() { return m_publish_url; }
std::string GetPlayUrl() const { return m_play_url; }
private:
std::string m_publish_url; // 推流url
std::string m_play_url; // 观流url
};
/// \brief: 启用或者禁用直播通道的响应
class PutLiveChannelSwitchResp : public BaseResp {
public:
PutLiveChannelSwitchResp() {}
virtual ~PutLiveChannelSwitchResp() {}
};
/// \brief: 获取直播通道配置的响应
class GetLiveChannelResp : public BaseResp {
public:
GetLiveChannelResp() {}
virtual ~GetLiveChannelResp() {}
virtual bool ParseFromXmlString(const std::string& body);
const LiveChannelConfiguration& GetLiveChannelConf() const {
return m_chan_conf;
}
private:
LiveChannelConfiguration m_chan_conf;
};
/// \brief: 获取直播通道推流历史的响应
class GetLiveChannelHistoryResp : public BaseResp {
public:
GetLiveChannelHistoryResp() {}
virtual ~GetLiveChannelHistoryResp() {}
virtual bool ParseFromXmlString(const std::string& body);
const std::vector<LiveRecord>& GetChanHistory() const { return m_history; }
private:
std::vector<LiveRecord> m_history;
};
/// \brief: 获取直播通道推流状态的响应
class GetLiveChannelStatusResp : public BaseResp {
public:
GetLiveChannelStatusResp() {}
virtual ~GetLiveChannelStatusResp() {}
virtual bool ParseFromXmlString(const std::string& body);
const LiveChannelStatus& GetLiveChannelStatus() const {
return m_livechan_status;
}
private:
LiveChannelStatus m_livechan_status;
};
/// \brief: 删除直播通道的响应
class DeleteLiveChannelResp : public BaseResp {
public:
DeleteLiveChannelResp() {}
virtual ~DeleteLiveChannelResp() {}
};
/// \brief: 查询指定通道在指定时间段推流生成的播放列表的响应
class GetLiveChannelVodPlaylistResp : public BaseResp {
public:
GetLiveChannelVodPlaylistResp() {}
virtual ~GetLiveChannelVodPlaylistResp() {}
int WriteResultToFile(const std::string& file);
};
/// \brief: 为指定通道生成一个可供点播例用的播放列表的响应
class PostLiveChannelVodPlaylistResp : public BaseResp {
public:
PostLiveChannelVodPlaylistResp() {}
virtual ~PostLiveChannelVodPlaylistResp() {}
};
/* Multithread接口 */
class MultiPutObjectResp : public BaseResp {
public:
MultiPutObjectResp() {}
virtual ~MultiPutObjectResp() {}
virtual bool ParseFromXmlString(const std::string& body);
std::string GetRespTag() { return m_resp_tag; }
std::string GetLocation() const { return m_location; }
std::string GetKey() const { return m_key; }
std::string GetBucket() const { return m_bucket; }
void CopyFrom(const InitMultiUploadResp& resp);
void CopyFrom(const UploadPartDataResp& resp);
void CopyFrom(const CompleteMultiUploadResp& resp);
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_location; // Object的外网访问域名
std::string m_bucket;
std::string m_key;
std::string m_upload_id;
// FIXME(sevenyou) 先这么搞吧
std::string m_resp_tag; // 用于区分是哪一种response
};
class MultiGetObjectResp : public GetObjectByFileResp {
public:
MultiGetObjectResp() {}
~MultiGetObjectResp() {}
};
class PutObjectResumableSingleSyncResp : public GetObjectByFileResp {
public:
PutObjectResumableSingleSyncResp() {}
virtual ~PutObjectResumableSingleSyncResp() {}
std::string GetRespTag() { return m_resp_tag; }
std::string GetLocation() const { return m_location; }
std::string GetKey() const { return m_key; }
std::string GetBucket() const { return m_bucket; }
void CopyFrom(const InitMultiUploadResp& resp);
void CopyFrom(const PutObjectByFileResp& resp);
void CopyFrom(const CompleteMultiUploadResp& resp);
/// \brief Server端加密使用的算法
std::string GetXCosServerSideEncryption() const {
return GetHeader("x-cos-server-side-encryption");
}
private:
std::string m_location; // Object的外网访问域名
std::string m_bucket;
std::string m_key;
std::string m_upload_id;
// FIXME(sevenyou) 先这么搞吧
std::string m_resp_tag; // 用于区分是哪一种response
};
/* Async接口 */
//typedef PutObjectByFileResp PutObjectAsyncResp;
//typedef PutObjectByFileResp MultiPutObjectAsyncResp;
//typedef GetObjectByFileResp GetObjectAsyncResp;
//typedef GetObjectByFileResp MultiGetObjectAsyncResp;
class AsyncResp : public BaseResp {
public:
AsyncResp() {}
virtual ~AsyncResp() {}
};
/* 批量及目录操作接口 */
class PutObjectsByDirectoryResp {
public:
PutObjectsByDirectoryResp() {}
virtual ~PutObjectsByDirectoryResp() {}
public:
class PutResp {
public:
PutResp() {}
virtual ~PutResp() {}
std::string m_file_name; // 本地文件名
std::string m_object_name; // 对象名
BaseResp m_cos_resp; // cos返回的响应
};
// 成功上传的对象
std::vector<PutResp> m_succ_put_objs;
};
class PutDirectoryResp : public PutObjectResp {
public:
PutDirectoryResp() {}
virtual ~PutDirectoryResp() {}
};
class MoveObjectResp {
public:
MoveObjectResp() {}
virtual ~MoveObjectResp() {}
};
class DeleteObjectsByPrefixResp {
public:
DeleteObjectsByPrefixResp() {}
virtual ~DeleteObjectsByPrefixResp() {}
std::vector<std::string> m_succ_del_objs; // 成功删除的对象
};
} // namespace qcloud_cos
#endif // OBJECT_RESP_H

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 11/14/17
// Description:
#ifndef SERVICE_RESP_H
#define SERVICE_RESP_H
#pragma once
#include <vector>
#include "cos_config.h"
#include "cos_defines.h"
#include "response/base_resp.h"
namespace qcloud_cos {
class GetServiceResp : public BaseResp {
public:
GetServiceResp() {}
virtual ~GetServiceResp() {}
virtual bool ParseFromXmlString(const std::string& body);
/// \brief 获取 Bucket 持有者的信息
///
/// \return Owner 持有者的信息
Owner GetOwner() const { return m_owner; }
/// \brief 获取所有 Bucket 列表信息
std::vector<Bucket> GetBuckets() const { return m_buckets; }
private:
Owner m_owner;
std::vector<Bucket> m_buckets;
};
} // namespace qcloud_cos
#endif // SERVICE_RESP_H

View File

@@ -0,0 +1,36 @@
#pragma once
#include <memory>
#include "response/object_resp.h"
#include "trsf/transfer_handler.h"
namespace qcloud_cos {
class AsyncContext {
public:
explicit AsyncContext(const SharedTransferHandler& handler) : m_handler(handler) {}
/// @brief 取消操作
void Cancel() { return m_handler->Cancel(); }
/// @brief 等待操作结束
void WaitUntilFinish() { return m_handler->WaitUntilFinish(); }
std::string GetBucketName() const { return m_handler->GetBucketName(); }
std::string GetObjectName() const { return m_handler->GetObjectName(); }
std::string GetLocalFilePath() const { return m_handler->GetLocalFilePath(); }
/// @brief 获取操作结果
CosResult GetResult() const { return m_handler->GetResult(); }
/// @brief 获取多线程上传响应
AsyncResp GetAsyncResp() const {
return m_handler->GetAsyncResp();
}
private:
SharedTransferHandler m_handler;
};
} // namespace qcloud_cos

23
include/trsf/async_task.h Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
#include <functional>
#include "Poco/Task.h"
#include "Poco/TaskManager.h"
namespace qcloud_cos {
using TaskFunc = std::function<void()>;
class AsyncTask : public Poco::Task {
public:
explicit AsyncTask(TaskFunc &&f) : Task("AsyncTask"), _f(f) {}
~AsyncTask() {}
void runTask() { _f(); }
private:
TaskFunc _f;
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,221 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_TRSF_TRANSFER_HANDLER_H_
#define COS_CPP_SDK_V5_INCLUDE_TRSF_TRANSFER_HANDLER_H_
#include <condition_variable>
#include <exception>
#include <functional>
#include <istream>
#include <map>
#include <memory>
#include <mutex>
#include <ostream>
#include "op/cos_result.h"
#include "response/object_resp.h"
#include "util/illegal_intercept.h"
namespace qcloud_cos {
class ObjectReq;
class TransferHandler;
class AsyncContext;
typedef std::shared_ptr<TransferHandler> SharedTransferHandler;
typedef std::shared_ptr<AsyncContext> SharedAsyncContext;
/// @brief 进度回调函数
using TransferProgressCallback = std::function<void(
uint64_t transferred_size, uint64_t total_size, void* user_data)>;
/// @brief 完成回调函数
using DoneCallback =
std::function<void(const SharedAsyncContext& context, void* user_data)>;
class PartState {
public:
PartState();
PartState(int part_num, std::string& etag, size_t size,
bool last_part = false);
void SetPartNum(int number) { m_part_num = number; }
int GetPartNum() const { return m_part_num; }
void SetEtag(const std::string& etag) { m_etag = etag; }
std::string GetEtag() const { return m_etag; }
void SetSize(size_t size) { m_size_inbytes = size; }
size_t GetSize() const { return m_size_inbytes; }
void SetLastPart(bool lastpart) { m_lastpart = lastpart; }
bool IsLastPart() { return m_lastpart; }
private:
int m_part_num;
// current use the md5
std::string m_etag;
size_t m_size_inbytes;
// TODO for now just care about the whole progress
/* size_t m_current_progress_inbytes; */
/* size_t m_range_begin; */
bool m_lastpart;
};
typedef std::shared_ptr<PartState> PartPointer;
// Key is partnumber
typedef std::map<int, PartPointer> PartStateMap;
enum class TransferStatus {
NOT_START,
// Operation is now running
IN_PROGRESS,
// Operation was canceled.
CANCELED,
// Operation failed
FAILED,
// Operation was successful
COMPLETED,
// Operation either failed or was canceled and a user deleted the multi-part
// upload .
RETRY,
ABORTED
};
class TransferHandler : public std::enable_shared_from_this<TransferHandler> {
public:
TransferHandler();
~TransferHandler() {}
void SetBucketName(const std::string& bucket_name) {
if (!IllegalIntercept::CheckBucket(bucket_name)) {
throw std::invalid_argument("Invalid bucket_name argument :" + bucket_name);
}
m_bucket_name = bucket_name;
}
std::string GetBucketName() const { return m_bucket_name; }
void SetObjectName(const std::string& object_name) {
m_object_name = object_name;
}
std::string GetObjectName() const { return m_object_name; }
void SetLocalFilePath(const std::string& local_file_path) {
m_local_file_path = local_file_path;
}
std::string GetLocalFilePath() const { return m_local_file_path; }
void SetTotalSize(uint64_t total_size) { m_total_size = total_size; }
uint64_t GetTotalSize() const { return m_total_size; }
// Notice there can not backwards
void UpdateProgress(uint64_t update_prog);
// Get the current upload size(B).
uint64_t GetProgress() const;
void UpdateStatus(const TransferStatus& status);
void UpdateStatus(const TransferStatus& status, const CosResult& result);
void UpdateStatus(const TransferStatus& status, const CosResult& result,
const std::map<std::string, std::string> headers,
const std::string& body = "");
TransferStatus GetStatus() const;
std::string GetStatusString() const;
void SetUploadID(const std::string& uploadid) { m_uploadid = uploadid; }
// Get the init or resumed uploadid.
std::string GetUploadID() const { return m_uploadid; }
// Cancel the process of interface the uploadid can reuse.
void Cancel();
bool ShouldContinue() const;
bool IsFinishStatus(TransferStatus status) const;
bool IsAllowTransition(TransferStatus org, TransferStatus dst) const;
// Block until finish.
void WaitUntilFinish();
/// @brief 设置进度回调函数
void SetTransferProgressCallback(const TransferProgressCallback& callback) {
m_progress_cb = callback;
}
/// @brief 设置状态回调函数
void SetDoneCallback(const DoneCallback& callback) { m_done_cb = callback; }
/// @brief 设置回调私有数据
void SetUserData(void* user_data) { m_user_data = user_data; }
/// @brief 设置请求信息
void SetRequest(const void* req);
///////////////////////////////////////////////////////////////////////////
// 用户调用的函数
/// @brief 获取操作结果
CosResult GetResult() const { return m_result; }
/// @brief 获取响应
AsyncResp GetAsyncResp() const;
private:
CosResult m_result;
std::map<std::string, std::string> m_resp_headers;
std::string m_resp_body;
private:
std::string m_bucket_name;
std::string m_object_name;
std::string m_local_file_path;
uint64_t m_total_size;
uint64_t m_current_progress;
TransferStatus m_status;
std::string m_uploadid;
// Is cancel
bool m_cancel;
PartStateMap m_part_map;
// Mutex lock for the progress
mutable std::mutex m_lock_prog;
// Mutex lock for the status
mutable std::mutex m_lock_stat;
// Condition
mutable std::condition_variable m_cond;
// callback function
TransferProgressCallback m_progress_cb;
DoneCallback m_done_cb;
void* m_user_data;
// Mutex lock for the part map
// mutable boost::mutex m_lock_parts;
};
class HandleStreamCopier {
public:
static std::streamsize handleCopyStream(const SharedTransferHandler& handler,
std::istream& istr,
std::ostream& ostr,
std::size_t bufferSize = 8192);
static std::streamsize handleCopyStream(const SharedTransferHandler& handler,
const char *buf, size_t buf_len,
std::ostream& ostr,
std::size_t bufferSize = 8192);
};
class UserCancelException : public std::exception {
public:
UserCancelException() {}
~UserCancelException() throw() {}
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_TRSF_TRANSFER_HANDLER_H_

85
include/util/auth_tool.h Normal file
View File

@@ -0,0 +1,85 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_AUTH_TOOL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_AUTH_TOOL_H_
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include <unordered_set>
#include "request/base_req.h"
#include "util/noncopyable.h"
namespace qcloud_cos {
class AuthTool : private NonCopyable {
public:
/// \brief 返回签名,可以在指定的有效期内(通过CosSysConfig设置, 默认60s)使用
///
/// \param secret_id 开发者拥有的项目身份识别 ID用以身份认证
/// \param secret_key 开发者拥有的项目身份密钥
/// \param http_method http方法,如POST/GET/HEAD/PUT等, 传入大小写不敏感
/// \param in_uri http uri
/// \param headers http header的键值对
/// \param params http params的键值对
///
/// \return 字符串形式的签名,返回空串代表失败
static std::string Sign(const std::string& secret_id,
const std::string& secret_key,
const std::string& http_method,
const std::string& in_uri,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
const std::unordered_set<std::string>& not_sign_headers);
/// \brief 返回签名,可以在指定的有效期内使用
///
/// \param secret_id 开发者拥有的项目身份识别 ID用以身份认证
/// \param secret_key 开发者拥有的项目身份密钥
/// \param http_method http方法,如POST/GET/HEAD/PUT等, 传入大小写不敏感
/// \param in_uri http uri
/// \param headers http header的键值对
/// \param params http params的键值对
///
/// \return 字符串形式的签名,返回空串代表失败
static std::string Sign(const std::string& secret_id,
const std::string& secret_key,
const std::string& http_method,
const std::string& in_uri,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
uint64_t start_time_in_s, uint64_t end_time_in_s,
const std::unordered_set<std::string>& not_sign_headers);
/// \brief get rtmp signature
static std::string RtmpSign(const std::string& secret_id,
const std::string& secret_key,
const std::string& token,
const std::string& bucket,
const std::string& channel,
const std::map<std::string, std::string>& params,
uint64_t expire);
private:
/// \brief 把params中的数据转小写正排,key放在param_list
/// key=value放param_value_list \param params 参数 \param key_encode
/// key是否进行uri编码 \param value_encode value是否进行uri编码 \param
/// value_lower value是否小写 \param param_list 参数名列表,以;分隔 \param
/// param_value_list 参数键值对列表,以&分隔 \retval 无
static void FillMap(const std::map<std::string, std::string>& params,
bool key_encode, bool value_encode, bool value_lower,
std::string* param_list, std::string* param_value_list);
/// \brief 找出需要鉴权的头部,并设置,目前host conent-type 还有x开头的都要鉴权
/// \param hedaers 头部的kv对
/// \param filted_req_headers 需要鉴权的头部
/// \retval 无
static void FilterAndSetSignHeader(
const std::map<std::string, std::string>& headers,
std::map<std::string, std::string>* filted_req_headers,
const std::unordered_set<std::string>& not_sign_headers);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_AUTH_TOOL_H_

View File

@@ -0,0 +1,32 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_BASE_OP_UTIL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_BASE_OP_UTIL_H_
#include <utility>
#include "cos_config.h"
#include "op/cos_result.h"
namespace qcloud_cos {
class BaseOpUtil {
public:
explicit BaseOpUtil(SharedConfig cos_conf) : m_config(std::move(cos_conf)) {}
BaseOpUtil() = default;
bool ShouldChangeBackupDomain(const CosResult &result, const uint32_t &request_num, bool is_ci_req = false) const;
void SleepBeforeRetry(const uint32_t &request_num) const;
std::string GetRealUrl(const std::string& host, const std::string& path, bool is_https, bool is_generate_presigned_url = false) const;
uint64_t GetMaxRetryTimes() const;
static std::string ChangeHostSuffix(const std::string& host);
private:
SharedConfig m_config;
bool UseDefaultDomain() const;
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_BASE_OP_UTIL_H_

89
include/util/codec_util.h Normal file
View File

@@ -0,0 +1,89 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_CODEC_UTIL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_CODEC_UTIL_H_
#include <stdint.h>
#include <string>
namespace qcloud_cos {
class CodecUtil {
public:
/**
* @brief 将字符x转成十六进制 (x的值[0, 15])
*
* @param x
*
* @return 十六进制字符
*/
static unsigned char ToHex(const unsigned char& x);
/**
* @brief 将二进制数据转成十六进制 (x的值[0, 15]),上层调用保证hex的大小足够
*
* @param bin
*
* @param binLen
*
* @param hex 存放结果的数据块
*
* @return 无
*/
static void BinToHex(const unsigned char* bin, unsigned int binLen,
char* hex);
static bool IsalnumAscii(int c);
static std::string EncodeKey(const std::string& key);
/**
* @brief 对字符串进行URL编码
*
* @param str 带编码的字符串
*
* @return 经过URL编码的字符串
*/
static std::string UrlEncode(const std::string& str);
/**
* @brief 对字符串进行base64编码
*
* @param plainText 待编码的字符串
*
* @return 编码后的字符串
*/
static std::string Base64Encode(const std::string& plainText);
/**
* @brief 获取hmacSha1值
*
* @param plainText 明文
* @param key 秘钥
*
* @return 获取的hmacsha1值
*/
static std::string HmacSha1(const std::string& plainText,
const std::string& key);
/**
* @brief 获取hmacSha1的16进制值
*
* @param plainText 明文
* @param key 秘钥
*
* @return 获取的hmacsha1的16进制值
*/
static std::string HmacSha1Hex(const std::string& plainText,
const std::string& key);
static std::string RawMd5(const std::string& plainText);
static std::string RawMd51(const std::string& plainText);
static std::string HexToBin(const std::string& strHex);
static std::string DigestToHex(const unsigned char *digest, size_t len);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_CODEC_UTIL_H_

13
include/util/crc64.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
#include <cstddef>
namespace qcloud_cos {
class CRC64 {
public:
static uint64_t CalcCRC(uint64_t crc, void *buf, size_t len);
static uint64_t CombineCRC(uint64_t crc1, uint64_t crc2, uintmax_t len2);
static uint64_t CalcCRC(uint64_t crc, void *buf, size_t len, bool little);
};
} // namespace qcloud_cos

31
include/util/file_util.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_FILE_UTIL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_FILE_UTIL_H_
#include <stdint.h>
#include <fstream>
#include <iostream>
#include <string>
namespace qcloud_cos {
class FileUtil {
public:
// 获取文件内容
static std::string GetFileContent(const std::string& path);
// 获取文件大小
static uint64_t GetFileLen(const std::string& path);
static bool IsDirectoryExists(const std::string& path);
static bool IsDirectory(const std::string& path);
static std::string GetDirectory(const std::string& path);
// 获取文件CRC64
static uint64_t GetFileCrc64(const std::string& file);
#if defined(_WIN32)
static uint64_t GetFileLen(const std::wstring& path);
static uint64_t GetFileCrc64(const std::wstring& file);
static std::wstring GetWideCharFilePath(const std::string file_path);
#endif
static std::string GetFileMd5(const std::string& file);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_FILE_UTIL_H_

View File

@@ -0,0 +1,94 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/18/17
// Description:
#ifndef HTTP_SENDER_H
#define HTTP_SENDER_H
#pragma once
#include <stdint.h>
#include <map>
#include <string>
#include "trsf/transfer_handler.h"
namespace qcloud_cos {
class HttpSender {
public:
static int SendRequest(const SharedTransferHandler& handler,
const std::string& http_method,
const std::string& url_str,
const std::map<std::string, std::string>& req_params,
const std::map<std::string, std::string>& req_headers,
const std::string& req_body,
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms,
std::map<std::string, std::string>* resp_headers,
std::string* resp_body, std::string* err_msg,
bool is_check_md5 = false,
bool is_verify_cert = true,
const std::string& ca_location = "",
const SSLCtxCallback& ssl_ctx_cb = nullptr,
void *user_data = nullptr);
static int SendRequest(const SharedTransferHandler& handler,
const std::string& http_method,
const std::string& url_str,
const std::map<std::string, std::string>& req_params,
const std::map<std::string, std::string>& req_headers,
std::istream& is, uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms,
std::map<std::string, std::string>* resp_headers,
std::string* resp_body, std::string* err_msg,
bool is_check_md5 = false,
bool is_verify_cert = true,
const std::string& ca_location = "",
const SSLCtxCallback& ssl_ctx_cb = nullptr,
void *user_data = nullptr);
static int SendRequest(const SharedTransferHandler& handler,
const std::string& http_method,
const std::string& url_str,
const std::map<std::string, std::string>& req_params,
const std::map<std::string, std::string>& req_headers,
std::istream& is, // 流式输入,用于传输请求正文
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms,
std::map<std::string, std::string>* resp_headers,
std::ostream& resp_stream, // 流式输出,用于接收响应正文
std::string* err_msg,
bool is_check_md5 = false,
bool is_verify_cert = true,
const std::string& ca_location = "",
const SSLCtxCallback& ssl_ctx_cb = nullptr,
void *user_data = nullptr,
const char *req_body_buf = nullptr, // 可选的缓冲区
size_t req_body_len = 0);
static int SendRequest(const SharedTransferHandler& handler,
const std::string& http_method,
const std::string& url_str,
const std::map<std::string, std::string>& req_params,
const std::map<std::string, std::string>& req_headers,
const std::string& req_body, // 字符串输入,用于传输请求正文
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms,
std::map<std::string, std::string>* resp_headers,
std::string* xml_err_str, // 额外的错误信息, 用于响应返回非 2xx 错误码时, 传输报错响应信息
std::ostream& resp_stream, // 流式输出, 用于传输响应正文
std::string* err_msg,
uint64_t* real_byte, // 实际接收字节数
bool is_check_md5 = false,
bool is_verify_cert = true,
const std::string& ca_location = "",
const SSLCtxCallback& ssl_ctx_cb = nullptr,
void *user_data = nullptr);
};
} // namespace qcloud_cos
#endif // HTTP_SENDER_H

View File

@@ -0,0 +1,14 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_ILLEGAL_INTERCEPT_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_ILLEGAL_INTERCEPT_H_
#include <string>
namespace qcloud_cos {
class IllegalIntercept {
public:
static bool ObjectKeySimplifyCheck(const std::string& path);
static bool CheckBucket(const std::string& path);
static bool isAlnum(char c);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_ILLEGAL_INTERCEPT_H_

23
include/util/log_util.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_LOG_UTIL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_LOG_UTIL_H_
#include <stdint.h>
#include <string>
#include "cos_defines.h"
namespace qcloud_cos {
typedef void (*LogCallback)(const std::string& logstr);
class LogUtil {
public:
static std::string GetLogPrefix(int level);
static std::string FormatLog(int level, const char* fmt, ...);
static void Syslog(int level, const char* fmt, ...);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_LOG_UTIL_H_

66
include/util/lru_cache.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <iostream>
#include <list>
#include <mutex>
#include <stdexcept>
#include <unordered_map>
namespace qcloud_cos {
template <typename KeyType, typename ValueType>
class LruCache {
public:
using KeyValuePair = std::pair<KeyType, ValueType>;
using ListIterator = typename std::list<KeyValuePair>::iterator;
explicit LruCache(size_t size) : m_max_size(size) {}
~LruCache() {}
void Put(const KeyType& key, const ValueType& value) {
std::lock_guard<std::mutex> lock(m_mutex);
m_entry_list.emplace_front(key, value);
auto it = m_entry_map.find(key);
if (it != m_entry_map.end()) {
m_entry_list.erase(it->second);
} else {
if (m_entry_list.size() > m_max_size) {
m_entry_map.erase(m_entry_list.back().first);
m_entry_list.pop_back();
}
}
m_entry_map[key] = m_entry_list.begin();
}
const ValueType Get(const KeyType& key) {
std::lock_guard<std::mutex> lock(m_mutex);
auto it = m_entry_map.find(key);
if (it == m_entry_map.end()) {
throw std::range_error("No such key in cache");
} else {
m_entry_list.emplace_front(key, it->second->second);
m_entry_list.erase(it->second);
m_entry_map[key] = m_entry_list.begin();
return m_entry_list.begin()->second;
}
}
bool Exist(const KeyType& key) const {
std::lock_guard<std::mutex> lock(m_mutex);
return m_entry_map.find(key) != m_entry_map.end();
}
size_t Size() const {
std::lock_guard<std::mutex> lock(m_mutex);
return m_entry_map.size();
}
private:
std::list<KeyValuePair> m_entry_list;
std::unordered_map<KeyType, ListIterator> m_entry_map;
size_t m_max_size;
mutable std::mutex m_mutex;
};
} // namespace qcloud_cos

View File

@@ -0,0 +1,25 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 08/03/17
// Description:
#ifndef NONCOPYABLE_H
#define NONCOPYABLE_H
#pragma once
namespace qcloud_cos {
class NonCopyable {
protected:
NonCopyable() {}
~NonCopyable() {}
private: // emphasize the following members are private
NonCopyable(const NonCopyable&);
const NonCopyable& operator=(const NonCopyable&);
};
} // namespace qcloud_cos
#endif // NONCOPYABLE_H

44
include/util/semaphore.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <mutex>
#include <condition_variable>
// C++11信号量实现用于滑动窗口控制
class Semaphore {
public:
explicit Semaphore(unsigned int count = 0) : max_count_(count) {}
bool acquire() {
std::unique_lock<std::mutex> lock(mutex_);
if (count_ < max_count_) {
++count_;
return true;
}
return false;
}
void release() {
std::unique_lock<std::mutex> lock(mutex_);
if (count_ <= 0) {
return;
}
--count_;
condition_.notify_one();
}
void wait() {
std::unique_lock<std::mutex> lock(mutex_);
condition_.wait(lock, [this]() { return count_ < max_count_; });
}
unsigned int get_count() const {
std::unique_lock<std::mutex> lock(mutex_);
return count_;
}
private:
mutable std::mutex mutex_;
std::condition_variable condition_;
unsigned int count_ = 0;
const unsigned int max_count_;
};

48
include/util/sha1.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_SHA1_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_SHA1_H_
#include <stdio.h>
#include <stdlib.h>
#include <string>
namespace qcloud_cos {
/* Useful defines & typedefs */
typedef unsigned char SHA_BYTE; /* 8-bit quantity */
// SHA_LONG already defined in openssl/sha.h
typedef unsigned int SHA_LONG; /* 32-or-more-bit quantity */
#define SHA_BYTE_ORDER 1234
#define SHA_VERSION 1
#define SHA_BLOCKSIZE 64
#define SHA_DIGESTSIZE 20
typedef struct {
SHA_LONG digest[5]; /* message digest */
SHA_LONG count_lo, count_hi; /* 64-bit bit count */
SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
int local; /* unprocessed amount in data */
} SHA_INFO;
void ShaInit(SHA_INFO *);
void ShaUpdate(SHA_INFO *, SHA_BYTE *, int);
void ShaFinal(unsigned char[20], SHA_INFO *);
void ShaOutput(unsigned char[20], unsigned char[40]);
const char *ShaVersion(void);
class Sha1 {
public:
Sha1();
~Sha1();
void Append(const char *data, unsigned int size);
std::string Final();
private:
SHA_INFO m_sha;
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_SHA1_H_

View File

@@ -0,0 +1,32 @@
#pragma once
#include <map>
#include <memory>
#include <string>
#include "Poco/Net/DNS.h"
#include "Poco/Net/HostEntry.h"
#include "lru_cache.h"
namespace qcloud_cos {
struct HostEntryCache {
Poco::Net::HostEntry host_entry;
time_t cache_ts;
};
class SimpleDnsCache {
public:
using SharedLruCache = std::shared_ptr<LruCache<std::string, HostEntryCache>>;
SimpleDnsCache(unsigned max_size, unsigned expire_seconds);
~SimpleDnsCache();
// resolve host
std::string Resolve(const std::string& host);
bool Exist(const std::string& host);
private:
unsigned m_max_size;
unsigned m_expire_seconds;
SharedLruCache m_cache;
};
} // namespace qcloud_cos

272
include/util/string_util.h Normal file
View File

@@ -0,0 +1,272 @@
#ifndef COS_CPP_SDK_V5_INCLUDE_UTIL_STRING_UTIL_H_
#define COS_CPP_SDK_V5_INCLUDE_UTIL_STRING_UTIL_H_
#include <stdint.h>
#include <string>
#include "cos_defines.h"
#include "rapidxml/1.13/rapidxml.hpp"
#include "rapidxml/1.13/rapidxml_print.hpp"
#include "rapidxml/1.13/rapidxml_utils.hpp"
namespace qcloud_cos {
class StringUtil {
public:
/**
* @brief 去除string两端的空格
*
* @param s: 待去除空格的字符串,是入参也是出参
*
* @return 返回去除空格后的字符串,即s
*/
static std::string& Trim(std::string& s);
/**
* @brief 去除string两端指定的字符串
*
* @param s: 待去除的字符串,入参
* @param trim_value: 删除的字符串
*
* @return 返回Trim后的字符串
*/
static std::string Trim(const std::string& s, const std::string& trim_value);
/**
* @brief 将xml转为string
*
* @param xmlObject 需要转换xml对象
*
* @return 返回转换后的string
*/
static std::string XmlToString(const rapidxml::xml_document<>& xml_doc);
/**
* @brief 将string转换为xml
*
* @param xmlStr 待转换的string对象
* @param doc 待返回的xml对象[out]
*
* @return 转换成功返回true,否则返回false
*/
static bool StringToXml(char* xml_str, rapidxml::xml_document<>* doc);
/**
* @brief 把uint64_t类型的num转换成std::string,长度为8个字节
*
* @param num uint64_t类型
*
* @return 转换后的string
*/
static std::string Uint64ToString(uint64_t num);
/**
* @brief 将int转为string
*
* @param num int类型
*
* @return 转换后的string
*/
static std::string IntToString(int num);
/**
* @brief 将float转为string
*
* @param num float类型
*
* @return 转换后的string
*/
static std::string FloatToString(float num);
/**
* @brief 字符串就地转成全大写
*
* @param s 指向string类型的指针
*
* @return void
*/
static void StringToUpper(std::string* s);
/**
* @brief 字符串转成全大写
*
* @param s string类型的常引用
*
* @return 全大写字符串
*/
static std::string StringToUpper(const std::string& s);
/**
* @brief 字符串就地转成全小写
*
* @param s 指向string类型的指针
*
* @return void
*/
static void StringToLower(std::string* s);
/**
* @brief 字符串转成全小写
*
* @param s string类型的常引用
*
* @return 全大写字符串
*/
static std::string StringToLower(const std::string& s);
/**
* @brief 字符串连接
*
* @param str_vec 字符串vector
* @param delimiter 分隔符
*
* @return 字符串
*/
static std::string JoinStrings(const std::vector<std::string>& str_vec,
const std::string& delimiter);
/**
* @brief 将string转为uint64_t
*
* @param str string类型
*
* @return 转换后的uint64_t
*/
static uint64_t StringToUint64(const std::string& str);
static unsigned StringToUint32(const std::string& str);
/**
* @brief 将string转为int
*
* @param str string类型
*
* @return 转换后的int
*/
static int StringToInt(const std::string& str);
/**
* @brief 将string转为float
*
* @param str string类型
*
* @return 转换后的float
*/
static float StringToFloat(const std::string& str);
/**
* @brief 判断字符串是否以指定前缀开头
*
* @param str string类型
* @param prefix string类型
*
* @return str的前缀为prefix,则返回true;反之,返回false
*/
static bool StringStartsWith(const std::string& str,
const std::string& prefix);
/**
* @brief 判断字符串是否以指定前缀开头(忽略大小写)
*
* @param str string类型
* @param prefix string类型
*
* @return str的前缀为prefix,则返回true;反之,返回false
*/
static bool StringStartsWithIgnoreCase(const std::string& str,
const std::string& prefix);
/**
* @brief 移除前缀
*
* @param str string类型
* @param prefix string类型
*
* @return 返回移除了prefix前缀的字符串
*/
static std::string StringRemovePrefix(const std::string& str,
const std::string& prefix);
/**
* @brief 判断字符串是否以指定后缀结尾
*
* @param str string类型
* @param suffix string类型
*
* @return str的后缀为suffix,则返回true;反之,返回false
*/
static bool StringEndsWith(const std::string& str, const std::string& suffix);
/**
* @brief 判断字符串是否以指定后缀结尾(忽略大小写)
*
* @param str string类型
* @param suffix string类型
*
* @return str的后缀为suffix,则返回true;反之,返回false
*/
static bool StringEndsWithIgnoreCase(const std::string& str,
const std::string& suffix);
/**
* @brief 移除后缀
*
* @param str string类型
* @param suffix string类型
*
* @return 返回移除了suffix前缀的字符串
*/
static std::string StringRemoveSuffix(const std::string& str,
const std::string& suffix);
/**
* @brief 分割字符串
*
* @param str string类型,待分割字符串
* @param delim char类型,分割符
* @param vec std::vector类型,分割结果
*
* @return void
*/
static void SplitString(const std::string& str, char delim,
std::vector<std::string>* vec);
/**
* @brief 分割字符串
*
* @param str string类型,待分割字符串
* @param sep string类型,分割字符串
* @param vec std::vector类型,分割结果
*
* @return void
*/
static void SplitString(const std::string& str, const std::string& sep,
std::vector<std::string>* vec);
/**
* @brief 将HTTP_METHOD转成对应的字符串格式
*
* @param method HTTP_METHOD
*
* @return string
*/
static std::string HttpMethodToString(HTTP_METHOD method);
static bool IsV4ETag(const std::string& etag);
static bool IsMultipartUploadETag(const std::string& etag);
/**
* @brief 从字符串中获取uint32整型
*/
static uint32_t GetUint32FromStrWithBigEndian(const char* str);
/**
* @brief 从字符串中获取uint16整型
*/
static uint16_t GetUint16FromStrWithBigEndian(const char* str);
static size_t GetLengthFromIStream(std::istream& is);
};
} // namespace qcloud_cos
#endif // COS_CPP_SDK_V5_INCLUDE_UTIL_STRING_UTIL_H_

21
include/util/task.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
// 任务状态枚举
typedef enum {
TASK_IDLE = 0, // 任务空闲,可分配新任务
TASK_RUNNING = 1, // 任务正在执行中
TASK_COMPLETED = 2 // 任务已完成
} TaskStatus;
// 任务相关信息结构体
class TaskInfo {
public:
TaskStatus status;
uint64_t sequence;
TaskInfo() : status(TASK_IDLE), sequence(0) {}
explicit TaskInfo(TaskStatus status, uint64_t sequence) : status(status), sequence(sequence) {}
};

37
include/util/test_utils.h Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
#include <iostream>
#include <string>
namespace qcloud_cos {
class TestUtils {
public:
static void WriteStringtoFile(const std::string& file,
const std::string& str);
static void WriteRandomDatatoFile(const std::string& file, unsigned len);
static void RemoveFile(const std::string& file);
static std::string GetRandomString(unsigned size);
static std::string CalcFileMd5(const std::string& file);
static std::string CalcStreamMd5(std::istream& is);
static std::string CalcStringMd5(const std::string& str);
static std::string CalcStreamSHA1(std::istream& is);
static std::string GetEnvVar(const std::string& env_var_name);
#if defined(__linux__)
static bool IsDirectoryExists(const std::string& path);
static bool MakeDirectory(const std::string& path);
static bool RemoveDirectory(const std::string& path);
#endif
};
#define GetEnvVar TestUtils::GetEnvVar
struct FileInfo {
std::string m_object_name;
std::string m_local_file;
std::string m_local_file_download;
uint64_t m_file_size;
uint64_t m_file_crc64_origin;
std::string m_file_md5_origin;
int m_op_type;
};
} // namespace qcloud_cos

0
libs/Win32/.gitkeep Normal file
View File

0
libs/linux/.gitkeep Normal file
View File

0
libs/macOS/.gitkeep Normal file
View File

0
libs/x64/.gitkeep Normal file
View File

52
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,52 @@
project(cossdk)
if(USE_OPENSSL_MD5)
message(STATUS "Use Openssl Md5 Func")
add_definitions(-DUSE_OPENSSL_MD5)
endif()
file(GLOB sdk_common_header "${CMAKE_SOURCE_DIR}/include/*.h")
file(GLOB sdk_op_header "${CMAKE_SOURCE_DIR}/include/op/*.h")
file(GLOB sdk_request_header "${CMAKE_SOURCE_DIR}/include/request/*.h")
file(GLOB sdk_response_header "${CMAKE_SOURCE_DIR}/include/response/*.h")
file(GLOB sdk_threadpool_header "${CMAKE_SOURCE_DIR}/include/threadpool/*.h")
file(GLOB sdk_trsf_header "${CMAKE_SOURCE_DIR}/include/trsf/*.h")
file(GLOB sdk_util_header "${CMAKE_SOURCE_DIR}/include/util/*.h")
file(GLOB sdk_header
${sdk_common_header}
${sdk_op_header}
${sdk_request_header}
${sdk_response_header}
${sdk_threadpool_header}
${sdk_trsf_header}
${sdk_util_header})
file(GLOB sdk_common_src "${CMAKE_SOURCE_DIR}/src/*.cpp")
file(GLOB sdk_op_src "${CMAKE_SOURCE_DIR}/src/op/*.cpp")
file(GLOB sdk_request_src "${CMAKE_SOURCE_DIR}/src/request/*.cpp")
file(GLOB sdk_response_src "${CMAKE_SOURCE_DIR}/src/response/*.cpp")
file(GLOB sdk_trsf_src "${CMAKE_SOURCE_DIR}/src/trsf/*.cpp")
file(GLOB sdk_util_src "${CMAKE_SOURCE_DIR}/src/util/*.cpp")
file(GLOB sdk_src
${sdk_common_src}
${sdk_op_src}
${sdk_request_src}
${sdk_response_src}
${sdk_trsf_src}
${sdk_util_src})
message("Sdk header: ${sdk_header}")
message("Sdk src: ${sdk_src}")
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
include_directories(${CMAKE_SOURCE_DIR}/include/ ${POCO_INCLUDE_DIR})
add_library(${PROJECT_NAME} STATIC ${sdk_src} ${sdk_header})
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "cossdk")
if(BUILD_SHARED_LIB)
message(STATUS "Build shared lib")
link_directories(${POCO_LINK_DIR} ${OPENSSL_LINK_DIR}) #这一行要放到add_library前面
add_library(${PROJECT_NAME}-shared SHARED ${sdk_src})
include_directories(${CMAKE_SOURCE_DIR}/include/ ${POCO_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME}-shared ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS})
endif()

923
src/cos_api.cpp Normal file
View File

@@ -0,0 +1,923 @@
#include "cos_api.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/TaskManager.h"
#include "cos_sys_config.h"
#include "trsf/async_context.h"
#include "trsf/async_task.h"
namespace qcloud_cos {
bool CosAPI::s_init = false;
bool CosAPI::s_poco_init = false;
int CosAPI::s_cos_obj_num = 0;
std::mutex g_init_lock;
Poco::TaskManager& GetGlobalTaskManager() {
static Poco::ThreadPool async_thread_pool("aysnc_pool", 2, CosSysConfig::GetAsynThreadPoolSize());
static Poco::TaskManager task_manager(async_thread_pool);
return task_manager;
}
CosAPI::CosAPI(CosConfig& config)
: m_config(new CosConfig(config)), m_object_op(m_config),
m_bucket_op(m_config), m_service_op(m_config) {
if (!m_config->CheckRegion()) {
throw std::invalid_argument("Invalid region configuration in CosConfig :" + m_config->GetRegion());
}
CosInit();
}
CosAPI::~CosAPI() { CosUInit(); }
int CosAPI::CosInit() {
std::lock_guard<std::mutex> lock(g_init_lock);
++s_cos_obj_num;
if (!s_init) {
if (!s_poco_init) {
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
Poco::Net::initializeSSL();
s_poco_init = true;
}
s_init = true;
}
return 0;
}
void CosAPI::CosUInit() {
std::lock_guard<std::mutex> lock(g_init_lock);
--s_cos_obj_num;
if (s_init && s_cos_obj_num == 0) {
s_init = false;
}
}
void CosAPI::SetCredentail(const std::string& ak, const std::string& sk,
const std::string& token) {
m_config->SetConfigCredentail(ak, sk, token);
}
bool CosAPI::IsBucketExist(const std::string& bucket_name) {
return m_bucket_op.IsBucketExist(bucket_name);
}
bool CosAPI::IsObjectExist(const std::string& bucket_name,
const std::string& object_name) {
return m_object_op.IsObjectExist(bucket_name, object_name);
}
std::string CosAPI::GeneratePresignedUrl(const GeneratePresignedUrlReq& req) {
return m_object_op.GeneratePresignedUrl(req);
}
std::string CosAPI::GeneratePresignedUrl(const std::string& bucket_name,
const std::string& object_name,
uint64_t start_time_in_s,
uint64_t end_time_in_s,
HTTP_METHOD http_method) {
GeneratePresignedUrlReq req(bucket_name, object_name, http_method);
req.SetStartTimeInSec(start_time_in_s);
req.SetExpiredTimeInSec(end_time_in_s - start_time_in_s);
return GeneratePresignedUrl(req);
}
std::string CosAPI::GeneratePresignedUrl(const std::string& bucket_name,
const std::string& key,
uint64_t start_time_in_s,
uint64_t end_time_in_s) {
return GeneratePresignedUrl(bucket_name, key, start_time_in_s, end_time_in_s,
HTTP_GET);
}
std::string CosAPI::GetBucketLocation(const std::string& bucket_name) {
return m_bucket_op.GetBucketLocation(bucket_name);
}
CosResult CosAPI::GetService(const GetServiceReq& req, GetServiceResp* resp) {
return m_service_op.GetService(req, resp);
}
CosResult CosAPI::HeadBucket(const HeadBucketReq& req, HeadBucketResp* resp) {
return m_bucket_op.HeadBucket(req, resp);
}
CosResult CosAPI::PutBucket(const PutBucketReq& req, PutBucketResp* resp) {
return m_bucket_op.PutBucket(req, resp);
}
CosResult CosAPI::GetBucket(const GetBucketReq& req, GetBucketResp* resp) {
return m_bucket_op.GetBucket(req, resp);
}
CosResult CosAPI::ListMultipartUpload(const ListMultipartUploadReq& req,
ListMultipartUploadResp* resp) {
return m_bucket_op.ListMultipartUpload(req, resp);
}
CosResult CosAPI::DeleteBucket(const DeleteBucketReq& req,
DeleteBucketResp* resp) {
return m_bucket_op.DeleteBucket(req, resp);
}
CosResult CosAPI::GetBucketVersioning(const GetBucketVersioningReq& req,
GetBucketVersioningResp* resp) {
return m_bucket_op.GetBucketVersioning(req, resp);
}
CosResult CosAPI::PutBucketVersioning(const PutBucketVersioningReq& req,
PutBucketVersioningResp* resp) {
return m_bucket_op.PutBucketVersioning(req, resp);
}
CosResult CosAPI::GetBucketReplication(const GetBucketReplicationReq& req,
GetBucketReplicationResp* resp) {
return m_bucket_op.GetBucketReplication(req, resp);
}
CosResult CosAPI::PutBucketReplication(const PutBucketReplicationReq& req,
PutBucketReplicationResp* resp) {
return m_bucket_op.PutBucketReplication(req, resp);
}
CosResult CosAPI::DeleteBucketReplication(const DeleteBucketReplicationReq& req,
DeleteBucketReplicationResp* resp) {
return m_bucket_op.DeleteBucketReplication(req, resp);
}
CosResult CosAPI::GetBucketLifecycle(const GetBucketLifecycleReq& req,
GetBucketLifecycleResp* resp) {
return m_bucket_op.GetBucketLifecycle(req, resp);
}
CosResult CosAPI::PutBucketLifecycle(const PutBucketLifecycleReq& req,
PutBucketLifecycleResp* resp) {
return m_bucket_op.PutBucketLifecycle(req, resp);
}
CosResult CosAPI::DeleteBucketLifecycle(const DeleteBucketLifecycleReq& req,
DeleteBucketLifecycleResp* resp) {
return m_bucket_op.DeleteBucketLifecycle(req, resp);
}
CosResult CosAPI::GetBucketACL(const GetBucketACLReq& req,
GetBucketACLResp* resp) {
return m_bucket_op.GetBucketACL(req, resp);
}
CosResult CosAPI::PutBucketACL(const PutBucketACLReq& req,
PutBucketACLResp* resp) {
return m_bucket_op.PutBucketACL(req, resp);
}
CosResult CosAPI::PutBucketPolicy(const PutBucketPolicyReq& req,
PutBucketPolicyResp* resp) {
return m_bucket_op.PutBucketPolicy(req, resp);
}
CosResult CosAPI::GetBucketPolicy(const GetBucketPolicyReq& req,
GetBucketPolicyResp* resp) {
return m_bucket_op.GetBucketPolicy(req, resp);
}
CosResult CosAPI::DeleteBucketPolicy(const DeleteBucketPolicyReq& req,
DeleteBucketPolicyResp* resp) {
return m_bucket_op.DeleteBucketPolicy(req, resp);
}
CosResult CosAPI::GetBucketCORS(const GetBucketCORSReq& req,
GetBucketCORSResp* resp) {
return m_bucket_op.GetBucketCORS(req, resp);
}
CosResult CosAPI::PutBucketCORS(const PutBucketCORSReq& req,
PutBucketCORSResp* resp) {
return m_bucket_op.PutBucketCORS(req, resp);
}
CosResult CosAPI::DeleteBucketCORS(const DeleteBucketCORSReq& req,
DeleteBucketCORSResp* resp) {
return m_bucket_op.DeleteBucketCORS(req, resp);
}
CosResult CosAPI::PutBucketReferer(const PutBucketRefererReq& req,
PutBucketRefererResp* resp) {
return m_bucket_op.PutBucketReferer(req, resp);
}
CosResult CosAPI::GetBucketReferer(const GetBucketRefererReq& req,
GetBucketRefererResp* resp) {
return m_bucket_op.GetBucketReferer(req, resp);
}
CosResult CosAPI::PutBucketLogging(const PutBucketLoggingReq& req,
PutBucketLoggingResp* resp) {
return m_bucket_op.PutBucketLogging(req, resp);
}
CosResult CosAPI::GetBucketLogging(const GetBucketLoggingReq& req,
GetBucketLoggingResp* resp) {
return m_bucket_op.GetBucketLogging(req, resp);
}
CosResult CosAPI::PutBucketDomain(const PutBucketDomainReq& req,
PutBucketDomainResp* resp) {
return m_bucket_op.PutBucketDomain(req, resp);
}
CosResult CosAPI::GetBucketDomain(const GetBucketDomainReq& req,
GetBucketDomainResp* resp) {
return m_bucket_op.GetBucketDomain(req, resp);
}
CosResult CosAPI::PutBucketWebsite(const PutBucketWebsiteReq& req,
PutBucketWebsiteResp* resp) {
return m_bucket_op.PutBucketWebsite(req, resp);
}
CosResult CosAPI::GetBucketWebsite(const GetBucketWebsiteReq& req,
GetBucketWebsiteResp* resp) {
return m_bucket_op.GetBucketWebsite(req, resp);
}
CosResult CosAPI::DeleteBucketWebsite(const DeleteBucketWebsiteReq& req,
DeleteBucketWebsiteResp* resp) {
return m_bucket_op.DeleteBucketWebsite(req, resp);
}
CosResult CosAPI::PutBucketTagging(const PutBucketTaggingReq& req,
PutBucketTaggingResp* resp) {
return m_bucket_op.PutBucketTagging(req, resp);
}
CosResult CosAPI::GetBucketTagging(const GetBucketTaggingReq& req,
GetBucketTaggingResp* resp) {
return m_bucket_op.GetBucketTagging(req, resp);
}
CosResult CosAPI::DeleteBucketTagging(const DeleteBucketTaggingReq& req,
DeleteBucketTaggingResp* resp) {
return m_bucket_op.DeleteBucketTagging(req, resp);
}
CosResult CosAPI::PutBucketInventory(const PutBucketInventoryReq& req,
PutBucketInventoryResp* resp) {
return m_bucket_op.PutBucketInventory(req, resp);
}
CosResult CosAPI::GetBucketInventory(const GetBucketInventoryReq& req,
GetBucketInventoryResp* resp) {
return m_bucket_op.GetBucketInventory(req, resp);
}
CosResult CosAPI::ListBucketInventoryConfigurations(
const ListBucketInventoryConfigurationsReq& req,
ListBucketInventoryConfigurationsResp* resp) {
return m_bucket_op.ListBucketInventoryConfigurations(req, resp);
}
CosResult CosAPI::DeleteBucketInventory(const DeleteBucketInventoryReq& req,
DeleteBucketInventoryResp* resp) {
return m_bucket_op.DeleteBucketInventory(req, resp);
}
CosResult CosAPI::GetBucketObjectVersions(const GetBucketObjectVersionsReq& req,
GetBucketObjectVersionsResp* resp) {
return m_bucket_op.GetBucketObjectVersions(req, resp);
}
CosResult CosAPI::PutObject(const PutObjectByFileReq& req,
PutObjectByFileResp* resp) {
return m_object_op.PutObject(req, resp);
}
CosResult CosAPI::PutObject(const PutObjectByStreamReq& req,
PutObjectByStreamResp* resp) {
return m_object_op.PutObject(req, resp);
}
CosResult CosAPI::GetObject(const GetObjectByStreamReq& req,
GetObjectByStreamResp* resp) {
return m_object_op.GetObject(req, resp);
}
CosResult CosAPI::GetObject(const GetObjectByFileReq& req,
GetObjectByFileResp* resp) {
return m_object_op.GetObject(req, resp);
}
CosResult CosAPI::MultiGetObject(const MultiGetObjectReq& req,
MultiGetObjectResp* resp) {
return m_object_op.MultiGetObject(static_cast<GetObjectByFileReq>(req), resp);
}
std::string CosAPI::GetObjectUrl(const std::string& bucket,
const std::string& object, bool https,
const std::string& region) {
std::string object_url;
if (https) {
object_url = "https://";
} else {
object_url = "http://"; // NOCA:HttpHardcoded(ignore)
}
std::string destdomain = m_config->GetDestDomain().empty() ?
CosSysConfig::GetDestDomain() : m_config->GetDestDomain();
if (!destdomain.empty()) {
object_url += destdomain;
} else {
object_url += bucket + ".cos.";
if (!region.empty()) {
object_url += region;
} else {
object_url += m_config->GetRegion();
}
object_url += ".myqcloud.com";
}
object_url += "/" + object;
return object_url;
}
CosResult CosAPI::DeleteObject(const DeleteObjectReq& req,
DeleteObjectResp* resp) {
return m_object_op.DeleteObject(req, resp);
}
CosResult CosAPI::DeleteObjects(const DeleteObjectsReq& req,
DeleteObjectsResp* resp) {
return m_object_op.DeleteObjects(req, resp);
}
CosResult CosAPI::HeadObject(const HeadObjectReq& req, HeadObjectResp* resp) {
return m_object_op.HeadObject(req, resp);
}
CosResult CosAPI::InitMultiUpload(const InitMultiUploadReq& req,
InitMultiUploadResp* resp) {
return m_object_op.InitMultiUpload(req, resp);
}
CosResult CosAPI::UploadPartData(const UploadPartDataReq& req,
UploadPartDataResp* resp) {
return m_object_op.UploadPartData(req, resp);
}
CosResult CosAPI::UploadPartCopyData(const UploadPartCopyDataReq& req,
UploadPartCopyDataResp* resp) {
return m_object_op.UploadPartCopyData(req, resp);
}
CosResult CosAPI::CompleteMultiUpload(const CompleteMultiUploadReq& req,
CompleteMultiUploadResp* resp) {
return m_object_op.CompleteMultiUpload(req, resp);
}
CosResult CosAPI::MultiPutObject(const MultiPutObjectReq& req,
MultiPutObjectResp* resp) {
return m_object_op.MultiUploadObject(static_cast<PutObjectByFileReq>(req), resp);
}
CosResult CosAPI::PutObjectResumableSingleThreadSync(const PutObjectResumableSingleSyncReq& req,
PutObjectResumableSingleSyncResp* resp) {
return m_object_op.UploadObjectResumableSingleThreadSync(static_cast<PutObjectByFileReq>(req), resp);
}
CosResult CosAPI::AbortMultiUpload(const AbortMultiUploadReq& req,
AbortMultiUploadResp* resp) {
return m_object_op.AbortMultiUpload(req, resp);
}
CosResult CosAPI::ListParts(const ListPartsReq& req, ListPartsResp* resp) {
return m_object_op.ListParts(req, resp);
}
CosResult CosAPI::GetObjectACL(const GetObjectACLReq& req,
GetObjectACLResp* resp) {
return m_object_op.GetObjectACL(req, resp);
}
CosResult CosAPI::PutObjectACL(const PutObjectACLReq& req,
PutObjectACLResp* resp) {
return m_object_op.PutObjectACL(req, resp);
}
CosResult CosAPI::PutObjectTagging(const PutObjectTaggingReq& req,
PutObjectTaggingResp* resp) {
return m_object_op.PutObjectTagging(req, resp);
}
CosResult CosAPI::GetObjectTagging(const GetObjectTaggingReq& req,
GetObjectTaggingResp* resp) {
return m_object_op.GetObjectTagging(req, resp);
}
CosResult CosAPI::DeleteObjectTagging(const DeleteObjectTaggingReq& req,
DeleteObjectTaggingResp* resp) {
return m_object_op.DeleteObjectTagging(req, resp);
}
CosResult CosAPI::PutObjectCopy(const PutObjectCopyReq& req,
PutObjectCopyResp* resp) {
return m_object_op.PutObjectCopy(req, resp);
}
CosResult CosAPI::Copy(const CopyReq& req, CopyResp* resp) {
return m_object_op.Copy(req, resp);
}
CosResult CosAPI::PostObjectRestore(const PostObjectRestoreReq& req,
PostObjectRestoreResp* resp) {
return m_object_op.PostObjectRestore(req, resp);
}
CosResult CosAPI::OptionsObject(const OptionsObjectReq& req,
OptionsObjectResp* resp) {
return m_object_op.OptionsObject(req, resp);
}
CosResult CosAPI::SelectObjectContent(const SelectObjectContentReq& req,
SelectObjectContentResp* resp) {
return m_object_op.SelectObjectContent(req, resp);
}
CosResult CosAPI::AppendObject(const AppendObjectReq& req,
AppendObjectResp* resp) {
return m_object_op.AppendObject(req, resp);
}
CosResult CosAPI::PutLiveChannel(const PutLiveChannelReq& req,
PutLiveChannelResp* resp) {
return m_object_op.PutLiveChannel(req, resp);
}
std::string CosAPI::GetRtmpSignedPublishUrl(
const std::string& bucket, const std::string& channel, int expire,
const std::map<std::string, std::string> url_params) {
std::string rtmp_signed_url = "rtmp://" + bucket + ".cos." +
m_config->GetRegion() + ".myqcloud.com/live/" +
channel;
std::string sign_info = AuthTool::RtmpSign(
m_config->GetAccessKey(), m_config->GetSecretKey(),
m_config->GetTmpToken(), bucket, channel, url_params, expire);
return rtmp_signed_url + "?" + sign_info;
}
CosResult CosAPI::PutLiveChannelSwitch(const PutLiveChannelSwitchReq& req,
PutLiveChannelSwitchResp* resp) {
return m_object_op.PutLiveChannelSwitch(req, resp);
}
CosResult CosAPI::GetLiveChannel(const GetLiveChannelReq& req,
GetLiveChannelResp* resp) {
return m_object_op.GetLiveChannel(req, resp);
}
CosResult CosAPI::GetLiveChannelHistory(const GetLiveChannelHistoryReq& req,
GetLiveChannelHistoryResp* resp) {
return m_object_op.GetLiveChannelHistory(req, resp);
}
CosResult CosAPI::GetLiveChannelStatus(const GetLiveChannelStatusReq& req,
GetLiveChannelStatusResp* resp) {
return m_object_op.GetLiveChannelStatus(req, resp);
}
CosResult CosAPI::DeleteLiveChannel(const DeleteLiveChannelReq& req,
DeleteLiveChannelResp* resp) {
return m_object_op.DeleteLiveChannel(req, resp);
}
CosResult
CosAPI::GetLiveChannelVodPlaylist(const GetLiveChannelVodPlaylistReq& req,
GetLiveChannelVodPlaylistResp* resp) {
return m_object_op.GetLiveChannelVodPlaylist(req, resp);
}
CosResult
CosAPI::PostLiveChannelVodPlaylist(const PostLiveChannelVodPlaylistReq& req,
PostLiveChannelVodPlaylistResp* resp) {
return m_object_op.PostLiveChannelVodPlaylist(req, resp);
}
CosResult CosAPI::ListLiveChannel(const ListLiveChannelReq& req,
ListLiveChannelResp* resp) {
return m_bucket_op.ListLiveChannel(req, resp);
}
CosResult CosAPI::PutBucketIntelligentTiering(const PutBucketIntelligentTieringReq& req,
PutBucketIntelligentTieringResp* resp) {
return m_bucket_op.PutBucketIntelligentTiering(req, resp);
}
CosResult CosAPI::GetBucketIntelligentTiering(const GetBucketIntelligentTieringReq& req,
GetBucketIntelligentTieringResp* resp) {
return m_bucket_op.GetBucketIntelligentTiering(req, resp);
}
CosResult CosAPI::ResumableGetObject(const GetObjectByFileReq& req,
GetObjectByFileResp* resp) {
return m_object_op.ResumableGetObject(req, resp);
}
SharedAsyncContext CosAPI::AsyncPutObject(const AsyncPutObjectReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
handler->SetTotalSize(req.GetLocalFileSize());
TaskFunc fn = [=]() {
PutObjectByFileResp resp;
m_object_op.PutObject(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncPutObject(const AsyncPutObjectReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
handler->SetTotalSize(req.GetLocalFileSize());
TaskFunc fn = [=]() {
PutObjectByFileResp resp;
m_object_op.PutObject(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncPutObject(const AsyncPutObjectByStreamReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
auto& is = req.GetStream();
is.seekg(0, std::ios::end);
handler->SetTotalSize(is.tellg());
is.seekg(0, std::ios::beg);
TaskFunc fn = [=]() {
PutObjectByStreamResp resp;
m_object_op.PutObject(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncPutObject(const AsyncPutObjectByStreamReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
auto& is = req.GetStream();
is.seekg(0, std::ios::end);
handler->SetTotalSize(is.tellg());
is.seekg(0, std::ios::beg);
TaskFunc fn = [=]() {
PutObjectByStreamResp resp;
m_object_op.PutObject(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncMultiPutObject(const AsyncMultiPutObjectReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
handler->SetTotalSize(req.GetLocalFileSize());
TaskFunc fn = [=]() {
MultiPutObjectResp resp;
m_object_op.MultiUploadObject(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncMultiPutObject(const AsyncMultiPutObjectReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
handler->SetTotalSize(req.GetLocalFileSize());
TaskFunc fn = [=]() {
MultiPutObjectResp resp;
m_object_op.MultiUploadObject(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncGetObject(const AsyncGetObjectReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.GetObject(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.GetObject(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncResumableGetObject(const AsyncGetObjectReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.ResumableGetObject(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncResumableGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.ResumableGetObject(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncMultiGetObject(const AsyncMultiGetObjectReq& req) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.MultiThreadDownload(req, &resp, handler);
};
GetGlobalTaskManager().start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
SharedAsyncContext CosAPI::AsyncMultiGetObject(const AsyncMultiGetObjectReq& req, Poco::TaskManager*& taskManager) {
SharedTransferHandler handler(new TransferHandler());
handler->SetRequest(reinterpret_cast<const void*>(&req));
TaskFunc fn = [=]() {
GetObjectByFileResp resp;
m_object_op.MultiThreadDownload(req, &resp, handler);
};
taskManager = &GetGlobalTaskManager();
(*taskManager).start(new AsyncTask(std::move(fn)));
SharedAsyncContext context(new AsyncContext(handler));
return context;
}
CosResult CosAPI::PutObjects(const PutObjectsByDirectoryReq& req,
PutObjectsByDirectoryResp* resp) {
return m_object_op.PutObjects(req, resp);
}
CosResult CosAPI::PutDirectory(const PutDirectoryReq& req,
PutDirectoryResp* resp) {
return m_object_op.PutDirectory(req, resp);
}
CosResult CosAPI::DeleteObjects(const DeleteObjectsByPrefixReq& req,
DeleteObjectsByPrefixResp* resp) {
CosResult get_bucket_result;
GetBucketReq get_bucket_req(req.GetBucketName());
get_bucket_req.SetPrefix(req.GetPrefix());
bool is_truncated = false;
do {
GetBucketResp get_bucket_resp;
get_bucket_result = m_bucket_op.GetBucket(get_bucket_req, &get_bucket_resp);
if (get_bucket_result.IsSucc()) {
std::vector<Content> contents = get_bucket_resp.GetContents();
for (auto& content : contents) {
DeleteObjectReq del_req(req.GetBucketName(), content.m_key);
DeleteObjectResp del_resp;
CosResult del_result = DeleteObject(del_req, &del_resp);
if (del_result.IsSucc()) {
resp->m_succ_del_objs.push_back(content.m_key);
} else {
return del_result;
}
}
get_bucket_req.SetMarker(get_bucket_resp.GetNextMarker());
is_truncated = get_bucket_resp.IsTruncated();
} else {
get_bucket_result = m_bucket_op.GetBucket(get_bucket_req, &get_bucket_resp, COS_CHANGE_BACKUP_DOMAIN);
}
} while (get_bucket_result.IsSucc() && is_truncated);
return get_bucket_result;
};
CosResult CosAPI::MoveObject(const MoveObjectReq& req) {
return m_object_op.MoveObject(req);
}
CosResult CosAPI::PutBucketToCI(const PutBucketToCIReq& req,
PutBucketToCIResp* resp) {
return m_bucket_op.PutBucketToCI(req, resp);
}
CosResult CosAPI::PutImage(PutImageByFileReq& req,
PutImageByFileResp* resp) {
req.CheckCoverOriginImage();
return m_object_op.PutImage(req, resp);
}
CosResult CosAPI::CloudImageProcess(const CloudImageProcessReq& req,
CloudImageProcessResp* resp) {
return m_object_op.CloudImageProcess(req, resp);
}
CosResult CosAPI::GetQRcode(const GetQRcodeReq& req, GetQRcodeResp* resp) {
return m_object_op.GetQRcode(req, resp);
}
CosResult
CosAPI::DescribeDocProcessBuckets(const DescribeDocProcessBucketsReq& req,
DescribeDocProcessBucketsResp* resp) {
return m_object_op.DescribeDocProcessBuckets(req, resp);
}
CosResult CosAPI::CreateDocBucket(const CreateDocBucketReq& req,
CreateDocBucketResp* resp) {
return m_bucket_op.CreateDocBucket(req, resp);
}
CosResult CosAPI::DocPreview(const DocPreviewReq& req, DocPreviewResp* resp) {
return m_object_op.DocPreview(req, resp);
}
CosResult CosAPI::CreateDocProcessJobs(const CreateDocProcessJobsReq& req,
CreateDocProcessJobsResp* resp) {
return m_bucket_op.CreateDocProcessJobs(req, resp);
}
CosResult CosAPI::DescribeDocProcessJob(const DescribeDocProcessJobReq& req,
DescribeDocProcessJobResp* resp) {
return m_bucket_op.DescribeDocProcessJob(req, resp);
}
CosResult CosAPI::DescribeDocProcessJobs(const DescribeDocProcessJobsReq& req,
DescribeDocProcessJobsResp* resp) {
return m_bucket_op.DescribeDocProcessJobs(req, resp);
}
CosResult
CosAPI::DescribeDocProcessQueues(const DescribeDocProcessQueuesReq& req,
DescribeDocProcessQueuesResp* resp) {
return m_bucket_op.DescribeDocProcessQueues(req, resp);
}
CosResult CosAPI::UpdateDocProcessQueue(const UpdateDocProcessQueueReq& req,
UpdateDocProcessQueueResp* resp) {
return m_bucket_op.UpdateDocProcessQueue(req, resp);
}
CosResult CosAPI::DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
DescribeMediaBucketsResp* resp) {
return m_bucket_op.DescribeMediaBuckets(req, resp);
}
CosResult CosAPI::CreateMediaBucket(const CreateMediaBucketReq& req,
CreateMediaBucketResp* resp) {
return m_bucket_op.CreateMediaBucket(req, resp);
}
CosResult CosAPI::GetSnapshot(const GetSnapshotReq& req,
GetSnapshotResp* resp) {
return m_object_op.GetObject(static_cast<GetObjectByFileReq>(req),
static_cast<GetObjectByFileResp*>(resp));
}
CosResult CosAPI::GetMediaInfo(const GetMediaInfoReq& req,
GetMediaInfoResp* resp) {
return m_object_op.GetMediaInfo(req, resp);
}
CosResult CosAPI::GetPm3u8(const GetPm3u8Req& req,
GetPm3u8Resp* resp) {
return m_object_op.GetObject(static_cast<GetObjectByFileReq>(req),
static_cast<GetObjectByFileResp*>(resp));
}
CosResult CosAPI::DescribeMediaQueues(const DescribeMediaQueuesReq& req,
DescribeQueuesResp* resp) {
return m_bucket_op.DescribeMediaQueues(req, resp);
}
CosResult CosAPI::UpdateMediaQueue(const UpdateMediaQueueReq& req,
UpdateQueueResp* resp) {
return m_bucket_op.UpdateMediaQueue(req, resp);
}
CosResult CosAPI::DescribeFileBuckets(const DescribeFileBucketsReq& req,
DescribeFileBucketsResp* resp) {
return m_bucket_op.DescribeFileBuckets(req, resp);
}
CosResult CosAPI::CreateFileBucket(const CreateFileBucketReq& req,
CreateFileBucketResp* resp) {
return m_bucket_op.CreateFileBucket(req, resp);
}
CosResult CosAPI::CreateDataProcessJobs(const CreateDataProcessJobsReq& req,
CreateDataProcessJobsResp* resp) {
return m_bucket_op.CreateDataProcessJobs(req, resp);
}
CosResult CosAPI::DescribeDataProcessJob(const DescribeDataProcessJobReq& req,
DescribeDataProcessJobResp* resp) {
return m_bucket_op.DescribeDataProcessJob(req, resp);
}
CosResult CosAPI::CancelDataProcessJob(const CancelDataProcessJobReq& req,
CancelDataProcessJobResp* resp) {
return m_bucket_op.CancelDataProcessJob(req, resp);
}
CosResult CosAPI::GetImageAuditing(const GetImageAuditingReq& req,
GetImageAuditingResp* resp) {
return m_object_op.GetImageAuditing(req, resp);
}
CosResult CosAPI::BatchImageAuditing(const BatchImageAuditingReq& req,
BatchImageAuditingResp* resp) {
return m_bucket_op.BatchImageAuditing(req, resp);
}
CosResult CosAPI::DescribeImageAuditingJob(const DescribeImageAuditingJobReq &req,
DescribeImageAuditingJobResp *resp) {
return m_bucket_op.DescribeImageAuditingJob(req, resp);
}
CosResult CosAPI::CreateVideoAuditingJob(const CreateVideoAuditingJobReq& req,
CreateVideoAuditingJobResp* resp) {
return m_bucket_op.CreateVideoAuditingJob(req, resp);
}
CosResult CosAPI::DescribeVideoAuditingJob(const DescribeVideoAuditingJobReq& req,
DescribeVideoAuditingJobResp* resp) {
return m_bucket_op.DescribeVideoAuditingJob(req, resp);
}
CosResult CosAPI::CreateAudioAuditingJob(const CreateAudioAuditingJobReq& req,
CreateAudioAuditingJobResp* resp) {
return m_bucket_op.CreateAudioAuditingJob(req, resp);
}
CosResult CosAPI::DescribeAudioAuditingJob(const DescribeAudioAuditingJobReq& req,
DescribeAudioAuditingJobResp* resp) {
return m_bucket_op.DescribeAudioAuditingJob(req, resp);
}
CosResult CosAPI::CreateTextAuditingJob(const CreateTextAuditingJobReq& req,
CreateTextAuditingJobResp* resp) {
return m_bucket_op.CreateTextAuditingJob(req, resp);
}
CosResult CosAPI::DescribeTextAuditingJob(const DescribeTextAuditingJobReq& req,
DescribeTextAuditingJobResp* resp) {
return m_bucket_op.DescribeTextAuditingJob(req, resp);
}
CosResult CosAPI::CreateDocumentAuditingJob(const CreateDocumentAuditingJobReq& req,
CreateDocumentAuditingJobResp* resp) {
return m_bucket_op.CreateDocumentAuditingJob(req, resp);
}
CosResult CosAPI::DescribeDocumentAuditingJob(const DescribeDocumentAuditingJobReq& req,
DescribeDocumentAuditingJobResp* resp) {
return m_bucket_op.DescribeDocumentAuditingJob(req, resp);
}
CosResult CosAPI::CreateWebPageAuditingJob(const CreateWebPageAuditingJobReq& req,
CreateWebPageAuditingJobResp* resp) {
return m_bucket_op.CreateWebPageAuditingJob(req, resp);
}
CosResult CosAPI::DescribeWebPageAuditingJob(const DescribeWebPageAuditingJobReq& req,
DescribeWebPageAuditingJobResp* resp) {
return m_bucket_op.DescribeWebPageAuditingJob(req, resp);
}
} // namespace qcloud_cos

327
src/cos_config.cpp Normal file
View File

@@ -0,0 +1,327 @@
#include "cos_config.h"
#include <fstream>
#include <iostream>
#include <mutex>
#include <string>
#include "cos_sys_config.h"
#include "util/string_util.h"
#include "util/illegal_intercept.h"
namespace qcloud_cos {
CosConfig::CosConfig(const std::string& config_file)
: m_app_id(0),
m_access_key(""),
m_secret_key(""),
m_region(""),
m_tmp_token(""),
m_set_intranet_once(false),
m_is_use_intranet(false),
m_intranet_addr(""),
m_dest_domain(""),
m_is_domain_same_to_host(false),
m_config_parsed(false),
m_max_retry_times(COS_DEFAULT_MAX_RETRY_TIMES),
m_retry_interval_ms(COS_DEFAULT_RETRY_INTERVAL_MS) {
if (InitConf(config_file)) {
m_config_parsed = true;
}
}
bool CosConfig::JsonObjectGetStringValue(
const Poco::JSON::Object::Ptr& json_object, const std::string& key,
std::string* value) {
if (json_object->has(key)) {
Poco::Dynamic::Var value_get = json_object->get(key);
if (value_get.isString()) {
(*value).clear();
*value = value_get.convert<std::string>();
return true;
} else {
std::cerr << "failed to parse config file, " << key
<< " should be interger" << std::endl;
}
}
return false;
}
bool CosConfig::JsonObjectGetIntegerValue(
const Poco::JSON::Object::Ptr& json_object, const std::string& key,
uint64_t* value) {
if (json_object->has(key)) {
Poco::Dynamic::Var value_get = json_object->get(key);
if (value_get.isInteger()) {
*value = value_get;
return true;
} else {
std::cerr << "failed to parse config file, " << key
<< " should be unsigned interger" << std::endl;
}
}
return false;
}
bool CosConfig::JsonObjectGetBoolValue(
const Poco::JSON::Object::Ptr& json_object, const std::string& key,
bool* value) {
if (json_object->has(key)) {
Poco::Dynamic::Var value_get = json_object->get(key);
if (value_get.isBoolean()) {
*value = value_get;
return true;
} else {
std::cerr << "failed to parse config file, " << key
<< " should be boolean" << std::endl;
}
}
return false;
}
bool CosConfig::InitConf(const std::string& config_file) {
Poco::JSON::Parser parser;
std::ifstream ifs(config_file.c_str(), std::ios::in);
if (!ifs || !ifs.is_open()) {
std::cerr << "failed to open config file " << config_file << std::endl;
return false;
}
std::istream& is = ifs;
Poco::Dynamic::Var result;
try {
result = parser.parse(is);
} catch (Poco::JSON::JSONException& jsone) {
std::cerr << "failed to parse config file, " << jsone.message()
<< std::endl;
return false;
}
if (result.type() != typeid(Poco::JSON::Object::Ptr)) {
std::cerr << "failed to parse config file " << config_file << std::endl;
ifs.close();
return false;
}
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
JsonObjectGetIntegerValue(object, "AppID", &m_app_id);
JsonObjectGetStringValue(object, "AccessKey", &m_access_key);
JsonObjectGetStringValue(object, "SecretId", &m_access_key);
JsonObjectGetStringValue(object, "SecretKey", &m_secret_key);
if (m_access_key.empty() || m_secret_key.empty()) {
std::cerr << "warnning, access_key or serete_key not exists" << std::endl;
}
m_access_key = StringUtil::Trim(m_access_key);
m_secret_key = StringUtil::Trim(m_secret_key);
//设置cos区域和下载域名:cos,cdn,innercos,自定义,默认:cos
JsonObjectGetStringValue(object, "Region", &m_region);
m_region = StringUtil::Trim(m_region);
JsonObjectGetIntegerValue(object, "RetryIntervalMs", &m_retry_interval_ms);
JsonObjectGetIntegerValue(object, "MaxRetryTimes", &m_max_retry_times);
uint64_t integer_value;
//设置签名超时时间,单位:秒
if (JsonObjectGetIntegerValue(object, "SignExpiredTime", &integer_value)) {
CosSysConfig::SetAuthExpiredTime(integer_value);
}
//设置连接超时时间,单位:毫秒
if (JsonObjectGetIntegerValue(object, "ConnectTimeoutInms", &integer_value)) {
CosSysConfig::SetConnTimeoutInms(integer_value);
}
//设置接收超时时间,单位:毫秒
if (JsonObjectGetIntegerValue(object, "ReceiveTimeoutInms", &integer_value)) {
CosSysConfig::SetRecvTimeoutInms(integer_value);
}
//设置上传分片大小,默认:10M
if (JsonObjectGetIntegerValue(object, "UploadPartSize", &integer_value)) {
CosSysConfig::SetUploadPartSize(integer_value);
}
//设置单文件分片并发上传的线程池大小
if (JsonObjectGetIntegerValue(object, "UploadThreadPoolSize",
&integer_value)) {
CosSysConfig::SetUploadThreadPoolSize((unsigned)integer_value);
}
//异步上传下载的线程池大小
if (JsonObjectGetIntegerValue(object, "AsynThreadPoolSize", &integer_value)) {
CosSysConfig::SetAsynThreadPoolSize((unsigned)integer_value);
}
//设置log输出,0:不输出, 1:屏幕,2:syslog,默认:0
if (JsonObjectGetIntegerValue(object, "LogoutType", &integer_value)) {
CosSysConfig::SetLogOutType((LOG_OUT_TYPE)integer_value);
}
// 设置日志级别
if (JsonObjectGetIntegerValue(object, "LogLevel", &integer_value)) {
CosSysConfig::SetLogLevel((LOG_LEVEL)integer_value);
}
if (JsonObjectGetIntegerValue(object, "DownloadThreadPoolSize",
&integer_value)) {
CosSysConfig::SetDownThreadPoolSize((unsigned)integer_value);
}
if (JsonObjectGetIntegerValue(object, "DownloadSliceSize", &integer_value)) {
CosSysConfig::SetDownSliceSize((unsigned)integer_value);
}
bool bool_value;
// 长连接相关
#if 0
if (JsonObjectGetBoolValue(object, "keepalive_mode", &bool_value)) {
CosSysConfig::SetKeepAlive(bool_value);
}
if (JsonObjectGetIntegerValue(object, "keepalive_idle_time", &integer_value)) {
CosSysConfig::SetKeepIdle(integer_value);
}
if (JsonObjectGetIntegerValue(object, "keepalive_interval_time", &integer_value)) {
CosSysConfig::SetKeepIntvl(integer_value);
}
#endif
if (JsonObjectGetBoolValue(object, "IsCheckMd5", &bool_value)) {
CosSysConfig::SetCheckMd5(bool_value);
}
std::string str_value;
if (JsonObjectGetStringValue(object, "DestDomain", &str_value)) {
CosSysConfig::SetDestDomain(str_value);
m_dest_domain = str_value;
}
if (JsonObjectGetBoolValue(object, "IsDomainSameToHost", &bool_value)) {
CosSysConfig::SetDomainSameToHost(bool_value);
}
if (JsonObjectGetBoolValue(object, "IsUseIntranet", &bool_value)) {
CosSysConfig::SetIsUseIntranet(bool_value);
m_is_use_intranet = bool_value;
m_set_intranet_once = true;
}
if (JsonObjectGetStringValue(object, "IntranetAddr", &str_value)) {
CosSysConfig::SetIntranetAddr(str_value);
m_intranet_addr = str_value;
m_set_intranet_once = true;
}
CosSysConfig::PrintValue();
return true;
}
uint64_t CosConfig::GetAppId() const { return m_app_id; }
std::string CosConfig::GetAccessKey() const {
std::lock_guard<std::mutex> lock(m_lock);
std::string ak = m_access_key;
return ak;
}
std::string CosConfig::GetSecretKey() const {
std::lock_guard<std::mutex> lock(m_lock);
std::string sk = m_secret_key;
return sk;
}
std::string CosConfig::GetRegion() const { return m_region; }
std::string CosConfig::GetTmpToken() const {
std::lock_guard<std::mutex> lock(m_lock);
std::string token = m_tmp_token;
return token;
}
uint64_t CosConfig::GetMaxRetryTimes() const {
return m_max_retry_times;
}
void CosConfig::SetMaxRetryTimes(uint64_t max_retry_count) {
m_max_retry_times = max_retry_count;
}
uint64_t CosConfig::GetRetryIntervalMs() const {
return m_retry_interval_ms;
}
void CosConfig::SetRetryIntervalMs(uint64_t retry_interval_ms) {
m_retry_interval_ms = retry_interval_ms;
}
void CosConfig::SetConfigCredentail(const std::string& access_key,
const std::string& secret_key,
const std::string& tmp_token) {
std::lock_guard<std::mutex> lock(m_lock);
m_access_key = access_key;
m_secret_key = secret_key;
m_tmp_token = tmp_token;
}
void CosConfig::SetIsUseIntranetAddr(bool is_use_intranet) {
CosSysConfig::SetIsUseIntranet(is_use_intranet);
m_is_use_intranet = is_use_intranet;
m_set_intranet_once = true;
}
bool CosConfig::IsUseIntranet() {
return m_is_use_intranet;
}
void CosConfig::SetIntranetAddr(const std::string& intranet_addr) {
CosSysConfig::SetIntranetAddr(intranet_addr);
m_intranet_addr = intranet_addr;
m_set_intranet_once = true;
}
std::string CosConfig::GetIntranetAddr() {
return m_intranet_addr;
}
void CosConfig::SetDestDomain(const std::string& domain) {
CosSysConfig::SetDestDomain(domain);
m_dest_domain = domain;
}
const std::string& CosConfig::GetDestDomain() const {
return m_dest_domain;
}
bool CosConfig::IsDomainSameToHost() const {
return m_is_domain_same_to_host;
}
void CosConfig::SetDomainSameToHost(bool is_domain_same_to_host) {
m_is_domain_same_to_host = is_domain_same_to_host;
m_is_domain_same_to_host_enable = true;
}
bool CosConfig::IsDomainSameToHostEnable() const {
return m_is_domain_same_to_host_enable;
}
void CosConfig::SetLogCallback(const LogCallback log_callback) {
CosSysConfig::SetLogCallback(log_callback);
}
bool CosConfig::CheckRegion() {
// 检查 region 是否符合规范
if (m_region.empty() || !IllegalIntercept::isAlnum(m_region.front()) || !IllegalIntercept::isAlnum(m_region.back())) {
return false;
}
for (size_t i = 1; i < m_region.size() - 1; ++i) {
char c = m_region[i];
if (!IllegalIntercept::isAlnum(c) && c != '.' && c != '-') {
return false;
}
}
return true;
}
} // namespace qcloud_cos

322
src/cos_sys_config.cpp Normal file
View File

@@ -0,0 +1,322 @@
#include "cos_sys_config.h"
#include <stdint.h>
#include <iostream>
#include <mutex>
#include "cos_defines.h"
#include "util/string_util.h"
namespace qcloud_cos {
//上传文件分片大小,默认10M
uint64_t CosSysConfig::m_upload_part_size = kPartSize1M * 10;
//上传复制文件分片大小,默认20M
uint64_t CosSysConfig::m_upload_copy_part_size = kPartSize1M * 20;
//签名超时时间,默认60秒
uint64_t CosSysConfig::m_sign_expire_in_s = 3600;
//本地时间与网络时间差值默认为0
int64_t CosSysConfig::m_timestamp_delta = 0;
// HTTP连接/接收时间(秒)
uint64_t CosSysConfig::m_conn_timeout_in_ms = 5 * 1000;
uint64_t CosSysConfig::m_recv_timeout_in_ms = 5 * 1000;
unsigned CosSysConfig::m_threadpool_size = kDefaultThreadPoolSizeUploadPart;
unsigned CosSysConfig::m_asyn_threadpool_size = kDefaultPoolSize;
//日志输出
LOG_OUT_TYPE CosSysConfig::m_log_outtype = COS_LOG_STDOUT;
LOG_LEVEL CosSysConfig::m_log_level = COS_LOG_DBG;
//下载文件到本地线程池大小
unsigned CosSysConfig::m_down_thread_pool_size = 10;
//下载文件到本地,每次下载字节数
unsigned CosSysConfig::m_down_slice_size = 4 * 1024 * 1024;
// 长连接
bool CosSysConfig::m_keep_alive = false;
int64_t CosSysConfig::m_keep_idle = 20;
int64_t CosSysConfig::m_keep_intvl = 5;
bool CosSysConfig::m_is_check_md5 = false;
// 设置私有云host
// NOCA:StaticGlobalString(设计如此)
std::string CosSysConfig::m_dest_domain = "";
bool CosSysConfig::m_is_domain_same_to_host = false;
// 设置私有ip和host
// NOCA:StaticGlobalString(设计如此)
std::string CosSysConfig::m_intranet_addr = "";
bool CosSysConfig::m_is_use_intranet = false;
LogCallback CosSysConfig::m_log_callback = nullptr;
// 是否使用dns cache
bool CosSysConfig::m_use_dns_cache = false;
// dns cache过期时间
unsigned CosSysConfig::m_dns_cache_expire_seconds = 600;
// dns cache大小
unsigned CosSysConfig::m_dns_cache_size = 1000;
bool CosSysConfig::m_retry_change_domain = false;
bool CosSysConfig::m_object_key_simplify_check = true;
std::mutex m_intranet_addr_lock;
std::mutex m_dest_domain_lock;
void CosSysConfig::PrintValue() {
std::cout << "upload_part_size:" << m_upload_part_size << std::endl;
std::cout << "upload_copy_part_size:" << m_upload_copy_part_size << std::endl;
std::cout << "sign_expire_in_s:" << m_sign_expire_in_s << std::endl;
std::cout << "conn_timeout_in_ms:" << m_conn_timeout_in_ms << std::endl;
std::cout << "recv_timeout_in_ms:" << m_recv_timeout_in_ms << std::endl;
std::cout << "threadpool_size:" << m_threadpool_size << std::endl;
std::cout << "asyn_threadpool_size:" << m_asyn_threadpool_size << std::endl;
std::cout << "log_outtype:" << m_log_outtype << std::endl;
std::cout << "log_level:" << m_log_level << std::endl;
std::cout << "down_thread_pool_size:" << m_down_thread_pool_size << std::endl;
std::cout << "down_slice_size:" << m_down_slice_size << std::endl;
std::cout << "is_domain_same_to_host:" << m_is_domain_same_to_host
<< std::endl;
std::cout << "dest_domain:" << m_dest_domain << std::endl;
std::cout << "is_use_intranet:" << m_is_use_intranet << std::endl;
std::cout << "intranet_addr:" << m_intranet_addr << std::endl;
std::cout << "keepalive:" << m_keep_alive << std::endl;
std::cout << "keepidle:" << m_keep_idle << std::endl;
std::cout << "keepintvl:" << m_keep_intvl << std::endl;
}
void CosSysConfig::SetKeepAlive(bool keep_alive) { m_keep_alive = keep_alive; }
void CosSysConfig::SetKeepIdle(int64_t keep_idle) { m_keep_idle = keep_idle; }
void CosSysConfig::SetKeepIntvl(int64_t keep_intvl) {
m_keep_intvl = keep_intvl;
}
void CosSysConfig::SetUploadPartSize(uint64_t part_size) {
m_upload_part_size = part_size;
}
void CosSysConfig::SetUploadCopyPartSize(uint64_t part_size) {
m_upload_copy_part_size = part_size;
}
void CosSysConfig::SetDownThreadPoolSize(unsigned size) {
if (size > 10) {
m_down_thread_pool_size = 10;
} else if (size < 1) {
m_down_thread_pool_size = 1;
} else {
m_down_thread_pool_size = size;
}
}
void CosSysConfig::SetDownSliceSize(unsigned slice_size) {
if (slice_size < 4 * 1024) {
m_down_slice_size = 4 * 1024;
} else if (slice_size > 20 * 1024 * 1024) {
m_down_slice_size = 20 * 1024 * 1024;
} else {
m_down_slice_size = slice_size;
}
}
void CosSysConfig::SetDestDomain(const std::string& dest_domain) {
std::lock_guard<std::mutex> lock(m_dest_domain_lock);
m_dest_domain = dest_domain;
}
unsigned CosSysConfig::GetDownThreadPoolSize() {
return m_down_thread_pool_size;
}
unsigned CosSysConfig::GetDownSliceSize() { return m_down_slice_size; }
bool CosSysConfig::GetKeepAlive() { return m_keep_alive; }
int64_t CosSysConfig::GetKeepIdle() { return m_keep_idle; }
int64_t CosSysConfig::GetKeepIntvl() { return m_keep_intvl; }
void CosSysConfig::SetAuthExpiredTime(uint64_t time) {
m_sign_expire_in_s = time;
}
void CosSysConfig::SetTimeStampDelta(int64_t delta) {
m_timestamp_delta = delta;
}
void CosSysConfig::SetConnTimeoutInms(uint64_t time) {
m_conn_timeout_in_ms = time;
}
void CosSysConfig::SetRecvTimeoutInms(uint64_t time) {
m_recv_timeout_in_ms = time;
}
void CosSysConfig::SetUploadThreadPoolSize(unsigned size) {
if (size > kMaxThreadPoolSizeUploadPart) {
m_threadpool_size = kMaxThreadPoolSizeUploadPart;
} else if (size < kMinThreadPoolSizeUploadPart) {
m_threadpool_size = kMinThreadPoolSizeUploadPart;
} else {
m_threadpool_size = size;
}
}
void CosSysConfig::SetAsynThreadPoolSize(unsigned size) {
// 异步线程池不设置上限
if (size < kMinThreadPoolSizeUploadPart) {
m_asyn_threadpool_size = kMinThreadPoolSizeUploadPart;
return;
}
m_asyn_threadpool_size = size;
}
unsigned CosSysConfig::GetAsynThreadPoolSize() {
return m_asyn_threadpool_size;
}
unsigned CosSysConfig::GetUploadThreadPoolSize() { return m_threadpool_size; }
void CosSysConfig::SetLogOutType(LOG_OUT_TYPE log) { m_log_outtype = log; }
void CosSysConfig::SetLogLevel(LOG_LEVEL level) { m_log_level = level; }
int CosSysConfig::GetLogOutType() { return (int)m_log_outtype; }
int CosSysConfig::GetLogLevel() { return (int)m_log_level; }
uint64_t CosSysConfig::GetUploadPartSize() { return m_upload_part_size; }
uint64_t CosSysConfig::GetUploadCopyPartSize() {
return m_upload_copy_part_size;
}
uint64_t CosSysConfig::GetAuthExpiredTime() { return m_sign_expire_in_s; }
int64_t CosSysConfig::GetTimeStampDelta() { return m_timestamp_delta; }
uint64_t CosSysConfig::GetConnTimeoutInms() { return m_conn_timeout_in_ms; }
uint64_t CosSysConfig::GetRecvTimeoutInms() { return m_recv_timeout_in_ms; }
bool CosSysConfig::IsCheckMd5() { return m_is_check_md5; }
void CosSysConfig::SetCheckMd5(bool is_check_md5) {
m_is_check_md5 = is_check_md5;
}
bool CosSysConfig::IsDomainSameToHost() { return m_is_domain_same_to_host; }
void CosSysConfig::SetDomainSameToHost(bool is_domain_same_to_host) {
m_is_domain_same_to_host = is_domain_same_to_host;
}
void CosSysConfig::SetIsUseIntranet(bool is_use_intranet) {
m_is_use_intranet = is_use_intranet;
}
bool CosSysConfig::IsUseIntranet() { return m_is_use_intranet; }
void CosSysConfig::SetIntranetAddr(const std::string& intranet_addr) {
std::lock_guard<std::mutex> lock(m_intranet_addr_lock);
m_intranet_addr = intranet_addr;
}
std::string CosSysConfig::GetHost(uint64_t app_id, const std::string& region,
const std::string& bucket_name, bool change_backup_domain) {
std::string format_region("");
if (region == "cn-east" || region == "cn-north" || region == "cn-south" ||
region == "cn-southwest" || region == "cn-south-2" || region == "sg" ||
StringUtil::StringStartsWith(region, "cos.")) {
format_region = region;
} else {
format_region = "cos." + region;
}
std::string app_id_suffix = "-" + StringUtil::Uint64ToString(app_id);
std::string domain_suffix = change_backup_domain ? ".tencentcos.cn" : ".myqcloud.com";
if (app_id == 0 || StringUtil::StringEndsWith(bucket_name, app_id_suffix)) {
return bucket_name + "." + format_region + domain_suffix;
}
return bucket_name + app_id_suffix + "." + format_region + domain_suffix;
}
std::string CosSysConfig::GetCIHost(const std::string& bucket_name,
const std::string& region) {
std::string host;
if (bucket_name.empty()) {
host = "ci." + region + ".myqcloud.com";
} else {
host = bucket_name + ".ci." + region + ".myqcloud.com";
}
return host;
}
std::string CosSysConfig::GetPICHost(uint64_t app_id, const std::string& region,
const std::string& bucket_name) {
std::string app_id_suffix = "-" + StringUtil::Uint64ToString(app_id);
if (app_id == 0 || StringUtil::StringEndsWith(bucket_name, app_id_suffix)) {
return bucket_name + ".pic." + region + ".myqcloud.com";
}
return bucket_name + app_id_suffix + ".pic." + region + ".myqcloud.com";
}
std::string CosSysConfig::GetDestDomain() {
std::lock_guard<std::mutex> lock(m_dest_domain_lock);
return m_dest_domain;
}
std::string CosSysConfig::GetIntranetAddr() {
std::lock_guard<std::mutex> lock(m_intranet_addr_lock);
return m_intranet_addr;
}
LogCallback CosSysConfig::GetLogCallback() { return m_log_callback; }
void CosSysConfig::SetLogCallback(const LogCallback log_callback) {
m_log_callback = log_callback;
}
void CosSysConfig::SetUseDnsCache(bool use_dns_cache) {
m_use_dns_cache = use_dns_cache;
}
bool CosSysConfig::GetUseDnsCache() { return m_use_dns_cache; }
void CosSysConfig::SetDnsCacheExpireSeconds(unsigned expire_secondes) {
m_dns_cache_expire_seconds = expire_secondes;
}
unsigned CosSysConfig::GetDnsCacheExpireSeconds() {
return m_dns_cache_expire_seconds;
}
void CosSysConfig::SetDnsCacheSize(unsigned cache_size) {
m_dns_cache_size = cache_size;
}
unsigned CosSysConfig::GetDnsCacheSize() { return m_dns_cache_size; }
void CosSysConfig::SetRetryChangeDomain(bool retry_change_domain) {
m_retry_change_domain = retry_change_domain;
}
bool CosSysConfig::GetRetryChangeDomain() {
return m_retry_change_domain;
}
void CosSysConfig::SetObjectKeySimplifyCheck(bool object_key_simplify_check) {
m_object_key_simplify_check = object_key_simplify_check;
}
bool CosSysConfig::GetObjectKeySimplifyCheck() {
return m_object_key_simplify_check;
}
} // namespace qcloud_cos

450
src/op/base_op.cpp Normal file
View File

@@ -0,0 +1,450 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#include "op/base_op.h"
#include <iostream>
#include <unordered_set>
#include <regex>
#include "cos_sys_config.h"
#include "request/base_req.h"
#include "response/base_resp.h"
#include "util/auth_tool.h"
#include "util/http_sender.h"
#include "util/simple_dns_cache.h"
#include "trsf/transfer_handler.h"
namespace qcloud_cos {
CosConfig BaseOp::GetCosConfig() const { return *m_config; }
uint64_t BaseOp::GetAppId() const { return m_config->GetAppId(); }
std::string BaseOp::GetRegion() const { return m_config->GetRegion(); }
std::string BaseOp::GetAccessKey() const { return m_config->GetAccessKey(); }
std::string BaseOp::GetSecretKey() const { return m_config->GetSecretKey(); }
std::string BaseOp::GetTmpToken() const { return m_config->GetTmpToken(); }
std::string BaseOp::GetDestDomain() const {
return m_config->GetDestDomain().empty() ?
CosSysConfig::GetDestDomain() : m_config->GetDestDomain();
}
bool BaseOp::IsDomainSameToHost() const {
return m_config->IsDomainSameToHostEnable() ?
m_config->IsDomainSameToHost() : CosSysConfig::IsDomainSameToHost();
}
bool BaseOp::IsDefaultHost(const std::string &host) const {
size_t dot_pos = host.find('.');
if (dot_pos == std::string::npos) {
return false;
}
const char* str = host.substr(dot_pos + 1).c_str();
if (str == NULL) {
return false;
}
int len = strlen(str);
int i = 0;
// 匹配 \cos\.
if (i >= len || strncmp(str + i, "cos.", 4) != 0) {
return false;
}
i += 4;
// 匹配 ([\w-]+)-([\w-]+)
int flag = 0;
while (i < len && (isalnum(str[i]) || str[i] == '-')) {
if(str[i] == '-') flag = 1;
i++;
}
if (i >= len || str[i] != '.' || !flag) {
return false;
}
if (i >= len || strncmp(str + i, ".myqcloud.com", 13) != 0) {
return false;
}
i += 13;
return i == len;
}
bool BaseOp::NoNeedRetry(const CosResult &result) {
if (result.IsSucc()) {
// 请求成功, 不重试
return true;
}
int statusCode = result.GetHttpStatus();
return statusCode >= 400 && statusCode < 500;
}
CosResult BaseOp::NormalAction(const std::string& host, const std::string& path,
const BaseReq& req, const std::string& req_body,
bool check_body, BaseResp* resp, bool is_ci_req) {
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, check_body, resp, is_ci_req);
}
CosResult BaseOp::NormalAction(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
const std::string& req_body, bool check_body, BaseResp* resp,
bool is_ci_req) {
CosResult result;
if (!CheckConfigValidation()) {
std::string err_msg =
"Invalid access_key secret_key or region, please check your "
"configuration";
SDK_LOG_ERR("%s", err_msg.c_str());
result.SetErrorMsg(err_msg);
result.SetFail();
return result;
}
std::string domain = host;
for (uint32_t i = 0; ; i++) {
result = NormalRequest(domain, path, req, additional_headers, additional_params, req_body, check_body, resp, i, is_ci_req);
if (i >= m_op_util.GetMaxRetryTimes() || NoNeedRetry(result)) {
return result;
}
if (m_op_util.ShouldChangeBackupDomain(result, i, is_ci_req)) {
domain = BaseOpUtil::ChangeHostSuffix(domain);
}
m_op_util.SleepBeforeRetry(i);
}
}
CosResult BaseOp::NormalRequest(const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
const std::string& req_body, bool check_body, BaseResp* resp,
const uint32_t &request_retry_num, bool is_ci_req) {
CosResult result;
std::map<std::string, std::string> req_headers = req.GetHeaders();
std::map<std::string, std::string> req_params = req.GetParams();
req_headers.insert(additional_headers.begin(), additional_headers.end());
req_params.insert(additional_params.begin(), additional_params.end());
const std::string& tmp_token = m_config->GetTmpToken();
if (!tmp_token.empty()) {
if (is_ci_req) {
req_headers["x-ci-security-token"] = tmp_token;
} else {
req_headers["x-cos-security-token"] = tmp_token;
}
}
// 1. 获取host
if (!IsDomainSameToHost()) {
req_headers["Host"] = host;
} else {
req_headers["Host"] = GetDestDomain();
}
if (request_retry_num > 0) {
req_headers[kReqHeaderXCosSdkRetry] = "true";
}
std::unordered_set<std::string> not_sign_headers;
if (!req.SignHeaderHost()) {
not_sign_headers.insert("Host");
}
req_headers[kHttpHeaderContentLength] = std::to_string(req_body.length());
// 2. 计算签名
std::string auth_str = AuthTool::Sign(GetAccessKey(), GetSecretKey(), req.GetMethod(),
req.GetPath(), req_headers, req_params, not_sign_headers);
if (auth_str.empty()) {
result.SetErrorMsg("Generate auth str fail, check your access_key/secret_key.");
return result;
}
req_headers["Authorization"] = auth_str;
// 3. 发送请求
std::map<std::string, std::string> resp_headers;
std::string resp_body;
std::string dest_url = GetRealUrl(host, path, req.IsHttps());
std::string err_msg = "";
int http_code = HttpSender::SendRequest(nullptr,
req.GetMethod(), dest_url, req_params, req_headers, req_body,
req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers,
&resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation(),
req.GetSSLCtxCallback(), req.GetSSLCtxCbData());
if (http_code == -1) {
result.SetErrorMsg(err_msg);
return result;
}
// 4. 解析返回的xml字符串
result.SetHttpStatus(http_code);
if (http_code > 299 || http_code < 200) {
// 无法解析的错误, 填充到cos_result的error_info中
if (!result.ParseFromHttpResponse(resp_headers, resp_body)) {
result.SetErrorMsg(resp_body);
}
return result;
}
// 某些请求如PutObjectCopy/Complete请求需要进一步检查Body
if (check_body && result.ParseFromHttpResponse(resp_headers, resp_body)) {
result.SetErrorMsg(resp_body);
return result;
}
result.SetSucc();
resp->ParseFromXmlString(resp_body);
resp->ParseFromHeaders(resp_headers);
resp->SetBody(resp_body);
// resp requestid to result
result.SetXCosRequestId(resp->GetXCosRequestId());
return result;
}
CosResult BaseOp::DownloadAction(const std::string& host,
const std::string& path, const BaseReq& req,
BaseResp* resp, std::ostream& os,
const SharedTransferHandler& handler) {
CosResult result;
if (!CheckConfigValidation()) {
std::string err_msg =
"Invalid access_key secret_key or region, please check your "
"configuration";
SDK_LOG_ERR("%s", err_msg.c_str());
result.SetErrorMsg(err_msg);
result.SetFail();
return result;
}
std::string domain = host;
for (uint32_t i = 0; ; i++) {
result = DownloadRequest(domain, path, req, resp, os, i, handler);
if (i >= m_op_util.GetMaxRetryTimes() || NoNeedRetry(result)) {
return result;
}
os.rdbuf()->pubseekpos(0, std::ios_base::out);
os.clear();
if (m_op_util.ShouldChangeBackupDomain(result, i)) {
domain = BaseOpUtil::ChangeHostSuffix(domain);
}
m_op_util.SleepBeforeRetry(i);
}
}
CosResult BaseOp::DownloadRequest(const std::string &host, const std::string &path, const BaseReq &req,
BaseResp *resp, std::ostream &os, const uint32_t &request_retry_num, const SharedTransferHandler &handler) {
CosResult result;
std::map<std::string, std::string> req_headers = req.GetHeaders();
std::map<std::string, std::string> req_params = req.GetParams();
const std::string& tmp_token = m_config->GetTmpToken();
if (!tmp_token.empty()) {
req_headers["x-cos-security-token"] = tmp_token;
}
// 1. 获取host
if (!IsDomainSameToHost()) {
req_headers["Host"] = host;
} else {
req_headers["Host"] = GetDestDomain();
}
if (request_retry_num > 0) {
req_headers[kReqHeaderXCosSdkRetry] = "true";
}
std::unordered_set<std::string> not_sign_headers;
if (!req.SignHeaderHost()) {
not_sign_headers.insert("Host");
}
// 2. 计算签名
std::string auth_str =
AuthTool::Sign(GetAccessKey(), GetSecretKey(), req.GetMethod(),
req.GetPath(), req_headers, req_params, not_sign_headers);
if (auth_str.empty()) {
result.SetErrorMsg(
"Generate auth str fail, check your access_key/secret_key.");
return result;
}
req_headers["Authorization"] = auth_str;
// 3. 发送请求
std::map<std::string, std::string> resp_headers;
std::string xml_err_str; // 发送失败返回的xml写入该字符串避免直接输出到流中
std::string dest_url = GetRealUrl(host, path, req.IsHttps());
std::string err_msg = "";
uint64_t real_byte;
int http_code = HttpSender::SendRequest(
handler, req.GetMethod(), dest_url, req_params, req_headers, "",
req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers,
&xml_err_str, os, &err_msg, &real_byte, req.CheckMD5(),
req.GetVerifyCert(), req.GetCaLocation(),
req.GetSSLCtxCallback(), req.GetSSLCtxCbData());
if (http_code == -1) {
result.SetErrorMsg(err_msg);
resp->ParseFromHeaders(resp_headers);
result.SetXCosRequestId(resp->GetXCosRequestId());
return result;
}
result.SetRealByte(real_byte);
// 4. 解析返回的xml字符串
result.SetHttpStatus(http_code);
if (http_code > 299 || http_code < 200) {
// 无法解析的错误, 填充到cos_result的error_info中
if (!result.ParseFromHttpResponse(resp_headers, xml_err_str)) {
result.SetErrorMsg(xml_err_str);
}
} else {
result.SetSucc();
resp->ParseFromHeaders(resp_headers);
// resp requestid to result
result.SetXCosRequestId(resp->GetXCosRequestId());
}
// Check the resp content length header, when return 200, but size not match
// case.
if (result.IsSucc() && resp->GetContentLength() != real_byte) {
result.SetFail();
result.SetErrorMsg("Download failed with incomplete file");
SDK_LOG_ERR("Response content length %" PRIu64
" is not same to real recv byte %" PRIu64,
resp->GetContentLength(), real_byte);
}
return result;
}
CosResult BaseOp::UploadAction(
const std::string& host, const std::string& path, const BaseReq& req,
const std::map<std::string, std::string>& additional_headers,
const std::map<std::string, std::string>& additional_params,
std::istream& is, BaseResp* resp, const SharedTransferHandler& handler) {
CosResult result;
if (!CheckConfigValidation()) {
std::string err_msg =
"Invalid access_key secret_key or region, please check your "
"configuration";
SDK_LOG_ERR("%s", err_msg.c_str());
result.SetErrorMsg(err_msg);
return result;
}
std::string domain = host;
for (uint32_t i = 0; ; i++) {
std::streampos initial_pos = is.tellg();
result = UploadRequest(domain, path, req, additional_headers, additional_params, is, resp, i, handler);
if (i >= m_op_util.GetMaxRetryTimes() || NoNeedRetry(result) ) {
return result;
}
if (m_op_util.ShouldChangeBackupDomain(result, i)) {
domain = BaseOpUtil::ChangeHostSuffix(domain);
}
is.clear();
is.seekg(initial_pos);
m_op_util.SleepBeforeRetry(i);
}
}
CosResult BaseOp::UploadRequest(
const std::string &host, const std::string &path, const BaseReq &req,
const std::map<std::string, std::string> &additional_headers,
const std::map<std::string, std::string> &additional_params,
std::istream &is, BaseResp *resp, const uint32_t &request_retry_num, const SharedTransferHandler &handler) {
CosResult result;
std::map<std::string, std::string> req_headers = req.GetHeaders();
std::map<std::string, std::string> req_params = req.GetParams();
req_headers.insert(additional_headers.begin(), additional_headers.end());
req_params.insert(additional_params.begin(), additional_params.end());
const std::string &tmp_token = m_config->GetTmpToken();
if (!tmp_token.empty()) {
req_headers["x-cos-security-token"] = tmp_token;
}
// 1. 获取host
if (!IsDomainSameToHost()) {
req_headers["Host"] = host;
} else {
req_headers["Host"] = GetDestDomain();
}
if (request_retry_num > 0) {
req_headers[kReqHeaderXCosSdkRetry] = "true";
}
std::unordered_set<std::string> not_sign_headers;
if (!req.SignHeaderHost()) {
not_sign_headers.insert("Host");
}
req_headers[kHttpHeaderContentLength] = std::to_string(StringUtil::GetLengthFromIStream(is));
// 2. 计算签名
std::string auth_str =
AuthTool::Sign(GetAccessKey(), GetSecretKey(), req.GetMethod(),
req.GetPath(), req_headers, req_params, not_sign_headers);
if (auth_str.empty()) {
result.SetErrorMsg(
"Generate auth str fail, check your access_key/secret_key.");
return result;
}
req_headers["Authorization"] = auth_str;
// 3. 发送请求
std::map<std::string, std::string> resp_headers;
std::string resp_body;
std::string dest_url = GetRealUrl(host, path, req.IsHttps());
std::string err_msg = "";
int http_code = HttpSender::SendRequest(
handler, req.GetMethod(), dest_url, req_params, req_headers, is,
req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers,
&resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation(),
req.GetSSLCtxCallback(), req.GetSSLCtxCbData());
if (http_code == -1) {
result.SetErrorMsg(err_msg);
return result;
}
// 4. 解析返回的xml字符串
result.SetHttpStatus(http_code);
if (http_code > 299 || http_code < 200) {
// 无法解析的错误, 填充到cos_result的error_info中
if (!result.ParseFromHttpResponse(resp_headers, resp_body)) {
result.SetErrorMsg(resp_body);
}
} else {
result.SetSucc();
resp->ParseFromXmlString(resp_body);
resp->ParseFromHeaders(resp_headers);
resp->SetBody(resp_body);
//resp->SetHeaders(resp_headers);
result.SetXCosRequestId(resp->GetXCosRequestId());
}
return result;
}
// 1. host优先级私有ip > 自定义域名 > DNS cache > 默认域名
std::string BaseOp::GetRealUrl(const std::string& host, const std::string& path,
bool is_https, bool is_generate_presigned_url) {
return m_op_util.GetRealUrl(host, path, is_https, is_generate_presigned_url);
}
bool BaseOp::CheckConfigValidation() const {
if (GetAccessKey().empty() || GetSecretKey().empty() || GetRegion().empty()) {
return false;
}
return true;
}
} // namespace qcloud_cos

738
src/op/bucket_op.cpp Normal file
View File

@@ -0,0 +1,738 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/21/17
// Description:
#include "op/bucket_op.h"
#include "cos_defines.h"
#include "util/codec_util.h"
namespace qcloud_cos {
bool BucketOp::IsBucketExist(const std::string& bucket_name) {
HeadBucketReq req(bucket_name);
HeadBucketResp resp;
CosResult result = HeadBucket(req, &resp);
return result.IsSucc();
}
std::string BucketOp::GetBucketLocation(const std::string& bucket_name) {
GetBucketLocationReq req(bucket_name);
GetBucketLocationResp resp;
CosResult result = GetBucketLocation(req, &resp);
if (result.IsSucc()) {
return resp.GetLocation();
}
return "";
}
CosResult BucketOp::HeadBucket(const HeadBucketReq& req, HeadBucketResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucket(const PutBucketReq& req, PutBucketResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body = req.GetBody();
return NormalAction(host, path, req, req_body, false, resp);
}
CosResult BucketOp::GetBucket(const GetBucketReq& req, GetBucketResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::ListMultipartUpload(const ListMultipartUploadReq& req,
ListMultipartUploadResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DeleteBucket(const DeleteBucketReq& req,
DeleteBucketResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketVersioning(const GetBucketVersioningReq& req,
GetBucketVersioningResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketVersioning(const PutBucketVersioningReq& req,
PutBucketVersioningResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketVersioning Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketReplication(const GetBucketReplicationReq& req,
GetBucketReplicationResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketReplication(const PutBucketReplicationReq& req,
PutBucketReplicationResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketReplication Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::DeleteBucketReplication(
const DeleteBucketReplicationReq& req, DeleteBucketReplicationResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketLifecycle(const GetBucketLifecycleReq& req,
GetBucketLifecycleResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketLifecycle(const PutBucketLifecycleReq& req,
PutBucketLifecycleResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketLifecycle Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::DeleteBucketLifecycle(const DeleteBucketLifecycleReq& req,
DeleteBucketLifecycleResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketACL(const GetBucketACLReq& req,
GetBucketACLResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketACL(const PutBucketACLReq& req,
PutBucketACLResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
CosResult result;
std::string req_body;
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
const std::map<std::string, std::string>& headers = req.GetHeaders();
// 头部中不包含任何授权信息,则通过 Body 以 XML 格式传入 ACL 信息
if (headers.find("x-cos-acl") == headers.end() &&
headers.find("x-cos-grant-read") == headers.end() &&
headers.find("x-cos-grant-write") == headers.end() &&
headers.find("x-cos-grant-full-control") == headers.end()) {
if (!req.GenerateRequestBody(&req_body)) {
result.SetErrorMsg("Generate PutBucketACL Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
}
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::PutBucketPolicy(const PutBucketPolicyReq& req,
PutBucketPolicyResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body = req.GetBody();
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketPolicy(const GetBucketPolicyReq& req,
GetBucketPolicyResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DeleteBucketPolicy(const DeleteBucketPolicyReq& req,
DeleteBucketPolicyResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketCORS(const GetBucketCORSReq& req,
GetBucketCORSResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketCORS(const PutBucketCORSReq& req,
PutBucketCORSResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketCORS Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::DeleteBucketCORS(const DeleteBucketCORSReq& req,
DeleteBucketCORSResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketLocation(const GetBucketLocationReq& req,
GetBucketLocationResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::GetBucketObjectVersions(
const GetBucketObjectVersionsReq& req, GetBucketObjectVersionsResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketLogging(const PutBucketLoggingReq& req,
PutBucketLoggingResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketLogging Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketLogging(const GetBucketLoggingReq& req,
GetBucketLoggingResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketDomain(const PutBucketDomainReq& req,
PutBucketDomainResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketDomain Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketDomain(const GetBucketDomainReq& req,
GetBucketDomainResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketWebsite(const PutBucketWebsiteReq& req,
PutBucketWebsiteResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketWebsite Request Body fail.");
return result;
}
return NormalAction(host, path, req, req_body, false, resp);
}
CosResult BucketOp::GetBucketWebsite(const GetBucketWebsiteReq& req,
GetBucketWebsiteResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DeleteBucketWebsite(const DeleteBucketWebsiteReq& req,
DeleteBucketWebsiteResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketTagging(const PutBucketTaggingReq& req,
PutBucketTaggingResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketWebsite Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketTagging(const GetBucketTaggingReq& req,
GetBucketTaggingResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DeleteBucketTagging(const DeleteBucketTaggingReq& req,
DeleteBucketTaggingResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketInventory(const PutBucketInventoryReq& req,
PutBucketInventoryResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
// id必须设置.
if (!req.HasId()) {
CosResult result;
result.SetErrorMsg("PutBucketinventory need to set Id.");
return result;
}
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketWebsite Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketInventory(const GetBucketInventoryReq& req,
GetBucketInventoryResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
// id必须设置.
if (!req.HasId()) {
CosResult result;
result.SetErrorMsg("GetBucketinventory need to set Id.");
return result;
}
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::ListBucketInventoryConfigurations(
const ListBucketInventoryConfigurationsReq& req,
ListBucketInventoryConfigurationsResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DeleteBucketInventory(const DeleteBucketInventoryReq& req,
DeleteBucketInventoryResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
// id必须设置.
if (!req.HasId()) {
CosResult result;
result.SetErrorMsg("DeleteBucketinventory need to set Id.");
return result;
}
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketReferer(const PutBucketRefererReq& req,
PutBucketRefererResp* resp, bool change_backup_domain) {
return ProcessReq(req, resp);
}
CosResult BucketOp::GetBucketReferer(const GetBucketRefererReq& req,
GetBucketRefererResp* resp, bool change_backup_domain) {
return ProcessReq(req, resp);
}
CosResult BucketOp::ListLiveChannel(const ListLiveChannelReq& req,
ListLiveChannelResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketIntelligentTiering(
const PutBucketIntelligentTieringReq& req,
PutBucketIntelligentTieringResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate PutBucketWebsite Request Body fail.");
return result;
}
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp);
}
CosResult BucketOp::GetBucketIntelligentTiering(
const GetBucketIntelligentTieringReq& req,
GetBucketIntelligentTieringResp* resp, bool change_backup_domain) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName(), change_backup_domain);
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::PutBucketToCI(const PutBucketToCIReq& req,
PutBucketToCIResp* resp) {
std::string host = CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion());
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::ProcessReq(const BucketReq& req, BaseResp* resp,
bool is_ci_req) {
std::string host =
is_ci_req
? CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion())
: CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName());
std::string path = req.GetPath();
std::string req_body;
if (!req.GenerateRequestBody(&req_body)) {
CosResult result;
result.SetErrorMsg("Generate request body fail.");
return result;
}
if (is_ci_req) {
if (!req_body.empty()) {
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp, is_ci_req);
}
return NormalAction(host, path, req, "", false, resp, is_ci_req);
}
if (!req_body.empty()) {
std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
std::map<std::string, std::string> additional_headers;
std::map<std::string, std::string> additional_params;
additional_headers.insert(std::make_pair("Content-MD5", raw_md5));
return NormalAction(host, path, req, additional_headers, additional_params,
req_body, false, resp, is_ci_req);
} else {
return NormalAction(host, path, req, "", false, resp, is_ci_req);
}
}
CosResult BucketOp::CreateDocBucket(const CreateDocBucketReq& req,
CreateDocBucketResp* resp) {
std::string host = CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion());
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::CreateDocProcessJobs(const CreateDocProcessJobsReq& req,
CreateDocProcessJobsResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeDocProcessJob(const DescribeDocProcessJobReq& req,
DescribeDocProcessJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeDocProcessJobs(const DescribeDocProcessJobsReq& req,
DescribeDocProcessJobsResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeDocProcessQueues(const DescribeDocProcessQueuesReq& req,
DescribeDocProcessQueuesResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::UpdateDocProcessQueue(const UpdateDocProcessQueueReq& req,
UpdateDocProcessQueueResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
DescribeMediaBucketsResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateMediaBucket(const CreateMediaBucketReq& req,
CreateMediaBucketResp* resp) {
std::string host = CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion());
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::DescribeMediaQueues(const DescribeMediaQueuesReq& req,
DescribeQueuesResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::UpdateMediaQueue(const UpdateMediaQueueReq& req,
UpdateQueueResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeFileBuckets(const DescribeFileBucketsReq& req,
DescribeFileBucketsResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateFileBucket(const CreateFileBucketReq& req,
CreateFileBucketResp* resp) {
std::string host = CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion());
std::string path = req.GetPath();
return NormalAction(host, path, req, "", false, resp);
}
CosResult BucketOp::BatchImageAuditing(const BatchImageAuditingReq& req,
BatchImageAuditingResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateDataProcessJobs(const CreateDataProcessJobsReq& req,
CreateDataProcessJobsResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CancelDataProcessJob(const CancelDataProcessJobReq& req,
CancelDataProcessJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeDataProcessJob(const DescribeDataProcessJobReq& req,
DescribeDataProcessJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeImageAuditingJob(const DescribeImageAuditingJobReq& req,
DescribeImageAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateVideoAuditingJob(const CreateVideoAuditingJobReq& req,
CreateVideoAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeVideoAuditingJob(const DescribeVideoAuditingJobReq& req,
DescribeVideoAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateAudioAuditingJob(const CreateAudioAuditingJobReq& req,
CreateAudioAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeAudioAuditingJob(const DescribeAudioAuditingJobReq& req,
DescribeAudioAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateTextAuditingJob(const CreateTextAuditingJobReq& req,
CreateTextAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeTextAuditingJob(const DescribeTextAuditingJobReq& req,
DescribeTextAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateDocumentAuditingJob(const CreateDocumentAuditingJobReq& req,
CreateDocumentAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeDocumentAuditingJob(const DescribeDocumentAuditingJobReq& req,
DescribeDocumentAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::CreateWebPageAuditingJob(const CreateWebPageAuditingJobReq& req,
CreateWebPageAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
CosResult BucketOp::DescribeWebPageAuditingJob(const DescribeWebPageAuditingJobReq& req,
DescribeWebPageAuditingJobResp* resp) {
return ProcessReq(req, resp, true);
}
} // namespace qcloud_cos

85
src/op/cos_result.cpp Normal file
View File

@@ -0,0 +1,85 @@
// Copyright (c) 2017, Tencent Inc.
// All rights reserved.
//
// Author: sevenyou <sevenyou@tencent.com>
// Created: 07/26/17
// Description:
#include "op/cos_result.h"
#include <stdio.h>
#include <string.h>
#include "cos_params.h"
#include "cos_sys_config.h"
#include "rapidxml/1.13/rapidxml.hpp"
#include "rapidxml/1.13/rapidxml_print.hpp"
#include "rapidxml/1.13/rapidxml_utils.hpp"
#include "util/string_util.h"
namespace qcloud_cos {
bool CosResult::ParseFromHttpResponse(
const std::map<std::string, std::string>& headers,
const std::string& body) {
std::map<std::string, std::string>::const_iterator c_itr;
c_itr = headers.find("x-cos-request-id");
if (c_itr != headers.end()) {
m_x_cos_request_id = c_itr->second;
}
c_itr = headers.find("x-cos-trace-id");
if (c_itr != headers.end()) {
m_x_cos_trace_id = c_itr->second;
}
std::string tmp_body = body;
rapidxml::xml_document<> doc;
if (!StringUtil::StringToXml(&tmp_body[0], &doc)) {
SDK_LOG_ERR("Parse string to xml doc error, xml_body=%s", body.c_str());
return false;
}
rapidxml::xml_node<>* root = doc.first_node(kErrorRoot);
if (NULL == root) {
// SDK_LOG_INFO("Miss root node=Error, xml_body=%s", body.c_str());
// SetErrorMsg(body);
return false;
}
rapidxml::xml_node<>* node = root->first_node();
for (; node != NULL; node = node->next_sibling()) {
const std::string node_name = node->name();
if (node_name == kErrorCode) {
m_err_code = node->value();
} else if (node_name == kErrorMessage) {
m_err_msg = node->value();
} else if (node_name == kErrorResource) {
m_resource_addr = node->value();
} else if (node_name == kErrorRequestId) {
m_x_cos_request_id = node->value();
} else if (node_name == kErrorTraceId) {
m_x_cos_trace_id = node->value();
} else if (node_name == kErrorServerTime) {
m_x_cos_server_time = node->value();
} else {
SDK_LOG_WARN("Unknown field, field_name=%s, xml_body=%s",
node_name.c_str(), body.c_str());
}
}
return true;
}
std::string CosResult::DebugString() const {
std::string ret = "";
ret = "IsSucc=" + std::string(m_is_succ ? "true" : "false") + "\n" +
"HttpStatus=" + StringUtil::IntToString(m_http_status) + "\n" +
"\tErrorCode=" + m_err_code + "\tErrorMsg=" + m_err_msg +
"\tResourceAddr=" + m_resource_addr +
"\tXCosRequestId=" + m_x_cos_request_id +
"\tXCosTraceId=" + m_x_cos_trace_id + "]";
return ret;
}
} // namespace qcloud_cos

118
src/op/file_copy_task.cpp Normal file
View File

@@ -0,0 +1,118 @@
#include "op/file_copy_task.h"
#include "op/object_op.h"
#include "request/object_req.h"
#include "response/object_resp.h"
#include "util/http_sender.h"
#include "util/base_op_util.h"
namespace qcloud_cos {
FileCopyTask::FileCopyTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms)
: m_host(host),
m_path(path),
m_is_https(is_https),
m_op_util(op_util),
m_conn_timeout_in_ms(conn_timeout_in_ms),
m_recv_timeout_in_ms(recv_timeout_in_ms),
m_is_task_success(false),
m_etag(""),
m_verify_cert(true),
m_ssl_ctx_cb(nullptr),
m_user_data(nullptr) {}
bool FileCopyTask::IsTaskSuccess() const { return m_is_task_success; }
std::string FileCopyTask::GetTaskResp() const { return m_resp; }
int FileCopyTask::GetHttpStatus() const { return m_http_status; }
std::map<std::string, std::string> FileCopyTask::GetRespHeaders() const {
return m_resp_headers;
}
void FileCopyTask::SetParams(const std::map<std::string, std::string>& params) {
m_params.clear();
m_params.insert(params.begin(), params.end());
}
void FileCopyTask::SetHeaders(
const std::map<std::string, std::string>& headers) {
m_headers.clear();
m_headers.insert(headers.begin(), headers.end());
}
void FileCopyTask::SetVerifyCert(bool verify_cert) {
m_verify_cert = verify_cert;
}
void FileCopyTask::SetCaLocation(const std::string& ca_location) {
m_ca_location = ca_location;
}
void FileCopyTask::SetSslCtxCb(SSLCtxCallback cb, void *data) {
m_ssl_ctx_cb = cb;
m_user_data = data;
}
void FileCopyTask::run() {
m_is_task_success = false;
CopyTask();
}
void FileCopyTask::CopyTask() {
std::string domain = m_host;
for (int i = 0;; i++) {
SendRequestOnce(domain);
if (i >= m_op_util.GetMaxRetryTimes()) {
break;
}
if (m_is_task_success) {
break;
}
SDK_LOG_ERR("FileCopy: host(%s) path(%s) fail, retry num: %d, httpcode:%d, resp: %s",
domain.c_str(), m_path.c_str(), i, m_http_status, m_resp.c_str());
if (m_http_status >= 400 && m_http_status < 500) {
break;
}
CosResult result;
result.SetHttpStatus(m_http_status);
result.ParseFromHttpResponse(m_resp_headers, m_resp);
if (m_op_util.ShouldChangeBackupDomain(result, i)) {
domain = m_op_util.ChangeHostSuffix(domain);
}
m_op_util.SleepBeforeRetry(i);
}
}
void FileCopyTask::SendRequestOnce(std::string domain) {
m_resp_headers.clear();
m_resp = "";
std::string full_url = m_op_util.GetRealUrl(domain, m_path, m_is_https);
m_http_status = HttpSender::SendRequest(nullptr, "PUT", full_url, m_params, m_headers, "", m_conn_timeout_in_ms,
m_recv_timeout_in_ms, &m_resp_headers, &m_resp, &m_err_msg, false, m_verify_cert, m_ca_location, m_ssl_ctx_cb,
m_user_data);
if (m_http_status != 200) {
m_is_task_success = false;
return;
}
UploadPartCopyDataResp resp;
if (!resp.ParseFromXmlString(m_resp)) {
m_is_task_success = false;
return;
}
m_etag = resp.GetEtag();
m_last_modified = resp.GetLastModified();
m_is_task_success = true;
}
} // namespace qcloud_cos

View File

@@ -0,0 +1,139 @@
#include "op/file_download_task.h"
#include <string.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include "cos_sys_config.h"
#include "util/http_sender.h"
#include "util/base_op_util.h"
namespace qcloud_cos {
FileDownTask::FileDownTask(const std::string& host,
const std::string& path,
const bool is_https,
const BaseOpUtil& op_util,
const std::map<std::string, std::string>& headers,
const std::map<std::string, std::string>& params,
uint64_t conn_timeout_in_ms,
uint64_t recv_timeout_in_ms,
const SharedTransferHandler& handler,
uint64_t offset, unsigned char* pbuf,
const size_t data_len,
bool verify_cert,
const std::string& ca_lication,
SSLCtxCallback ssl_ctx_cb,
void *user_data,
Semaphore* semaphore)
: m_host(host),
m_path(path),
m_is_https(is_https),
m_op_util(op_util),
m_headers(headers),
m_params(params),
m_conn_timeout_in_ms(conn_timeout_in_ms),
m_recv_timeout_in_ms(recv_timeout_in_ms),
m_handler(handler),
m_offset(offset),
m_data_buf_ptr(pbuf),
m_data_len(data_len),
m_semaphore(semaphore),
m_resp(""),
m_is_task_success(false),
m_task_info(),
m_real_down_len(0),
m_verify_cert(verify_cert),
m_ca_location(ca_lication),
m_ssl_ctx_cb(ssl_ctx_cb),
m_user_data(user_data),
m_http_status(0) {}
void FileDownTask::run() {
m_resp = "";
m_is_task_success = false;
m_task_info.status = TaskStatus::TASK_RUNNING;
DownTask();
// 任务完成后标记状态, 最后自动通知信号量,释放资源槽位
m_task_info.status = TaskStatus::TASK_COMPLETED;
if (m_semaphore != nullptr) {
m_semaphore->release();
}
}
void FileDownTask::SetDownParams(unsigned char* pbuf, size_t data_len,
uint64_t offset) {
m_data_buf_ptr = pbuf;
m_data_len = data_len;
m_offset = offset;
}
void FileDownTask::SetVerifyCert(bool verify_cert) {
m_verify_cert = verify_cert;
}
void FileDownTask::SetCaLocation(const std::string& ca_location) {
m_ca_location = ca_location;
}
void FileDownTask::SetSslCtxCb(SSLCtxCallback cb, void *data) {
m_ssl_ctx_cb = cb;
m_user_data = data;
}
void FileDownTask::DownTask() {
char range_head[128];
memset(range_head, 0, sizeof(range_head));
snprintf(range_head, sizeof(range_head), "bytes=%" PRIu64 "-%" PRIu64, m_offset, (m_offset + m_data_len - 1));
// 增加Range头域避免大文件时将整个文件下载
m_headers["Range"] = range_head;
std::string domain = m_host;
for (int i = 0;; i++) {
SendRequestOnce(domain);
if (i >= m_op_util.GetMaxRetryTimes()) {
break;
}
if (m_is_task_success) {
break;
}
SDK_LOG_ERR("FileDownload: host(%s) path(%s) fail, httpcode:%d, resp: %s, try_times: %d", domain.c_str(),
m_path.c_str(), m_http_status, m_resp.c_str(), i);
if (m_http_status >= 400 && m_http_status < 500) {
break;
}
CosResult result;
result.SetHttpStatus(m_http_status);
result.ParseFromHttpResponse(m_resp_headers, m_resp);
if (m_op_util.ShouldChangeBackupDomain(result, i)) {
domain = m_op_util.ChangeHostSuffix(domain);
}
m_op_util.SleepBeforeRetry(i);
}
}
void FileDownTask::SendRequestOnce(std::string domain) {
m_resp_headers.clear();
m_resp = "";
std::string full_url = m_op_util.GetRealUrl(domain, m_path, m_is_https);
m_http_status = HttpSender::SendRequest(m_handler, "GET", full_url, m_params, m_headers, "", m_conn_timeout_in_ms,
m_recv_timeout_in_ms, &m_resp_headers, &m_resp, &m_err_msg, false, m_verify_cert, m_ca_location, m_ssl_ctx_cb,
m_user_data);
// 当实际长度小于请求的数据长度时httpcode为206
if (m_http_status != 200 && m_http_status != 206) {
m_is_task_success = false;
m_real_down_len = 0;
return;
}
size_t buf_max_size = m_data_len;
size_t len = std::min(m_resp.length(), buf_max_size);
memcpy(m_data_buf_ptr, m_resp.c_str(), len);
m_real_down_len = len;
m_is_task_success = true;
m_resp = "";
}
} // namespace qcloud_cos

Some files were not shown because too many files have changed in this diff Show More