diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce03673..8d1e673 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
-## [v5.5.10](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.9...v5.5.10) - 2023-03-06
+## [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
@@ -15,6 +15,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
* 增加允许不签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
@@ -23,6 +25,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
### 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)
@@ -33,6 +37,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- 增加允许不签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)
diff --git a/demo/cos_demo.cpp b/demo/cos_demo.cpp
index 0d30f12..717003f 100644
--- a/demo/cos_demo.cpp
+++ b/demo/cos_demo.cpp
@@ -86,6 +86,8 @@ void DeleteBucket(qcloud_cos::CosAPI& cos, const std::string& bucket_name) {
void PutBucket(qcloud_cos::CosAPI& cos, const std::string& bucket_name) {
qcloud_cos::PutBucketReq req(bucket_name);
+ //创建MAZ存储桶使用下方进行设置
+ //req.SetMAZBucket();
qcloud_cos::PutBucketResp resp;
qcloud_cos::CosResult result = cos.PutBucket(req, &resp);
@@ -327,6 +329,74 @@ void GetBucketACL(qcloud_cos::CosAPI& cos, const std::string& bucket_name) {
<< std::endl;
}
+void GetBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) {
+ qcloud_cos::GetBucketPolicyReq req(bucket_name);
+ qcloud_cos::GetBucketPolicyResp resp;
+ qcloud_cos::CosResult result = cos.GetBucketPolicy(req, &resp);
+
+ std::cout << resp.GetPolicy() << std::endl;
+ std::cout << "===================GetBucketPolicy====================="
+ << std::endl;
+ PrintResult(result, resp);
+ std::cout
+ << "===================================================================="
+ << std::endl;
+}
+
+void PutBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) {
+ qcloud_cos::PutBucketPolicyReq req(bucket_name);
+ qcloud_cos::PutBucketPolicyResp resp;
+ std::string bucket_policy =
+ " {"
+ " \"Statement\": ["
+ " {"
+ " \"Principal\": {"
+ " \"qcs\": ["
+ " \"qcs::cam::uin/100000000001:uin/100000000011\"" //替换成您想授予权限的账户 uin
+ " ]\n"
+ " },\n"
+ " \"Effect\": \"allow\","
+ " \"Action\": ["
+ " \"cos:PutObject\""
+ " ],\n"
+ " \"Resource\": [" //这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
+ " \"qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/exampleobject\""
+ " ],\n"
+ " \"Condition\": {"
+ " \"string_equal\": {"
+ " \"cos:x-cos-mime-limit\": \"image/jpeg\""
+ " }"
+ " }"
+ " }"
+ " ],"
+ " \"Version\": \"2.0\""
+ " }";
+ std::cout << bucket_policy << std::endl;
+ req.SetBody(bucket_policy);
+ qcloud_cos::CosResult result = cos.PutBucketPolicy(req, &resp);
+
+ std::cout << "===================PutBucketPolicy====================="
+ << std::endl;
+ PrintResult(result, resp);
+ std::cout
+ << "===================================================================="
+ << std::endl;
+}
+
+void DeleteBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) {
+ qcloud_cos::DeleteBucketPolicyReq req(bucket_name);
+ qcloud_cos::DeleteBucketPolicyResp resp;
+ qcloud_cos::CosResult result = cos.DeleteBucketPolicy(req, &resp);
+
+ std::cout << "===================DeleteBucketPolicy====================="
+ << std::endl;
+ PrintResult(result, resp);
+ std::cout
+ << "===================================================================="
+ << std::endl;
+}
+
+
void PutBucketCORS(qcloud_cos::CosAPI& cos, const std::string& bucket_name) {
qcloud_cos::PutBucketCORSReq req(bucket_name);
qcloud_cos::CORSRule rule;
diff --git a/demo/test_file/audio.mp3 b/demo/test_file/audio.mp3
new file mode 100644
index 0000000..4b19388
Binary files /dev/null and b/demo/test_file/audio.mp3 differ
diff --git a/demo/test_file/document.docx b/demo/test_file/document.docx
new file mode 100644
index 0000000..2c0454c
Binary files /dev/null and b/demo/test_file/document.docx differ
diff --git a/demo/test_file/test.jpg b/demo/test_file/test.jpg
new file mode 100644
index 0000000..7cdea36
Binary files /dev/null and b/demo/test_file/test.jpg differ
diff --git a/demo/test_file/text.txt b/demo/test_file/text.txt
new file mode 100755
index 0000000..8a41cd2
--- /dev/null
+++ b/demo/test_file/text.txt
@@ -0,0 +1 @@
+texttest
\ No newline at end of file
diff --git a/demo/test_file/video.mp4 b/demo/test_file/video.mp4
new file mode 100644
index 0000000..81d11df
Binary files /dev/null and b/demo/test_file/video.mp4 differ
diff --git a/gen_lcov.sh b/gen_lcov.sh
index a610551..a2b1cb7 100755
--- a/gen_lcov.sh
+++ b/gen_lcov.sh
@@ -1,7 +1,7 @@
#!/bin/sh
workspace=`pwd`
-EXTRACT="${workspace}/*/op/* ${workspace}/*/util/* ${workspace}/*/request/* ${workspace}/*/response/* ${workspace}/*/trsf/* ${workspace}/include"
+EXTRACT="${workspace}/*/op/* ${workspace}/*/util/* ${workspace}/*/request/* ${workspace}/*/response/* ${workspace}/*/trsf/* ${workspace}/include/* ${workspace}/src/*"
# clear
rm UTReport -rf
rm UTResport.tar
@@ -39,8 +39,8 @@ lcov --extract sevenyou.info ${EXTRACT} -o sevenyou_filted.info
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 sevenyou_init.info
+# rm sevenyou_init_filted.info
+# rm sevenyou.info
+# rm sevenyou_filted.info
rm UTReport -rf
diff --git a/include/cos_api.h b/include/cos_api.h
index 99f013a..08c10fb 100644
--- a/include/cos_api.h
+++ b/include/cos_api.h
@@ -50,7 +50,7 @@ class CosAPI {
bool IsObjectExist(const std::string& bucket_name,
const std::string& object_name);
- /// \brief 创建一个Bucket
+ /// \brief List Buckets
/// 详见: https://cloud.tencent.com/document/api/436/8291
///
/// \param req GetService请求
@@ -189,6 +189,30 @@ class CosAPI {
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketACL(const PutBucketACLReq& req, PutBucketACLResp* resp);
+ /// \brief 获取Bucket的权限策略
+ ///
+ /// \param req GetBucketPolicy请求
+ /// \param resp GetBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult GetBucketPolicy(const GetBucketPolicyReq& req, GetBucketPolicyResp* resp);
+
+ /// \brief 写入/替换Bucket的权限策略,通过Body传入
+ ///
+ /// \param req PutBucketPolicy请求
+ /// \param resp PutBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult PutBucketPolicy(const PutBucketPolicyReq& req, PutBucketPolicyResp* resp);
+
+ /// \brief 删除Bucket的权限策略
+ ///
+ /// \param req DeleteBucketPolicy请求
+ /// \param resp DeleteBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult DeleteBucketPolicy(const DeleteBucketPolicyReq& req, DeleteBucketPolicyResp* resp);
+
/// \brief 列出Bucket下的CORS
///
/// \param req GetBucketCORS请求
@@ -741,6 +765,12 @@ class CosAPI {
SharedAsyncContext AsyncGetObject(const AsyncGetObjectReq& req);
SharedAsyncContext AsyncGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager);
+ /// \brief 异步多线程下载对象到本地,支持断点续传
+ /// \param req AsyncResumableGetObject
+ /// \return 返回context
+ SharedAsyncContext AsyncResumableGetObject(const AsyncGetObjectReq& req);
+ SharedAsyncContext AsyncResumableGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager);;
+
/// \brief 异步多线程下载对象到本地
/// \param req MultiGetObjectAsync请求
/// \return 返回context
@@ -776,6 +806,10 @@ class CosAPI {
/* 数据处理接口 */
+ /*** 存储桶绑定万象服务 ***/
+ CosResult PutBucketToCI(const PutBucketToCIReq& req,
+ PutBucketToCIResp* resp);
+
/** 基础图片处理 **/
/** 图片持久化处理 **/
@@ -833,6 +867,10 @@ class CosAPI {
CosResult DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
DescribeMediaBucketsResp* resp);
+ /*** 存储桶绑定媒体处理 ***/
+ CosResult CreateMediaBucket(const CreateMediaBucketReq& req,
+ CreateMediaBucketResp* resp);
+
/*** 获取媒体文件某个时间的截图 ***/
// https://cloud.tencent.com/document/product/436/55671
CosResult GetSnapshot(const GetSnapshotReq& req, GetSnapshotResp* resp);
diff --git a/include/cos_sys_config.h b/include/cos_sys_config.h
index d19e26c..1cc3b5f 100644
--- a/include/cos_sys_config.h
+++ b/include/cos_sys_config.h
@@ -118,6 +118,10 @@ class CosSysConfig {
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和端口号
diff --git a/include/op/bucket_op.h b/include/op/bucket_op.h
index af80de1..890390b 100644
--- a/include/op/bucket_op.h
+++ b/include/op/bucket_op.h
@@ -164,6 +164,30 @@ class BucketOp : public BaseOp {
/// \return 本次请求的调用情况(如状态码等)
CosResult PutBucketACL(const PutBucketACLReq& req, PutBucketACLResp* resp);
+ /// \brief 获取Bucket的权限策略
+ ///
+ /// \param req GetBucketPolicy请求
+ /// \param resp GetBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult GetBucketPolicy(const GetBucketPolicyReq& req, GetBucketPolicyResp* resp);
+
+ /// \brief 写入/替换Bucket的权限策略,通过Body传入
+ ///
+ /// \param req PutBucketPolicy请求
+ /// \param resp PutBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult PutBucketPolicy(const PutBucketPolicyReq& req, PutBucketPolicyResp* resp);
+
+ /// \brief 删除Bucket的权限策略
+ ///
+ /// \param req DeleteBucketPolicy请求
+ /// \param resp DeleteBucketPolicy返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult DeleteBucketPolicy(const DeleteBucketPolicyReq& req, DeleteBucketPolicyResp* resp);
+
/// \brief 列出Bucket下的CORS
///
/// \param req GetBucketCORS请求
@@ -379,6 +403,15 @@ class BucketOp : public BaseOp {
const GetBucketIntelligentTieringReq& req,
GetBucketIntelligentTieringResp* resp);
+ /// \brief 存储桶绑定ci
+ ///
+ /// \param req PutBucketToCIReq请求
+ /// \param resp PutBucketToCIResp返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult PutBucketToCI(const PutBucketToCIReq& req,
+ PutBucketToCIResp* resp);
+
/// \brief 提交文档转码任务
/// \brief https://cloud.tencent.com/document/product/436/54056
/// \param req CreateDocProcessJobs请求
@@ -432,6 +465,14 @@ class BucketOp : public BaseOp {
CosResult DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
DescribeMediaBucketsResp* resp);
+ /// \brief 开通媒体处理
+ /// \brief https://cloud.tencent.com/document/product/436/72824
+ /// \param req DescribeMediaBuckets请求
+ /// \param resp DescribeMediaBuckets返回
+ ///
+ /// \return 本次请求的调用情况(如状态码等)
+ CosResult CreateMediaBucket(const CreateMediaBucketReq& req,
+ CreateMediaBucketResp* resp);
/// \brief 获取媒体文件信息
/// \brief https://cloud.tencent.com/document/product/436/55672
/// \param req GetMediainfo请求
diff --git a/include/op/object_op.h b/include/op/object_op.h
index 0bfe267..98ae4b8 100644
--- a/include/op/object_op.h
+++ b/include/op/object_op.h
@@ -324,7 +324,8 @@ class ObjectOp : public BaseOp {
/// \brief 支持断点下载
CosResult ResumableGetObject(const GetObjectByFileReq& req,
- GetObjectByFileResp* resp);
+ GetObjectByFileResp* resp,
+ const SharedTransferHandler& handler = nullptr);
/*批量及目录操作接口*/
CosResult PutObjects(const PutObjectsByDirectoryReq& req,
diff --git a/include/request/bucket_req.h b/include/request/bucket_req.h
index c2b6045..318821f 100644
--- a/include/request/bucket_req.h
+++ b/include/request/bucket_req.h
@@ -74,6 +74,14 @@ class PutBucketReq : public BucketReq {
void SetXCosGrantFullControl(const std::string& str) {
AddHeader("x-cos-grant-full-control", str);
}
+
+ //设置桶为多az存储桶
+ void SetMAZBucket() {
+ std::string maz = "";
+ maz += " MAZ";
+ maz += "";
+ SetBody(maz);
+ }
};
class GetBucketReq : public BucketReq {
@@ -354,6 +362,39 @@ class PutBucketACLReq : public BucketReq {
std::vector m_acl;
};
+class GetBucketPolicyReq : public BucketReq {
+ public:
+ GetBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
+ SetMethod("GET");
+ SetPath("/");
+ AddParam("policy", "");
+ }
+
+ virtual ~GetBucketPolicyReq() {}
+};
+
+class PutBucketPolicyReq : public BucketReq {
+ public:
+ PutBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
+ SetMethod("PUT");
+ SetPath("/");
+ AddParam("policy", "");
+ }
+
+ virtual ~PutBucketPolicyReq() {}
+};
+
+class DeleteBucketPolicyReq : public BucketReq {
+ public:
+ DeleteBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) {
+ SetMethod("DELETE");
+ SetPath("/");
+ AddParam("policy", "");
+ }
+
+ virtual ~DeleteBucketPolicyReq() {}
+};
+
class DeleteBucketACLReq : public BucketReq {
public:
DeleteBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) {
diff --git a/include/request/data_process_req.h b/include/request/data_process_req.h
index fc89eed..dbb1b48 100644
--- a/include/request/data_process_req.h
+++ b/include/request/data_process_req.h
@@ -440,6 +440,17 @@ struct DescribeMediaBucketsResult {
}
};
+struct CreateMediaBucketResult {
+ std::string request_id; // 请求的唯一ID
+ BucketInfo media_bucket; // 媒体Bucket
+ std::string to_string() const {
+ std::stringstream ss;
+ ss << "request_id: " << request_id << std::endl;
+ ss << media_bucket.to_string() << std::endl;
+ ss << std::endl;
+ return ss.str();
+ }
+};
struct VideoInfo {
int index; // 该流的编号
std::string codec_name; // 编解码格式名字
@@ -958,6 +969,26 @@ class GetSnapshotReq : public GetObjectByFileReq {
void SetMode(const std::string& mode) { AddParam("mode", mode); }
};
+class PutBucketToCIReq : public BucketReq{
+ public:
+ PutBucketToCIReq(const std::string& bucket_name) : BucketReq(bucket_name) {
+ m_method = "PUT";
+ }
+
+ virtual ~PutBucketToCIReq() {}
+};
+
+class CreateMediaBucketReq : public BucketReq{
+ public:
+ CreateMediaBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) {
+ m_method = "POST";
+ m_path = "/mediabucket";
+ SetHttps();
+ }
+
+ virtual ~CreateMediaBucketReq() {}
+};
+
class GetMediaInfoReq : public ObjectReq {
public:
GetMediaInfoReq(const std::string& bucket_name,
diff --git a/include/response/bucket_resp.h b/include/response/bucket_resp.h
index c835a51..da54fb7 100644
--- a/include/response/bucket_resp.h
+++ b/include/response/bucket_resp.h
@@ -244,6 +244,25 @@ class PutBucketACLResp : public BaseResp {
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() {}
diff --git a/include/response/data_process_resp.h b/include/response/data_process_resp.h
index 540d9dd..d55fcf9 100644
--- a/include/response/data_process_resp.h
+++ b/include/response/data_process_resp.h
@@ -199,6 +199,24 @@ class DescribeMediaBucketsResp : public BaseResp {
DescribeMediaBucketsResult m_result;
};
+class PutBucketToCIResp : public BaseResp {
+ public:
+ PutBucketToCIResp() {}
+ virtual ~PutBucketToCIResp() {}
+};
+
+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() {}
diff --git a/include/util/test_utils.h b/include/util/test_utils.h
index 9f81291..6f2d7a2 100644
--- a/include/util/test_utils.h
+++ b/include/util/test_utils.h
@@ -16,6 +16,9 @@ class TestUtils {
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);
+ static bool IsDirectoryExists(const std::string& path);
+ static bool MakeDirectory(const std::string& path);
+ static bool RemoveDirectory(const std::string& path);
};
#define GetEnvVar TestUtils::GetEnvVar
diff --git a/src/cos_api.cpp b/src/cos_api.cpp
index a36bd74..96c51d6 100644
--- a/src/cos_api.cpp
+++ b/src/cos_api.cpp
@@ -173,6 +173,21 @@ CosResult CosAPI::PutBucketACL(const PutBucketACLReq& req,
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);
@@ -602,6 +617,31 @@ SharedAsyncContext CosAPI::AsyncGetObject(const AsyncGetObjectReq& req, Poco::Ta
return context;
}
+SharedAsyncContext CosAPI::AsyncResumableGetObject(const AsyncGetObjectReq& req) {
+ SharedTransferHandler handler(new TransferHandler());
+ handler->SetRequest(reinterpret_cast(&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(&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(&req));
@@ -671,6 +711,10 @@ CosResult CosAPI::DeleteObjects(const DeleteObjectsByPrefixReq& req,
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) {
@@ -728,6 +772,11 @@ CosResult CosAPI::DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
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(req),
diff --git a/src/cos_sys_config.cpp b/src/cos_sys_config.cpp
index 0729a94..e959ad9 100644
--- a/src/cos_sys_config.cpp
+++ b/src/cos_sys_config.cpp
@@ -251,6 +251,16 @@ std::string CosSysConfig::GetCIHost(const std::string& bucket_name,
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 lock(m_dest_domain_lock);
return m_dest_domain;
diff --git a/src/op/bucket_op.cpp b/src/op/bucket_op.cpp
index 47cfa39..2ed9e3c 100644
--- a/src/op/bucket_op.cpp
+++ b/src/op/bucket_op.cpp
@@ -45,7 +45,8 @@ CosResult BucketOp::PutBucket(const PutBucketReq& req, PutBucketResp* resp) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
req.GetBucketName());
std::string path = req.GetPath();
- return NormalAction(host, path, req, "", false, resp);
+ std::string req_body = req.GetBody();
+ return NormalAction(host, path, req, req_body, false, resp);
}
CosResult BucketOp::GetBucket(const GetBucketReq& req, GetBucketResp* resp) {
@@ -214,6 +215,38 @@ CosResult BucketOp::PutBucketACL(const PutBucketACLReq& req,
req_body, false, resp);
}
+CosResult BucketOp::PutBucketPolicy(const PutBucketPolicyReq& req,
+ PutBucketPolicyResp* resp) {
+ std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
+ req.GetBucketName());
+ std::string path = req.GetPath();
+
+ std::string req_body = req.GetBody();
+ std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body));
+
+ std::map additional_headers;
+ std::map 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) {
+ std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
+ req.GetBucketName());
+ std::string path = req.GetPath();
+ return NormalAction(host, path, req, "", false, resp);
+}
+
+CosResult BucketOp::DeleteBucketPolicy(const DeleteBucketPolicyReq& req,
+ DeleteBucketPolicyResp* resp) {
+ std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
+ req.GetBucketName());
+ std::string path = req.GetPath();
+ return NormalAction(host, path, req, "", false, resp);
+}
+
CosResult BucketOp::GetBucketCORS(const GetBucketCORSReq& req,
GetBucketCORSResp* resp) {
std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(),
@@ -521,6 +554,14 @@ CosResult BucketOp::GetBucketIntelligentTiering(
return NormalAction(host, path, req, "", false, resp);
}
+CosResult BucketOp::PutBucketToCI(const PutBucketToCIReq& req,
+ PutBucketToCIResp* resp) {
+ std::string host = CosSysConfig::GetPICHost(GetAppId(), m_config->GetRegion(),
+ req.GetBucketName());
+ 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 =
@@ -579,6 +620,13 @@ CosResult BucketOp::DescribeMediaBuckets(const DescribeMediaBucketsReq& req,
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::BatchImageAuditing(const BatchImageAuditingReq& req,
BatchImageAuditingResp* resp) {
return ProcessReq(req, resp, true);
diff --git a/src/op/object_op.cpp b/src/op/object_op.cpp
index 15c6a32..067b939 100644
--- a/src/op/object_op.cpp
+++ b/src/op/object_op.cpp
@@ -1861,16 +1861,24 @@ ObjectOp::PostLiveChannelVodPlaylist(const PostLiveChannelVodPlaylistReq& req,
}
CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
- GetObjectByFileResp* resp) {
+ GetObjectByFileResp* resp,
+ const SharedTransferHandler& handler) {
CosResult result;
-
+ if (!handler && !resp) {
+ SetResultAndLogError(result, "invalid input parameter");
+ return result;
+ }
CosResult head_result;
// 1. 调用HeadObject获取文件长度
HeadObjectReq head_req(req.GetBucketName(), req.GetObjectName());
HeadObjectResp head_resp;
head_result = HeadObject(head_req, &head_resp);
if (!head_result.IsSucc()) {
- SDK_LOG_ERR("failed to get object length before downloading object.");
+ SetResultAndLogError(
+ head_result, "failed to get object length before downloading object.");
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED, head_result);
+ }
return head_result;
}
@@ -1934,6 +1942,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
if (auth_str.empty()) {
result.SetErrorMsg(
"Generate auth str fail, check your access_key/secret_key.");
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED);
+ }
return result;
}
headers["Authorization"] = auth_str;
@@ -1974,12 +1985,19 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
") fail, errno=" + StringUtil::IntToString(errno);
SDK_LOG_ERR("%s", err_msg.c_str());
result.SetErrorMsg(err_msg);
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED);
+ }
return result;
}
// 4. 多线程下载
std::string object_etag = head_resp.GetEtag();
uint64_t file_size = head_resp.GetContentLength();
+ if (handler) {
+ handler->SetTotalSize(file_size);
+ handler->UpdateStatus(TransferStatus::IN_PROGRESS);
+ }
unsigned pool_size = CosSysConfig::GetUploadThreadPoolSize();
unsigned slice_size = CosSysConfig::GetDownSliceSize();
@@ -1998,7 +2016,7 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
for (unsigned i = 0; i < pool_size; ++i) {
pptaskArr[i] =
new FileDownTask(dest_url, headers, params, req.GetConnTimeoutInms(),
- req.GetRecvTimeoutInms());
+ req.GetRecvTimeoutInms(), handler);
}
SDK_LOG_INFO(
@@ -2018,6 +2036,11 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
uint64_t resume_update_offset = 0; // 更新offset
while (offset < file_size) {
+ if (handler && !handler->ShouldContinue()) {
+ task_fail_flag = true;
+ SetResultAndLogError(result, "Request canceled by user");
+ break;
+ }
SDK_LOG_DBG("down data, offset=%" PRIu64 ", file_size=%" PRIu64, offset,
file_size);
unsigned task_index = 0;
@@ -2117,6 +2140,10 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
// 下载成功则用head得到的content_length和etag设置get response
resp->SetContentLength(file_size);
resp->SetEtag(object_etag);
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::COMPLETED, result,
+ resp->GetHeaders());
+ }
// 下载成功,删除任务文件
::remove(resumable_task_json_file.c_str());
} else {
@@ -2137,6 +2164,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
SDK_LOG_ERR("we may encounter network error");
// 可能网络传输错误,需要用户重试
result.SetFail();
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED, result);
+ }
}
}
} else {
@@ -2156,6 +2186,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
UpdateResumableDownloadTaskFile(resumable_task_json_file,
resume_task_check_element,
resume_update_offset);
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED, result);
+ }
}
// 4. 释放所有资源
@@ -2174,7 +2207,18 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req,
if (need_to_redownload) {
// 本地文件不是最新的,需要重新下载
SDK_LOG_INFO("non-resumable download object");
- return MultiThreadDownload(req, resp);
+ result = MultiThreadDownload(req, resp);
+ if (handler) {
+ if (result.IsSucc()){
+ handler->UpdateStatus(TransferStatus::COMPLETED, result,
+ resp->GetHeaders());
+ } else {
+ if (handler) {
+ handler->UpdateStatus(TransferStatus::FAILED, result);
+ }
+ }
+ }
+ return result;
}
return result;
diff --git a/src/response/data_process_resp.cpp b/src/response/data_process_resp.cpp
index 79c953c..dd4af3a 100644
--- a/src/response/data_process_resp.cpp
+++ b/src/response/data_process_resp.cpp
@@ -671,6 +671,38 @@ bool DescribeMediaBucketsResp::ParseFromXmlString(const std::string& body) {
}
return true;
}
+bool CreateMediaBucketResp::ParseFromXmlString(const std::string& body) {
+ 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("Response");
+ if (NULL == root) {
+ SDK_LOG_ERR("Missing root node Response, xml_body=%s", body.c_str());
+ return false;
+ }
+
+ rapidxml::xml_node<>* node = root->first_node();
+ for (; node != NULL; node = node->next_sibling()) {
+ const std::string& node_name = node->name();
+ if ("RequestId" == node_name) {
+ m_result.request_id = node->value();
+ } else if ("MediaBucket" == node_name) {
+ BucketInfo bucket_info;
+ DescribeDocProcessBucketsResp::ParseBucketInfo(node, bucket_info);
+ m_result.media_bucket = bucket_info;
+ } else {
+ SDK_LOG_WARN("Unknown field in Response, field_name=%s",
+ node_name.c_str());
+ return false;
+ }
+ }
+ return true;
+}
bool GetMediaInfoResp::ParseVideo(rapidxml::xml_node<>* root,
VideoInfo& video_info) {
diff --git a/src/util/auth_tool.cpp b/src/util/auth_tool.cpp
index 9e00118..f35fbd2 100644
--- a/src/util/auth_tool.cpp
+++ b/src/util/auth_tool.cpp
@@ -42,14 +42,8 @@ void AuthTool::FilterAndSetSignHeader(
"if-unmodified-since",
"origin",
"range",
- "response-cache-control",
- "response-content-disposition",
- "response-content-encoding",
- "response-content-language",
- "response-content-type",
- "response-expires",
- "transfer-encoding",
- "versionid"};
+ "transfer-encoding"
+ };
for (std::map::const_iterator itr = headers.begin();
itr != headers.end(); ++itr) {
if (! not_sign_headers.count(itr->first) && (sign_headers.count(StringUtil::StringToLower(itr->first)) > 0 ||
diff --git a/src/util/test_utils.cpp b/src/util/test_utils.cpp
index 6578398..99e08ef 100644
--- a/src/util/test_utils.cpp
+++ b/src/util/test_utils.cpp
@@ -5,6 +5,9 @@
#include
#include
+#include
+#include
+#include
#include "Poco/DigestStream.h"
#include "Poco/MD5Engine.h"
@@ -77,4 +80,26 @@ std::string TestUtils::GetEnvVar(const std::string& env_var_name) {
return std::string(tmp);
}
+bool TestUtils::IsDirectoryExists(const std::string& path) {
+ struct stat info;
+ if (0 == stat(path.c_str(), &info) && info.st_mode & S_IFDIR) {
+ return true;
+ } else {
+ return false;
+ }
+}
+bool TestUtils::MakeDirectory(const std::string& path) {
+ if (0 == mkdir(path.c_str(), 0775)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+bool TestUtils::RemoveDirectory(const std::string& path) {
+ if (0 == rmdir(path.c_str())) {
+ return true;
+ }else {
+ return false;
+ }
+}
} // namespace qcloud_cos
diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt
index 531b471..9a30754 100644
--- a/unittest/CMakeLists.txt
+++ b/unittest/CMakeLists.txt
@@ -2,7 +2,8 @@ project(cos-cpp-sdk-ut)
file(GLOB common_src src/test_utils.cpp)
file(GLOB object_request_test_src src/object_request_test.cpp)
-file(GLOB object_response_test_src src/object_request_test.cpp)
+file(GLOB object_response_test_src src/object_response_test.cpp)
+file(GLOB bucket_response_test_src src/bucket_response_test.cpp)
file(GLOB util_test_src src/util_test.cpp)
file(GLOB object_op_test_src src/object_op_test.cpp)
file(GLOB bucket_op_test_src src/bucket_op_test.cpp)
@@ -18,6 +19,9 @@ target_link_libraries(object-request-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${G
add_executable(object-response-test ${object_response_test_src} ${common_src})
target_link_libraries(object-response-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS})
+add_executable(bucket-response-test ${bucket_response_test_src} ${common_src})
+target_link_libraries(bucket-response-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS})
+
add_executable(util-test ${util_test_src} ${common_src})
target_link_libraries(util-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS})
@@ -39,6 +43,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
add_executable(all-test
${object_request_test_src}
${object_response_test_src}
+ ${bucket_response_test_src}
${util_test_src}
${object_op_test_src}
${bucket_op_test_src}
diff --git a/unittest/src/async_op_test.cpp b/unittest/src/async_op_test.cpp
index 499c99f..f952f1c 100644
--- a/unittest/src/async_op_test.cpp
+++ b/unittest/src/async_op_test.cpp
@@ -516,6 +516,215 @@ TEST_F(AsyncOpTest, AsyncOpWithWithDoneCallback) {
}
}
+TEST_F(AsyncOpTest, AsyncPutByStreamWithDoneCallback) {
+ {
+ size_t file_size = ((rand() % 100) + 1) * 1024;
+ std::string object_name = "test_async_by_stream_" + std::to_string(file_size);
+ std::istringstream iss(TestUtils::GetRandomString(file_size));
+ // 完成回调
+ auto multi_put_done_cb = [](const SharedAsyncContext& context,
+ void* user_data) {
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(resp)
+ };
+
+ // 开始上传
+ SharedAsyncContext context;
+ std::cout << "async upload object: " << object_name << std::endl;
+
+ // 异步上传
+ qcloud_cos::AsyncPutObjectByStreamReq put_req(m_bucket_name, object_name,
+ iss);
+ // 设置上传完成回调
+ put_req.SetDoneCallback(multi_put_done_cb);
+ // 设置私有数据
+ put_req.SetUserData(&put_req);
+ context = m_client->AsyncPutObject(put_req);
+ // 等待上传结束
+ context->WaitUntilFinish();
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp put_resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(put_resp)
+
+ // 删除对象
+ CosResult del_result;
+ qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name);
+ qcloud_cos::DeleteObjectResp del_resp;
+ del_result = m_client->DeleteObject(del_req, &del_resp);
+ CHECK_COMMON_RESULT(del_result)
+ CHECK_COMMON_RESP(del_resp)
+ CHECK_DEL_RESP(del_resp)
+ }
+}
+
+TEST_F(AsyncOpTest, AsyncPutByStreamWithDoneCallbackWithOutputTaskManager) {
+ {
+ size_t file_size = ((rand() % 100) + 1) * 1024;
+ std::string object_name = "test_async_by_stream_" + std::to_string(file_size);
+ std::istringstream iss(TestUtils::GetRandomString(file_size));
+ // 完成回调
+ auto multi_put_done_cb = [](const SharedAsyncContext& context,
+ void* user_data) {
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(resp)
+ };
+
+ // 开始上传
+ SharedAsyncContext context;
+ Poco::TaskManager* taskManager;
+ std::cout << "async upload object: " << object_name << std::endl;
+
+ // 异步上传
+ qcloud_cos::AsyncPutObjectByStreamReq put_req(m_bucket_name, object_name,
+ iss);
+ // 设置上传完成回调
+ put_req.SetDoneCallback(multi_put_done_cb);
+ // 设置私有数据
+ put_req.SetUserData(&put_req);
+ context = m_client->AsyncPutObject(put_req, taskManager);
+ // 等待上传结束
+ context->WaitUntilFinish();
+ taskManager->joinAll();
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp put_resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(put_resp)
+
+ // 删除对象
+ CosResult del_result;
+ qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name);
+ qcloud_cos::DeleteObjectResp del_resp;
+ del_result = m_client->DeleteObject(del_req, &del_resp);
+ CHECK_COMMON_RESULT(del_result)
+ CHECK_COMMON_RESP(del_resp)
+ CHECK_DEL_RESP(del_resp)
+ }
+}
+
+
+
+TEST_F(AsyncOpTest, AsyncOpWithWithDoneCallbackWithOutputTaskManager) {
+ std::vector base_file_size_v = {
+ 1, 5, 35, 356, 1024, 2545, 25678, 1024 * 1024, 5 * 1024 * 1024};
+ std::vector op_type_v = {ASYNC_OP, MULTI_ASYNC_OP};
+ for (auto& size : base_file_size_v) {
+ for (auto& op_type : op_type_v) {
+ std::cout << "base_size: " << size << ", op_type: " << op_type
+ << std::endl;
+ size_t file_size = ((rand() % 100) + 1) * size;
+ GENERATE_LOCAL_FILE(file_size)
+
+ FileInfo file_info = {
+ object_name, local_file, local_file + "_download",
+ file_size, file_crc64_origin, file_md5_origin,
+ op_type};
+
+ // 完成回调
+ auto multi_put_done_cb = [](const SharedAsyncContext& context,
+ void* user_data) {
+ CHECK_COMMON_RESULT(context->GetResult())
+ FileInfo* file_info = reinterpret_cast(user_data);
+ std::string file_md5_origin = file_info->m_file_md5_origin;
+ uint64_t file_crc64_origin = file_info->m_file_crc64_origin;
+ AsyncResp resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(resp)
+ CHECK_PUT_RESP(resp, file_info->m_op_type)
+ };
+
+ // 开始上传
+ SharedAsyncContext context;
+ Poco::TaskManager* taskManager;
+ if (op_type == ASYNC_OP) {
+ std::cout << "async upload object: " << object_name << std::endl;
+ // 异步上传
+ qcloud_cos::AsyncPutObjectReq put_req(m_bucket_name, object_name,
+ local_file);
+ // 设置上传完成回调
+ put_req.SetDoneCallback(multi_put_done_cb);
+ // 设置私有数据
+ put_req.SetUserData(reinterpret_cast(&file_info));
+
+ context = m_client->AsyncPutObject(put_req, taskManager);
+ } else {
+ std::cout << "multi async upload object: " << object_name << std::endl;
+ // 异步上传
+ qcloud_cos::AsyncMultiPutObjectReq put_req(m_bucket_name, object_name,
+ local_file);
+ // 设置上传完成回调
+ put_req.SetDoneCallback(multi_put_done_cb);
+ // 设置私有数据
+ put_req.SetUserData(reinterpret_cast(&file_info));
+ context = m_client->AsyncMultiPutObject(put_req, taskManager);
+ }
+
+ // 等待上传结束
+ context->WaitUntilFinish();
+ taskManager->joinAll();
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp put_resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(put_resp)
+ CHECK_PUT_RESP(put_resp, op_type)
+
+ // 下载
+ auto multi_get_done_cb = [](const SharedAsyncContext& context,
+ void* user_data) {
+ CHECK_COMMON_RESULT(context->GetResult())
+ FileInfo* file_info = (reinterpret_cast(user_data));
+ std::string file_md5_origin = file_info->m_file_md5_origin;
+ std::string local_file_download = file_info->m_local_file_download;
+ uint64_t file_crc64_origin = file_info->m_file_crc64_origin;
+ uint64_t file_size = file_info->m_file_size;
+ AsyncResp resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(resp)
+ CHECK_GET_RESP(resp, file_info->m_op_type)
+ };
+ std::string local_file_download = local_file + "_download";
+ if (op_type == ASYNC_OP) {
+ std::cout << "async download object: " << object_name << std::endl;
+ qcloud_cos::AsyncGetObjectReq get_req(m_bucket_name, object_name,
+ local_file_download);
+ // 设置完成回调
+ get_req.SetDoneCallback(multi_get_done_cb);
+ // 设置私有数据
+ get_req.SetUserData(reinterpret_cast(&file_info));
+ context = m_client->AsyncGetObject(get_req, taskManager);
+ } else {
+ std::cout << "multi async download object: " << object_name
+ << std::endl;
+ qcloud_cos::AsyncMultiGetObjectReq get_req(m_bucket_name, object_name,
+ local_file_download);
+ // 设置完成回调
+ get_req.SetDoneCallback(multi_get_done_cb);
+ // 设置私有数据
+ get_req.SetUserData(reinterpret_cast(&file_info));
+ context = m_client->AsyncMultiGetObject(get_req, taskManager);
+ }
+
+ // 等待下载结束
+ context->WaitUntilFinish();
+ taskManager->joinAll();
+ CHECK_COMMON_RESULT(context->GetResult())
+ AsyncResp get_resp = context->GetAsyncResp();
+ CHECK_COMMON_RESP(get_resp)
+ CHECK_GET_RESP(get_resp, op_type)
+
+ // 删除对象
+ CosResult del_result;
+ qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name);
+ qcloud_cos::DeleteObjectResp del_resp;
+ del_result = m_client->DeleteObject(del_req, &del_resp);
+ CHECK_COMMON_RESULT(del_result)
+ CHECK_COMMON_RESP(del_resp)
+ CHECK_DEL_RESP(del_resp)
+
+ // 删除本地文件
+ TestUtils::RemoveFile(local_file);
+ TestUtils::RemoveFile(local_file_download);
+ }
+ }
+}
+
#if 0
TEST_F(AsyncOpTest, AsyncOpWithConcurrent) {
const int concurrent_size = 5; // 并发文件个数为5
@@ -722,6 +931,7 @@ TEST_F(AsyncOpTest, AsyncOpWithConcurrent) {
}
#endif
+
TEST_F(AsyncOpTest, AsyncPutWithException) {
// cancel op
std::vector base_file_size_v = {1, 5, 35, 356,
diff --git a/unittest/src/bucket_op_test.cpp b/unittest/src/bucket_op_test.cpp
index 20bb55f..5218b14 100644
--- a/unittest/src/bucket_op_test.cpp
+++ b/unittest/src/bucket_op_test.cpp
@@ -153,6 +153,76 @@ TEST_F(BucketOpTest, PutBucketTest) {
}
}
+TEST_F(BucketOpTest, GetServiceTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ // normal true
+ {
+ GetServiceReq req;
+ GetServiceResp resp;
+ req.AddParam("range","gt");
+ auto ms = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch());
+ req.AddParam("create-time",std::to_string(ms.count()-3600000));
+ CosResult result = m_client2->GetService(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+TEST_F(BucketOpTest, SetCredentailTest) {
+ {
+ qcloud_cos::CosConfig config(00000,"secretId","secretKey",GetEnvVar("CPP_SDK_V5_REGION"));
+ qcloud_cos::CosAPI cos(config);
+ cos.SetCredentail(GetEnvVar("CPP_SDK_V5_ACCESS_KEY"),GetEnvVar("CPP_SDK_V5_SECRET_KEY"),"");
+ EXPECT_EQ(config.GetAccessKey(), "secretId");
+ EXPECT_EQ(config.GetAppId(), 00000);
+ EXPECT_EQ(config.GetSecretKey(), "secretKey");
+ EXPECT_EQ(config.GetRegion(), GetEnvVar("CPP_SDK_V5_REGION"));
+ bool result = cos.IsBucketExist(m_bucket_name2);
+ EXPECT_TRUE(result);
+ }
+}
+
+TEST_F(BucketOpTest, IsBucketExistTest) {
+ // normal true
+ {
+ bool result = m_client2->IsBucketExist(m_bucket_name2);
+ EXPECT_TRUE(result);
+ }
+
+ // wrong false
+ {
+ bool result = m_client2->IsBucketExist(m_bucket_name_nil);
+ EXPECT_TRUE(!result);
+ }
+}
+
+TEST_F(BucketOpTest, DescribeDocProcessTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ {
+ DescribeDocProcessBucketsReq req;
+ DescribeDocProcessBucketsResp resp;
+ CosResult result = m_client->DescribeDocProcessBuckets(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ EXPECT_EQ(resp.GetServer(), "tencent-ci");
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+TEST_F(BucketOpTest, DescribeMediaTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ {
+ DescribeMediaBucketsReq req;
+ DescribeMediaBucketsResp resp;
+ CosResult result = m_client->DescribeMediaBuckets(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ EXPECT_EQ(resp.GetServer(), "tencent-ci");
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
TEST_F(BucketOpTest, HeadBucketTest) {
// normal 200
{
@@ -183,6 +253,87 @@ TEST_F(BucketOpTest, HeadBucketTest) {
}
}
+TEST_F(BucketOpTest, PutBucketDomainTest) {
+ // 400
+ {
+ qcloud_cos::PutBucketDomainReq req(m_bucket_name2);
+ DomainRule rules;
+ rules.SetStatus("ENABLED");
+ rules.SetName("111");
+ rules.SetType("REST");
+ req.SetDomainRule(rules);
+ PutBucketDomainResp resp;
+ CosResult result = m_client2->PutBucketDomain(req, &resp);
+ EXPECT_TRUE(!result.IsSucc());
+ EXPECT_EQ(result.GetHttpStatus(), 400);
+ }
+}
+
+TEST_F(BucketOpTest, GetBucketDomainTest) {
+ // 404
+ {
+ GetBucketDomainReq req(m_bucket_name2);
+ GetBucketDomainResp resp;
+ CosResult result = m_client2->GetBucketDomain(req, &resp);
+ EXPECT_TRUE(!result.IsSucc());
+ EXPECT_EQ(result.GetHttpStatus(), 404);
+ }
+}
+
+
+TEST_F(BucketOpTest, GetBucketLocationTest) {
+ // normal CPP_SDK_V5_REGION
+ {
+ std::string location = m_client2->GetBucketLocation(m_bucket_name2);
+ EXPECT_EQ(location,GetEnvVar("CPP_SDK_V5_REGION"));
+ }
+
+ // wrong ""
+ {
+ std::string location = m_client2->GetBucketLocation(m_bucket_name_wrong);
+ EXPECT_EQ(location,"");
+ }
+}
+
+TEST_F(BucketOpTest, BucketIntelligentTieringTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ std::string ittest_bucket_name = "ittest-" + GetEnvVar("CPP_SDK_V5_APPID");
+ {
+ PutBucketReq req(ittest_bucket_name);
+ PutBucketResp resp;
+ CosResult result = m_client->PutBucket(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ }
+
+ {
+ PutBucketIntelligentTieringReq req(ittest_bucket_name);
+ PutBucketIntelligentTieringResp resp;
+ req.SetStatus(true);
+ req.SetDays(60);
+ CosResult result = m_client->PutBucketIntelligentTiering(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ }
+ {
+ GetBucketIntelligentTieringReq req(ittest_bucket_name);
+ GetBucketIntelligentTieringResp resp;
+ CosResult result = m_client->GetBucketIntelligentTiering(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ EXPECT_EQ(resp.GetStatus(), "Enabled");
+ EXPECT_EQ(resp.GetDays(), 60);
+ }
+
+ {
+ DeleteBucketReq req(ittest_bucket_name);
+ DeleteBucketResp resp;
+ CosResult result = m_client->DeleteBucket(req, &resp);
+ EXPECT_TRUE(result.IsSucc());
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+
+
TEST_F(BucketOpTest, ListMultipartUpload) {
{
std::string object_name = "testlistuploadpartsdiffer";
diff --git a/unittest/src/bucket_response_test.cpp b/unittest/src/bucket_response_test.cpp
new file mode 100644
index 0000000..0d4a800
--- /dev/null
+++ b/unittest/src/bucket_response_test.cpp
@@ -0,0 +1,92 @@
+#include "gtest/gtest.h"
+#include "response/bucket_resp.h"
+#include "response/data_process_resp.h"
+
+namespace qcloud_cos {
+
+TEST(BucketRespTest, BucketDomainTest) {
+ {
+ std::string body;
+ body += "\n";
+ body += " Code\n";
+ body += " Message\n";
+ body += " RequestId\n";
+ body += " TraceId\n";
+ body += "";
+ PutBucketDomainResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetDomainErrorMsg().GetCode(), "Code");
+ ASSERT_EQ(resp.GetDomainErrorMsg().GetMessage(), "Message");
+ ASSERT_EQ(resp.GetDomainErrorMsg().GetRequestid(), "RequestId");
+ ASSERT_EQ(resp.GetDomainErrorMsg().GetTraceid(), "TraceId");
+ }
+ {
+ std::string body;
+ body += "\n";
+ body += " \n";
+ body += " Status\n";
+ body += " Name\n";
+ body += " Type\n";
+ body += " \n";
+ body += "";
+ GetBucketDomainResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetStatus(), "Status");
+ ASSERT_EQ(resp.GetName(), "Name");
+ ASSERT_EQ(resp.GetType(), "Type");
+ }
+ {
+ GetBucketInventoryResp resp;
+ std::string body;
+ body += "\n";
+ body += " \n";
+ body += " \n";
+ body += " CSV\n";
+ body += " 1250000000\n";
+ body += " qcs::cos:ap-guangzhou::examplebucket-1250000000\n";
+ body += " list1\n";
+ body += " \n";
+ body += " \n";
+ body += " \n";
+ body += " \n";
+ body += " \n";
+ body += " \n";
+ body += " Daily\n";
+ body += " \n";
+ body += " \n";
+ body += " myPrefix\n";
+ body += " \n";
+ body += " \n";
+ body += " Size\n";
+ body += " LastModifiedDate\n";
+ body += " ETag\n";
+ body += " StorageClass\n";
+ body += " IsMultipartUploaded\n";
+ body += " ReplicationStatus\n";
+ body += " \n";
+ body += " All\n";
+ body += " Id\n";
+ body += " true\n";
+ body += "";
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetInventory().GetId(), "Id");
+ ASSERT_TRUE(resp.GetInventory().GetIsEnable());
+ ASSERT_EQ(resp.GetInventory().GetIncludedObjectVersions(), "All");
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsETag());
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsSize());
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsLastModified());
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsStorageClass());
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsMultipartUploaded());
+ ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsReplicationStatus());
+ ASSERT_EQ(resp.GetInventory().GetFilter(), "myPrefix");
+ ASSERT_EQ(resp.GetInventory().GetFrequency(), "Daily");
+ ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetAccountId(), "1250000000");
+ ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetBucket(), "qcs::cos:ap-guangzhou::examplebucket-1250000000");
+ ASSERT_TRUE(resp.GetInventory().GetCOSBucketDestination().GetEncryption());
+ ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetFormat(), "CSV");
+ ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetPrefix(), "list1");
+ }
+
+}
+
+} // namespace qcloud_cos
\ No newline at end of file
diff --git a/unittest/src/object_op_test.cpp b/unittest/src/object_op_test.cpp
index 7a85f32..fe6d581 100644
--- a/unittest/src/object_op_test.cpp
+++ b/unittest/src/object_op_test.cpp
@@ -7,6 +7,7 @@
#include
+#include
#include "Poco/MD5Engine.h"
#include "Poco/StreamCopier.h"
#include "cos_api.h"
@@ -421,6 +422,29 @@ TEST_F(ObjectOpTest, HeadObjectTest) {
EXPECT_EQ("AES256", head_resp.GetXCosServerSideEncryption());
}
}
+TEST_F(ObjectOpTest, PutDirectoryTest) {
+ {
+ std::string directory_name = "put_directory_test";
+ PutDirectoryReq req(m_bucket_name, directory_name);
+ PutDirectoryResp resp;
+ CosResult result = m_client->PutDirectory(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ }
+}
+
+TEST_F(ObjectOpTest, MoveObjectTest) {
+ {
+ std::istringstream iss("put_obj_by_stream_normal_string");
+ PutObjectByStreamReq req(m_bucket_name, "move_object_src", iss);
+ PutObjectByStreamResp resp;
+ CosResult result = m_client->PutObject(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+
+ MoveObjectReq mv_req(m_bucket_name, "move_object_src", "move_object_dst");
+ CosResult mv_result = m_client->MoveObject(mv_req);
+ ASSERT_TRUE(mv_result.IsSucc());
+ }
+}
TEST_F(ObjectOpTest, DeleteObjectTest) {
{
@@ -434,6 +458,500 @@ TEST_F(ObjectOpTest, DeleteObjectTest) {
}
}
+
+TEST_F(ObjectOpTest, DeleteObjectsTest) {
+ // 批量上传+批量删除
+ {
+ std::string directory_name = "delete_objects_testfile_directory";
+ if(!TestUtils::IsDirectoryExists(directory_name) && TestUtils::MakeDirectory(directory_name)){
+ std::string object_name1 = "testfile1";
+ std::string object_name2 = "testfile2";
+ std::string object_name3 = "testfile3";
+ std::string object_name4 = "testfile4";
+ std::string local_file1 = "./" + directory_name + "/" + object_name1;
+ std::string local_file2 = "./" + directory_name + "/" + object_name2;
+ std::string local_file3 = "./" + directory_name + "/" + object_name3;
+ std::string local_file4 = "./" + directory_name + "/" + object_name4;
+ TestUtils::WriteRandomDatatoFile(local_file1, 1024);
+ TestUtils::WriteRandomDatatoFile(local_file2, 1024);
+ TestUtils::WriteRandomDatatoFile(local_file3, 1024);
+ TestUtils::WriteRandomDatatoFile(local_file4, 1024);
+
+ PutObjectsByDirectoryReq req(m_bucket_name, directory_name);
+ PutObjectsByDirectoryResp resp;
+ CosResult result = m_client->PutObjects(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ TestUtils::RemoveFile(local_file1);
+ TestUtils::RemoveFile(local_file2);
+ TestUtils::RemoveFile(local_file3);
+ TestUtils::RemoveFile(local_file4);
+ TestUtils::RemoveDirectory(directory_name);
+
+ DeleteObjectsByPrefixReq del_req(m_bucket_name, directory_name);
+ DeleteObjectsByPrefixResp del_resp;
+ CosResult del_result = m_client->DeleteObjects(del_req, &del_resp);
+ ASSERT_TRUE(del_result.IsSucc());
+ }
+ }
+ //批量删除
+ {
+ std::string object_name1 = "testfile1";
+ std::string object_name2 = "testfile2";
+ std::string object_name3 = "testfile3";
+ std::string object_name4 = "testfile4";
+ std::istringstream iss("put_obj_by_stream_normal_string");
+ PutObjectByStreamReq put_req1(m_bucket_name, object_name1, iss);
+ PutObjectByStreamResp put_resp1;
+ CosResult put_result1 = m_client->PutObject(put_req1, &put_resp1);
+ ASSERT_TRUE(put_result1.IsSucc());
+ PutObjectByStreamReq put_req2(m_bucket_name, object_name2, iss);
+ PutObjectByStreamResp put_resp2;
+ CosResult put_result2 = m_client->PutObject(put_req2, &put_resp2);
+ ASSERT_TRUE(put_result2.IsSucc());
+ PutObjectByStreamReq put_req3(m_bucket_name, object_name3, iss);
+ PutObjectByStreamResp put_resp3;
+ CosResult put_result3 = m_client->PutObject(put_req3, &put_resp3);
+ ASSERT_TRUE(put_result3.IsSucc());
+ PutObjectByStreamReq put_req4(m_bucket_name, object_name4, iss);
+ PutObjectByStreamResp put_resp4;
+ CosResult put_result4 = m_client->PutObject(put_req4, &put_resp4);
+ ASSERT_TRUE(put_result4.IsSucc());
+
+ std::vector objects;
+ std::vector to_be_deleted;
+ objects.push_back(object_name1);
+ objects.push_back(object_name2);
+ objects.push_back(object_name3);
+ objects.push_back(object_name4);
+ for (size_t idx = 0; idx < objects.size(); ++idx) {
+ ObjectVersionPair pair;
+ pair.m_object_name = objects[idx];
+ to_be_deleted.push_back(pair);
+ }
+ qcloud_cos::DeleteObjectsReq req(m_bucket_name, to_be_deleted);
+ qcloud_cos::DeleteObjectsResp resp;
+ qcloud_cos::CosResult del_result = m_client->DeleteObjects(req, &resp);
+ ASSERT_TRUE(del_result.IsSucc());
+ }
+}
+
+TEST_F(ObjectOpTest, GetObjectByStreamTest) {
+ {
+ std::istringstream iss("put_obj_by_stream_normal_string");
+ std::string object_name = "get_object_by_stream_test";
+ PutObjectByStreamReq put_req(m_bucket_name, object_name, iss);
+ PutObjectByStreamResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+
+ std::ostringstream os;
+ GetObjectByStreamReq get_req(m_bucket_name, object_name, os);
+ GetObjectByStreamResp get_resp;
+ CosResult get_result = m_client->GetObject(get_req, &get_resp);
+ ASSERT_TRUE(get_result.IsSucc());
+
+ DeleteObjectReq del_req(m_bucket_name, object_name);
+ DeleteObjectResp del_resp;
+ CosResult del_result = m_client->DeleteObject(del_req, &del_resp);
+ ASSERT_TRUE(del_result.IsSucc());
+ }
+
+ // 下载服务端加密的文件
+ {
+ std::istringstream iss("put_obj_by_stream_normal_string");
+ std::string object_name = "get_sse_object_test";
+ PutObjectByStreamReq put_req(m_bucket_name, object_name, iss);
+ put_req.SetXCosServerSideEncryption("AES256");
+ PutObjectByStreamResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+
+ std::ostringstream os;
+ GetObjectByStreamReq get_req(m_bucket_name, object_name, os);
+ GetObjectByStreamResp get_resp;
+ CosResult get_result = m_client->GetObject(get_req, &get_resp);
+ ASSERT_TRUE(get_result.IsSucc());
+ EXPECT_EQ("AES256", get_resp.GetXCosServerSideEncryption());
+
+ DeleteObjectReq del_req(m_bucket_name, object_name);
+ DeleteObjectResp del_resp;
+ CosResult del_result = m_client->DeleteObject(del_req, &del_resp);
+ ASSERT_TRUE(del_result.IsSucc());
+ }
+}
+
+TEST_F(ObjectOpTest, GetObjectUrlTest) {
+ std::string destdomain = m_config->GetDestDomain().empty() ?
+ CosSysConfig::GetDestDomain() : m_config->GetDestDomain();
+ {
+ std::string object_url = m_client->GetObjectUrl("get_object_url_test_bucket_name",
+ "get_object_url_test_object_name",
+ true,
+ "get_object_url_test_region");
+ std::string myUrl = destdomain;
+ if(destdomain.empty()){
+ myUrl = "get_object_url_test_bucket_name.cos.get_object_url_test_region.myqcloud.com/get_object_url_test_object_name";
+ }
+ ASSERT_EQ(object_url, "https://"+myUrl);
+ }
+
+ {
+ std::string object_url = m_client->GetObjectUrl("get_object_url_test_bucket_name",
+ "get_object_url_test_object_name",
+ false,
+ "");
+ std::string myUrl = destdomain;
+ if(destdomain.empty()){
+ myUrl = "get_object_url_test_bucket_name.cos." + GetEnvVar("CPP_SDK_V5_REGION") + ".myqcloud.com/get_object_url_test_object_name";
+ }
+ ASSERT_EQ(object_url, "http://"+myUrl);
+ }
+}
+
+TEST_F(ObjectOpTest, PostObjectRestoreTest) {
+ //上传
+ {
+ std::istringstream iss("put object");
+ PutObjectByStreamReq req(m_bucket_name, "post_object_restore", iss);
+ req.SetXCosStorageClass("ARCHIVE");
+ PutObjectByStreamResp resp;
+ CosResult result = m_client->PutObject(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetXCosStorageClass(), "ARCHIVE");
+ }
+ //post
+ {
+ PostObjectRestoreReq req(m_bucket_name, "post_object_restore");
+ req.SetExiryDays(30);
+ req.SetTier("Standard");
+ PostObjectRestoreResp resp;
+ CosResult result = m_client->PostObjectRestore(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ }
+ //删除
+ {
+ DeleteObjectReq req(m_bucket_name, "post_object_restore");
+ DeleteObjectResp resp;
+ CosResult result = m_client->DeleteObject(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ }
+}
+
+TEST_F(ObjectOpTest, PutBucketToCITest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ {
+ PutBucketToCIReq req(m_bucket_name);
+ PutBucketToCIResp resp;
+ CosResult result = m_client->PutBucketToCI(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+TEST_F(ObjectOpTest, ImageProcessTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ std::string object_name = "test.jpg";
+ //上传处理
+ {
+ PutImageByFileReq req(m_bucket_name, object_name, "../../demo/test_file/test.jpg");
+ PutImageByFileResp resp;
+
+ PicOperation pic_operation;
+ PicRules rule1;
+ std::string newname = "/" + object_name + "_put_qrcode.jpg";
+ rule1.fileid = newname;
+ rule1.rule = "QRcode/cover/1";
+ pic_operation.AddRule(rule1);
+ req.SetPicOperation(pic_operation);
+ CosResult result = m_client->PutImage(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_TRUE(m_client->IsObjectExist(m_bucket_name, newname));
+ }
+ //云上处理
+ {
+ CloudImageProcessReq req(m_bucket_name, object_name);
+ CloudImageProcessResp resp;
+ PicOperation pic_operation;
+ PicRules rule;
+ std::string newname = "/" + object_name + "_cut.jpg";
+ rule.fileid = newname;
+ rule.rule = "imageMogr2/cut/300x300";
+ pic_operation.AddRule(rule);
+ req.SetPicOperation(pic_operation);
+ CosResult result = m_client->CloudImageProcess(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_TRUE(m_client->IsObjectExist(m_bucket_name, newname));
+ }
+ //下载处理
+ {
+ GetQRcodeReq req(m_bucket_name, object_name);
+ GetQRcodeResp resp;
+ CosResult result = m_client->GetQRcode(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetResult().qr_code_info[0].code_url, "testimage");
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+//媒体接口
+TEST_F(ObjectOpTest, MediaTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ std::string object_name = "video.mp4";
+ //上传媒体
+ {
+ PutObjectByFileReq put_req(m_bucket_name, object_name, "../../demo/test_file/video.mp4");
+ put_req.SetRecvTimeoutInms(1000 * 200);
+ PutObjectByFileResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+ }
+ //绑定媒体服务
+ {
+ CreateMediaBucketReq req(m_bucket_name);
+ CreateMediaBucketResp resp;
+ CosResult result = m_client->CreateMediaBucket(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetResult().media_bucket.name, m_bucket_name);
+ ASSERT_EQ(resp.GetResult().media_bucket.region, GetEnvVar("CPP_SDK_V5_REGION"));
+ }
+ //info
+ {
+ GetMediaInfoReq req(m_bucket_name, object_name);
+ GetMediaInfoResp resp;
+ CosResult result = m_client->GetMediaInfo(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetResult().media_info.stream.video.codec_name, "h264");
+ ASSERT_EQ(resp.GetResult().media_info.stream.video.height, 360);
+ ASSERT_EQ(resp.GetResult().media_info.stream.video.width, 640);
+ ASSERT_EQ(resp.GetResult().media_info.stream.audio.codec_name, "aac");
+ ASSERT_EQ(resp.GetResult().media_info.format.num_stream, 4);
+ }
+ //截图
+ {
+ GetSnapshotReq req(m_bucket_name, object_name, "local_file_snapshot.jpg");
+ GetSnapshotResp resp;
+ req.SetTime(10);
+ CosResult result = m_client->GetSnapshot(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetContentType(), "image/jpeg");
+ TestUtils::RemoveFile("local_file_snapshot.jpg");
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
+
+
+//审核接口
+TEST_F(ObjectOpTest, AuditingTest) {
+ bool use_dns_cache = CosSysConfig::GetUseDnsCache();
+ CosSysConfig::SetUseDnsCache(false);
+ //请勿改变审核测试前后的顺序
+ std::string image_object_name = "test.jpg";
+ std::string video_object_name = "video.mp4";
+ //图片同步审核
+ {
+ GetImageAuditingReq req(m_bucket_name);
+ GetImageAuditingResp resp;
+ req.SetObjectKey(image_object_name);
+ req.SetDataId("data_id_example");
+ req.SetDetectType("ads,porn,politics,terrorism");
+ req.SetInterval(1);
+ req.SetMaxFrames(2);
+ CosResult result = m_client->GetImageAuditing(req, &resp);
+ resp.GetJobsDetail().to_string();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetDataId(), "data_id_example");
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ ASSERT_EQ(resp.GetJobsDetail().GetObject(), image_object_name);
+
+ DescribeImageAuditingJobReq describe_req(m_bucket_name);
+ DescribeImageAuditingJobResp describe_resp;
+ describe_req.SetJobId(resp.GetJobsDetail().GetJobId());
+ CosResult describe_result = m_client->DescribeImageAuditingJob(describe_req, &describe_resp);
+ ASSERT_TRUE(describe_result.IsSucc());
+ ASSERT_EQ(describe_resp.GetJobsDetail().GetDataId(), "data_id_example");
+ }
+ //批量图片审核
+ {
+ BatchImageAuditingReq req(m_bucket_name);
+ BatchImageAuditingResp resp;
+ AuditingInput input = AuditingInput();
+ input.SetObject(image_object_name);
+ input.SetDataId("data_id_example2");
+ req.AddInput(input);
+ req.SetDetectType("Ads,Porn,Politics,Terrorism");
+ CosResult result = m_client->BatchImageAuditing(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetails()[0].GetDataId(), "data_id_example2");
+ ASSERT_EQ(resp.GetJobsDetails()[0].GetState(), "Success");
+ ASSERT_EQ(resp.GetJobsDetails()[0].GetObject(), image_object_name);
+ }
+ //提交视频审核任务
+ std::string video_job_id;
+ {
+ CreateVideoAuditingJobReq req(m_bucket_name);
+ CreateVideoAuditingJobResp resp;
+ req.SetObject(video_object_name);
+ req.SetDataId("DataId");
+ SnapShotConf snap_shot = SnapShotConf();
+ snap_shot.SetCount(5);
+ snap_shot.SetMode("Interval");
+ req.SetSnapShot(snap_shot);
+ req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal");
+ req.SetDetectContent(0);
+ CosResult result = m_client->CreateVideoAuditingJob(req, &resp);
+ video_job_id = resp.GetJobsDetail().GetJobId();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted");
+ }
+ //提交音频审核任务
+ std::string audio_object_name = "audio.mp3";
+ std::string audio_job_id;
+ {
+ {
+ PutObjectByFileReq put_req(m_bucket_name, audio_object_name, "../../demo/test_file/audio.mp3");
+ put_req.SetRecvTimeoutInms(1000 * 200);
+ PutObjectByFileResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+ }
+ {
+ CreateAudioAuditingJobReq req(m_bucket_name);
+ CreateAudioAuditingJobResp resp;
+ req.SetObject(audio_object_name);
+ req.SetDataId("DataId");
+ req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal");
+ req.SetCallBackVersion("Simple");
+ CosResult result = m_client->CreateAudioAuditingJob(req, &resp);
+ audio_job_id = resp.GetJobsDetail().GetJobId();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted");
+ }
+
+
+ }
+ //提交文本审核任务
+ std::string text_object_name = "text.txt";
+ std::string text_job_id;
+ {
+ {
+ PutObjectByFileReq put_req(m_bucket_name, text_object_name, "../../demo/test_file/text.txt");
+ put_req.SetRecvTimeoutInms(1000 * 200);
+ PutObjectByFileResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+ }
+ {
+ CreateTextAuditingJobReq req(m_bucket_name);
+ CreateTextAuditingJobResp resp;
+ req.SetObject(text_object_name);
+ req.SetDataId("DataId");
+ req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal");
+ req.SetCallBackVersion("Simple");
+ CosResult result = m_client->CreateTextAuditingJob(req, &resp);
+ text_job_id = resp.GetJobsDetail().GetJobId();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted");
+ }
+ }
+ //提交文档审核任务
+ std::string document_object_name = "document.docx";
+ std::string document_job_id;
+ {
+ {
+ PutObjectByFileReq put_req(m_bucket_name, document_object_name, "../../demo/test_file/document.docx");
+ put_req.SetRecvTimeoutInms(1000 * 200);
+ PutObjectByFileResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+ }
+ {
+ CreateDocumentAuditingJobReq req(m_bucket_name);
+ CreateDocumentAuditingJobResp resp;
+ req.SetObject(document_object_name);
+ req.SetDataId("DataId");
+ req.SetType("docx");
+ req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal");
+ CosResult result = m_client->CreateDocumentAuditingJob(req, &resp);
+ document_job_id = resp.GetJobsDetail().GetJobId();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted");
+ }
+ }
+ //提交网页审核任务
+ std::string url_job_id;
+ {
+ CreateWebPageAuditingJobReq req(m_bucket_name);
+ CreateWebPageAuditingJobResp resp;
+ req.SetUrl("https://www.baidu.com/");
+ req.SetDataId("DataId");
+ req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal");
+ CosResult result = m_client->CreateWebPageAuditingJob(req, &resp);
+ url_job_id = resp.GetJobsDetail().GetJobId();
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted");
+ }
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ //查询视频审核结果
+ {
+ DescribeVideoAuditingJobReq req(m_bucket_name);
+ DescribeVideoAuditingJobResp resp;
+ req.SetJobId(video_job_id);
+ CosResult result = m_client->DescribeVideoAuditingJob(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ resp.GetJobsDetail().to_string();
+ }
+ //查询音频审核结果
+ {
+ DescribeAudioAuditingJobReq req(m_bucket_name);
+ DescribeAudioAuditingJobResp resp;
+ req.SetJobId(audio_job_id);
+ CosResult result = m_client->DescribeAudioAuditingJob(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ }
+ //查询文本审核结果
+ {
+ DescribeTextAuditingJobReq req(m_bucket_name);
+ DescribeTextAuditingJobResp resp;
+ req.SetJobId(text_job_id);
+ CosResult result = m_client->DescribeTextAuditingJob(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ resp.GetJobsDetail().to_string();
+ }
+ //查询文档审核结果
+ {
+ DescribeDocumentAuditingJobReq req(m_bucket_name);
+ DescribeDocumentAuditingJobResp resp;
+ req.SetJobId(document_job_id);
+ CosResult result = m_client->DescribeDocumentAuditingJob(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ resp.GetJobsDetail().GetLabels().to_string();
+ if (resp.GetJobsDetail().GetPageSegment().HasResults()){
+ resp.GetJobsDetail().GetPageSegment().to_string();
+ resp.GetJobsDetail().GetPageSegment().GetResults()[0].to_string();
+ resp.GetJobsDetail().to_string();
+ }
+ }
+ //查询网页审核结果
+ {
+ DescribeWebPageAuditingJobReq req(m_bucket_name);
+ DescribeWebPageAuditingJobResp resp;
+ req.SetJobId(url_job_id);
+ CosResult result = m_client->DescribeWebPageAuditingJob(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success");
+ resp.GetJobsDetail().to_string();
+ }
+ CosSysConfig::SetUseDnsCache(use_dns_cache);
+}
+
TEST_F(ObjectOpTest, GetObjectByFileTest) {
{
std::istringstream iss("put_obj_by_stream_normal_string");
@@ -489,6 +1007,35 @@ TEST_F(ObjectOpTest, GetObjectByFileTest) {
}
}
+TEST_F(ObjectOpTest, ResumableGetObjectTest) {
+ {
+ std::istringstream iss("put_obj_by_stream_normal_string");
+ std::string object_name = "resumable_get_object_test";
+ PutObjectByStreamReq put_req(m_bucket_name, object_name, iss);
+ PutObjectByStreamResp put_resp;
+ CosResult put_result = m_client->PutObject(put_req, &put_resp);
+ ASSERT_TRUE(put_result.IsSucc());
+
+ std::string file_download = "resumable_get_object_test_file_download";
+ GetObjectByFileReq get_req(m_bucket_name, object_name, file_download);
+ GetObjectByFileResp get_resp;
+ CosResult get_result = m_client->ResumableGetObject(get_req, &get_resp);
+
+ ASSERT_TRUE(get_result.IsSucc());
+
+ std::string file_md5_download = TestUtils::CalcFileMd5(file_download);
+ ASSERT_EQ(file_md5_download, get_resp.GetEtag());
+
+ DeleteObjectReq del_req(m_bucket_name, object_name);
+ DeleteObjectResp del_resp;
+ CosResult del_result = m_client->DeleteObject(del_req, &del_resp);
+ ASSERT_TRUE(del_result.IsSucc());
+
+ TestUtils::RemoveFile(file_download);
+ }
+}
+
+
TEST_F(ObjectOpTest, MultiPutObjectTest) {
{
uint64_t part_size = 20 * 1000 * 1000;
@@ -667,6 +1214,86 @@ TEST_F(ObjectOpTest, MultiPutObjectTest_OneStep) {
}
}
+TEST_F(ObjectOpTest, UploadPartCopyDataTest) {
+ //上传一个对象
+ {
+ std::string local_file = "./object_test_upload_part_copy_data_source";
+ TestUtils::WriteRandomDatatoFile(local_file, 100 * 1024 * 1024);
+ PutObjectByFileReq req(m_bucket_name, "object_test_upload_part_copy_data_source", local_file);
+ req.SetXCosStorageClass(kStorageClassStandard);
+ PutObjectByFileResp resp;
+ CosResult result = m_client->PutObject(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ TestUtils::RemoveFile(local_file);
+ }
+ //分块copy
+ {
+ qcloud_cos::HeadObjectReq req(m_bucket_name, "object_test_upload_part_copy_data_source");
+ qcloud_cos::HeadObjectResp resp;
+ uint64_t part_size = 30 * 1024 * 1024;
+ uint64_t copy_size = 100 * 1024 * 1024;
+ uint64_t no_copy_size = copy_size;
+
+ std::string object_name_copy = "object_test_upload_part_copy_data_copy";
+ InitMultiUploadReq init_req(m_bucket_name, object_name_copy);
+ InitMultiUploadResp init_resp;
+ CosResult init_result = m_client->InitMultiUpload(init_req, &init_resp);
+ ASSERT_TRUE(init_result.IsSucc());
+ std::string host = CosSysConfig::GetHost(m_config->GetAppId(), m_config->GetRegion(),
+ m_bucket_name);
+ std::vector etags;
+ std::vector part_numbers;
+ for (uint64_t part_cnt = 0; no_copy_size > 0; ++part_cnt) {
+ UploadPartCopyDataReq req(m_bucket_name, object_name_copy, init_resp.GetUploadId(),
+ part_cnt + 1);
+ req.SetXCosCopySource(host + "/object_test_upload_part_copy_data_source");
+ std::string range = "bytes=" + std::to_string(part_cnt * part_size) + "-";
+ if(no_copy_size > part_size) {
+ range += std::to_string(((part_cnt + 1) * part_size) - 1);
+ }else range += std::to_string(copy_size - 1);
+ req.SetXCosCopySourceRange(range);
+ UploadPartCopyDataResp resp;
+ CosResult result = m_client->UploadPartCopyData(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ if(no_copy_size > part_size) {
+ no_copy_size -= part_size;
+ }else {
+ no_copy_size = 0;
+ }
+ etags.push_back(resp.GetEtag());
+ part_numbers.push_back(part_cnt + 1);
+ }
+ qcloud_cos::CompleteMultiUploadReq com_req(m_bucket_name, object_name_copy, init_resp.GetUploadId());
+ qcloud_cos::CompleteMultiUploadResp com_resp;
+ com_req.SetEtags(etags);
+ com_req.SetPartNumbers(part_numbers);
+ qcloud_cos::CosResult com_result = m_client->CompleteMultiUpload(com_req, &com_resp);
+ ASSERT_TRUE(com_result.IsSucc());
+ }
+}
+TEST_F(ObjectOpTest, CopyTest) {
+ //上传一个对象
+ {
+ std::string local_file = "./object_test_copy_data_source";
+ TestUtils::WriteRandomDatatoFile(local_file, 100 * 1024 * 1024);
+ PutObjectByFileReq req(m_bucket_name, "object_test_copy_data_source", local_file);
+ req.SetXCosStorageClass(kStorageClassStandard);
+ PutObjectByFileResp resp;
+ CosResult result = m_client->PutObject(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ TestUtils::RemoveFile(local_file);
+ }
+ {
+ std::string host = CosSysConfig::GetHost(m_config->GetAppId(), m_config->GetRegion(),
+ m_bucket_name);
+ CopyReq req(m_bucket_name, "object_test_copy_data_copy");
+ CopyResp resp;
+ req.SetXCosCopySource(host + "/object_test_copy_data_source");
+ CosResult result = m_client->Copy(req, &resp);
+ ASSERT_TRUE(result.IsSucc());
+ }
+}
+
TEST_F(ObjectOpTest, AbortMultiUploadTest) {
uint64_t part_size = 20 * 1000 * 1000;
uint64_t max_part_num = 3;
diff --git a/unittest/src/object_response_test.cpp b/unittest/src/object_response_test.cpp
index e2675c4..afecc4b 100644
--- a/unittest/src/object_response_test.cpp
+++ b/unittest/src/object_response_test.cpp
@@ -7,17 +7,522 @@
#include "gtest/gtest.h"
#include "response/object_resp.h"
+#include "response/data_process_resp.h"
+#include "response/auditing_resp.h"
namespace qcloud_cos {
-TEST(ObjectRespTest, NormalTest) {
+TEST(ObjectRespTest, DocTest) {
{
- GetObjectResp resp;
- std::map input_headers;
- input_headers[kReqHeaderContentLen] = "123";
- kReqHeaderContentType kReqHeaderXCosTraceId kReqHeaderXCosReqId
- kReqHeaderServer kReqHeaderDate kReqHeaderConnection kReqHeaderEtag
- resp.ParseFromHeaders(input_headers);
+ DocPreviewResp resp;
+ std::map headers = {
+ {kRespHeaderXTotalPage, "2"},
+ {kRespHeaderXErrNo, "0"},
+ {kRespHeaderXTotalSheet, "1"},
+ {kRespHeaderXSheetName, "test1"}
+ };
+ resp.ParseFromHeaders(headers);
+ ASSERT_EQ(resp.GetTotalPage(), 2);
+ ASSERT_EQ(resp.GetErrNo(), "0");
+ ASSERT_EQ(resp.GetTotalSheet(), 1);
+ ASSERT_EQ(resp.GetSheetName(), "test1");
+ }
+ std::string base_body;
+ {
+ CreateDocProcessJobsResp resp;
+ std::string body;
+ body += "\n";
+ base_body += " \n";
+ base_body += " 0\n";
+ base_body += " 1\n";
+ base_body += " 2\n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " 4\n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " 5\n";
+ base_body += " 6\n";
+ base_body += " 7\n";
+ base_body += " 8\n";
+ base_body += " 16\n";
+ base_body += " 17\n";
+ base_body += " 18\n";
+ base_body += " 19\n";
+ base_body += " 20\n";
+ base_body += " 20\n";
+ base_body += " 21\n";
+ base_body += " 9\n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " 22\n";
+ base_body += " 23\n";
+ base_body += " 24\n";
+ base_body += " 32\n";
+ base_body += " 25\n";
+ base_body += " \n";
+ base_body += " 26\n";
+ base_body += " 27\n";
+ base_body += " 28\n";
+ base_body += " 29\n";
+ base_body += " 30\n";
+ base_body += " 31\n";
+ base_body += " \n";
+ base_body += " \n";
+ base_body += " 13\n";
+ base_body += " 14\n";
+ base_body += " 15\n";
+ base_body += " \n";
+ body += base_body + "";
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetJobsDetail().code, "0");
+ ASSERT_EQ(resp.GetJobsDetail().create_time, "1");
+ ASSERT_EQ(resp.GetJobsDetail().end_time, "2");
+ ASSERT_EQ(resp.GetJobsDetail().input.object, "3");
+ resp.GetJobsDetail().input.to_string();
+ ASSERT_EQ(resp.GetJobsDetail().job_id, "4");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.src_type, "5");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.tgt_type, "6");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.sheet_id, 16);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.start_page, 7);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.end_page, 8);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.image_params, "9");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.doc_passwd, "17");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.comments, 18);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.paper_direction, 19);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.quality, 20);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.zoom, 21);
+ resp.GetJobsDetail().operation.doc_process.to_string();
+ ASSERT_EQ(resp.GetJobsDetail().operation.output.bucket, "10");
+ ASSERT_EQ(resp.GetJobsDetail().operation.output.object, "11");
+ ASSERT_EQ(resp.GetJobsDetail().operation.output.region, "12");
+ resp.GetJobsDetail().operation.output.to_string();
+ ASSERT_EQ(resp.GetJobsDetail().queue_id, "13");
+ ASSERT_EQ(resp.GetJobsDetail().state, "14");
+ ASSERT_EQ(resp.GetJobsDetail().tag, "15");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].page_no, 22);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].tgt_uri, "23");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].x_sheet_pics, 24);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].pic_index, 32);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].pic_num, 25);
+ resp.GetJobsDetail().operation.doc_process_result.page_infos[0].to_string();
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.tgt_type, "26");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.task_id, "31");
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.total_pageount, 27);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.succ_pagecount, 28);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.fail_pagecount, 29);
+ ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.total_sheetcount, 30);
+ resp.GetJobsDetail().operation.doc_process_result.to_string();
+ resp.GetJobsDetail().operation.to_string();
+ resp.GetJobsDetail().to_string();
+ }
+ {
+ DescribeDocProcessJobsResp resp;
+ std::string body;
+ body += "\n";
+ body += base_body;
+ body += " 32\n";
+ body += "";
+ // std::cout << body << std::endl;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetNextToken(), "32");
+ }
+ {
+ std::string body = "\n";
+ body += " 1\n";
+ body += " RequestId\n";
+ body += " 1\n";
+ body += " 2\n";
+ body += " \n";
+ body += " QueueId\n";
+ body += " QueueName\n";
+ body += " Active\n";
+ body += " \n";
+ body += " url\n";
+ body += " Event\n";
+ body += " Type\n";
+ body += " Off\n";
+ body += " \n";
+ body += " 10000\n";
+ body += " 10\n";
+ body += " CreateTime\n";
+ body += " UpdateTime\n";
+ body += " BucketId\n";
+ body += " DocProcess\n";
+ body += " \n";
+ body += " \n";
+ body += " 3\n";
+ body += " \n";
+ body += "";
+ DescribeDocProcessQueuesResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetTotalCount(), 1);
+ ASSERT_EQ(resp.GetRequestId(), "RequestId");
+ ASSERT_EQ(resp.GetPageNumber(), 1);
+ ASSERT_EQ(resp.GetPageSize(), 2);
+ ASSERT_EQ(resp.GetQueueList().queue_id, "QueueId");
+ ASSERT_EQ(resp.GetQueueList().name, "QueueName");
+ ASSERT_EQ(resp.GetQueueList().state, "Active");
+ ASSERT_EQ(resp.GetQueueList().notify_config.url, "url");
+ ASSERT_EQ(resp.GetQueueList().notify_config.event, "Event");
+ ASSERT_EQ(resp.GetQueueList().notify_config.type, "Type");
+ ASSERT_EQ(resp.GetQueueList().notify_config.state, "Off");
+ ASSERT_EQ(resp.GetQueueList().max_size, 10000);
+ ASSERT_EQ(resp.GetQueueList().max_concurrent, 10);
+ ASSERT_EQ(resp.GetQueueList().create_time, "CreateTime");
+ ASSERT_EQ(resp.GetQueueList().update_time, "UpdateTime");
+ ASSERT_EQ(resp.GetQueueList().bucket_id, "BucketId");
+ ASSERT_EQ(resp.GetQueueList().category, "DocProcess");
+ resp.GetQueueList().to_string();
+ ASSERT_EQ(resp.GetNonExistPIDs().queue_id[0], "3");
+ }
+ {
+ std::string body = "\n";
+ body += " RequestId\n";
+ body += " \n";
+ body += " QueueId\n";
+ body += " QueueName\n";
+ body += " Active\n";
+ body += " \n";
+ body += " url\n";
+ body += " Event\n";
+ body += " Type\n";
+ body += " Off\n";
+ body += " \n";
+ body += " 10000\n";
+ body += " 10\n";
+ body += " CreateTime\n";
+ body += " UpdateTime\n";
+ body += " BucketId\n";
+ body += " DocProcess\n";
+ body += " \n";
+ body += "";
+ UpdateDocProcessQueueResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetRequestId(), "RequestId");
+ ASSERT_EQ(resp.GetQueueList().queue_id, "QueueId");
+ ASSERT_EQ(resp.GetQueueList().name, "QueueName");
+ ASSERT_EQ(resp.GetQueueList().state, "Active");
+ ASSERT_EQ(resp.GetQueueList().notify_config.url, "url");
+ ASSERT_EQ(resp.GetQueueList().notify_config.event, "Event");
+ ASSERT_EQ(resp.GetQueueList().notify_config.type, "Type");
+ ASSERT_EQ(resp.GetQueueList().notify_config.state, "Off");
+ ASSERT_EQ(resp.GetQueueList().max_size, 10000);
+ ASSERT_EQ(resp.GetQueueList().max_concurrent, 10);
+ ASSERT_EQ(resp.GetQueueList().create_time, "CreateTime");
+ ASSERT_EQ(resp.GetQueueList().update_time, "UpdateTime");
+ ASSERT_EQ(resp.GetQueueList().bucket_id, "BucketId");
+ ASSERT_EQ(resp.GetQueueList().category, "DocProcess");
+ }
+}
+
+TEST(ObjectRespTest, ObjectTest) {
+ {
+ std::string body = "\n";
+ body += " Location\n";
+ body += " Bucket\n";
+ body += " Key\n";
+ body += " ETag\n";
+ body += "";
+ MultiPutObjectResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetLocation(), "Location");
+ ASSERT_EQ(resp.GetBucket(), "Bucket");
+ ASSERT_EQ(resp.GetKey(), "Key");
+ ASSERT_EQ(resp.GetEtag(), "ETag");
+ }
+ {
+ std::string body;
+ body += "\n";
+ body += " \n";
+ body += " StartTime\n";
+ body += " EndTime\n";
+ body += " RemoteAddr\n";
+ body += " RequestId\n";
+ body += " \n";
+ body += "";
+ GetLiveChannelHistoryResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetChanHistory()[0].m_start_time, "StartTime");
+ ASSERT_EQ(resp.GetChanHistory()[0].m_end_time, "EndTime");
+ ASSERT_EQ(resp.GetChanHistory()[0].m_remote_addr, "RemoteAddr");
+ ASSERT_EQ(resp.GetChanHistory()[0].m_request_id, "RequestId");
+ }
+ {
+ std::string body;
+ body += "\n";
+ body += " Live\n";
+ body += " ConnectedTime\n";
+ body += " RemoteAddr\n";
+ body += " RequestId\n";
+ body += " \n";
+ body += " \n";
+ body += "";
+ GetLiveChannelStatusResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_status, "Live");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_connected_time, "ConnectedTime");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_remote_addr, "RemoteAddr");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_request_id, "RequestId");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_width, "Width");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_heigh, "Height");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_framerate, "FrameRate");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_bandwidth, "Bandwidth");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_codec, "Codec");
+ ASSERT_TRUE(resp.GetLiveChannelStatus().m_has_audio);
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_bandwidth, "Bandwidth");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_samplerate, "SampleRate");
+ ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_codec, "Codec");
+
+ }
+ {
+ std::string body ;
+ body += "\n";
+ body += " \n";
+ body += " string1\n";
+ body += " true\n";
+ body += " string1\n";
+ body += " \n";
+ body += " \n";
+ body += " string2\n";
+ body += " string2\n";
+ body += " \n";
+ body += " \n";
+ body += " string3\n";
+ body += " false\n";
+ body += " string3\n";
+ body += " string3\n";
+ body += " \n";
+ body += " \n";
+ body += " string4\n";
+ body += " string4\n";
+ body += " string4\n";
+ body += " string4\n";
+ body += " \n";
+ body += "";
+ DeleteObjectsResp resp;
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetErrorMsgs()[0].m_code, "string4");
+ ASSERT_EQ(resp.GetErrorMsgs()[0].m_key, "string4");
+ ASSERT_EQ(resp.GetErrorMsgs()[0].m_message, "string4");
+ ASSERT_EQ(resp.GetErrorMsgs()[0].m_version_id, "string4");
+ ASSERT_EQ(resp.GetDeletedInfos()[0].m_key, "string1");
+ ASSERT_TRUE(resp.GetDeletedInfos()[0].m_delete_marker);
+ ASSERT_EQ(resp.GetDeletedInfos()[0].m_delete_marker_version_id, "string1");
+ ASSERT_EQ(resp.GetDeletedInfos()[1].m_key, "string2");
+ ASSERT_EQ(resp.GetDeletedInfos()[1].m_delete_marker_version_id, "string2");
+ ASSERT_EQ(resp.GetDeletedInfos()[2].m_key, "string3");
+ ASSERT_TRUE(!resp.GetDeletedInfos()[2].m_delete_marker);
+ ASSERT_EQ(resp.GetDeletedInfos()[2].m_delete_marker_version_id, "string3");
+ ASSERT_EQ(resp.GetDeletedInfos()[2].m_version_id, "string3");
+ }
+}
+
+TEST(ObjectRespTest, AudioAuditingRespTest) {
+ std::string base_body;
+ {
+ AudioAuditingResp resp;
+ std::string body;
+ body += "\n";
+ base_body += " \n";
+ base_body += " 0\n";
+ base_body += " \n";
+ base_body += " 4\n";
+ base_body += " 14\n";
+ base_body += " 1\n";
+ base_body += " 40\n";
+ base_body += " \n";
+ base_body += " 2\n";
+
+ base_body += " \n";
+ std::string info_body;
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " 3\n";
+ info_body += " \n";
+ info_body += " 5\n";
+ info_body += " 6\n";
+ info_body += " \n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " \n";
+ info_body += " \n";
+ info_body += " \n";
+ info_body += " 5\n";
+ info_body += " \n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " 5\n";
+ info_body += " \n";
+ info_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += info_body;
+ base_body += " \n";
+
+ base_body += " \n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " \n";
+ base_body += " 13\n";
+ base_body += " \n";
+ base_body += " 15\n";
+ base_body += " \n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " \n";
+ base_body += " 15\n";
+ base_body += " 15\n";
+ base_body += " \n";
+ base_body += " \n";
+ body += base_body + "";
+ resp.ParseFromXmlString(body);
+ ASSERT_EQ(resp.GetJobsDetail().GetCode(), "0");
+ ASSERT_EQ(resp.GetJobsDetail().GetJobId(), "4");
+ ASSERT_EQ(resp.GetJobsDetail().GetState(), "14");
+ ASSERT_EQ(resp.GetJobsDetail().GetCreationTime(), "1");
+ ASSERT_EQ(resp.GetJobsDetail().GetResult(), 40);
+ ASSERT_EQ(resp.GetJobsDetail().GetLabel(), "41");
+ ASSERT_EQ(resp.GetJobsDetail().GetAudioText(), "2");
+ ASSERT_TRUE(resp.GetJobsDetail().HasCode());
+ ASSERT_TRUE(resp.GetJobsDetail().HasJobId());
+ ASSERT_TRUE(resp.GetJobsDetail().HasState());
+ ASSERT_TRUE(resp.GetJobsDetail().HasCreationTime());
+ ASSERT_TRUE(resp.GetJobsDetail().HasResult());
+ ASSERT_TRUE(resp.GetJobsDetail().HasLabel());
+ ASSERT_TRUE(resp.GetJobsDetail().HasAudioText());
+ ASSERT_TRUE(resp.GetJobsDetail().HasLabel());
+
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCode(), 3);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetMsg(), "3");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCount(), 3);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetHitFlag(), 3);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetScore(), 3);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetSubLabel(), "3");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCategory(), "3");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetKeyWords()[0], "3");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetKeyWords()[0], "6");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetText(), "5");
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetX(), 5);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetY(), 5);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetWidth(), 5);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetHeight(), 5);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetRotate(), 5);
+ ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCode(), 3);
+
+
+ ASSERT_TRUE(resp.GetJobsDetail().HasPornInfo());
+ ASSERT_TRUE(resp.GetJobsDetail().HasAbuseInfo());
+ ASSERT_TRUE(resp.GetJobsDetail().HasAdsInfo());
+ ASSERT_TRUE(resp.GetJobsDetail().HasIllegalInfo());
+ ASSERT_TRUE(resp.GetJobsDetail().HasPoliticsInfo());
+ ASSERT_TRUE(resp.GetJobsDetail().HasTerrorismInfo());
+
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetTokenId(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetNickName(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetDeviceId(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetAppId(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetRoom(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetIp(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetType(), "15");
+
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasTokenId());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasNickName());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasDeviceId());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasAppId());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasRoom());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasIp());
+ ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasType());
+
+ ASSERT_TRUE(resp.GetJobsDetail().HasUserInfo());
+ ASSERT_EQ(resp.GetJobsDetail().GetDataId(), "13");
+ ASSERT_EQ(resp.GetJobsDetail().GetUrl(), "15");
+ ASSERT_EQ(resp.GetJobsDetail().GetObject(), "15");
+
+ ASSERT_TRUE(resp.GetJobsDetail().HasDataId());
+ ASSERT_TRUE(resp.GetJobsDetail().HasUrl());
+ ASSERT_TRUE(resp.GetJobsDetail().HasObject());
+ resp.GetJobsDetail().to_string();
+
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetUrl(),"15");
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetDuration(),15);
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetLabel(),"15");
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetOffsetTime(),15);
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetResult(),15);
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetText(),"15");
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetStartByte(),15);
+ ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetSnapShotTime(),15);
+
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasLabel());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasDuration());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasOffsetTime());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasUrl());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasResult());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasText());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasStartByte());
+ ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasSnapShotTime());
+
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasAdsInfo());
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasIllegalInfo());
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasPoliticsInfo());
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasTerrorismInfo());
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasPornInfo());
+ ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasAbuseInfo());
+ resp.GetJobsDetail().GetSection()[0].to_string();
}
}