diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index 576675a..a5c129e 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -3,15 +3,52 @@ project(cos-demo) if (NOT ${OS_TYPE} STREQUAL "WINDOWS") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function") endif() -file(GLOB demo_src "${CMAKE_SOURCE_DIR}/demo/cos_demo.cpp") -file(GLOB stable_test_src "${CMAKE_SOURCE_DIR}/demo/stable_test.cpp") +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") link_directories(${POCO_LINK_DIR} ${OPENSSL_LINK_DIR}) #这一行要放到add_executable前面 -add_executable(${PROJECT_NAME} ${demo_src}) -add_executable(stable_test ${stable_test_src}) + +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}) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) -target_link_libraries(${PROJECT_NAME} cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(stable_test cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) + +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}) + include_directories(${CMAKE_SOURCE_DIR}/include/ ${POCO_INCLUDE_DIR}) if(${OS_TYPE} STREQUAL "WINDOWS") diff --git a/demo/object_op_demo/copy_move_object_demo.cpp b/demo/object_op_demo/copy_move_object_demo.cpp new file mode 100644 index 0000000..d179bc3 --- /dev/null +++ b/demo/object_op_demo/copy_move_object_demo.cpp @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#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 etags; + std::vector 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); +} \ No newline at end of file diff --git a/demo/object_op_demo/delete_object_demo.cpp b/demo/object_op_demo/delete_object_demo.cpp new file mode 100644 index 0000000..753f845 --- /dev/null +++ b/demo/object_op_demo/delete_object_demo.cpp @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include +#include +#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 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 deleted_infos = resp.GetDeletedInfos(); // 单个删除成功的对象条目,仅当使用 Verbose 模式才会返回该元素 + std::vector 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); +} \ No newline at end of file diff --git a/demo/object_op_demo/get_object_demo.cpp b/demo/object_op_demo/get_object_demo.cpp new file mode 100644 index 0000000..aab9355 --- /dev/null +++ b/demo/object_op_demo/get_object_demo.cpp @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include +#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 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; +} + +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 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); + GetBucketDemo(cos); +} \ No newline at end of file diff --git a/demo/object_op_demo/get_object_url_demo.cpp b/demo/object_op_demo/get_object_url_demo.cpp new file mode 100644 index 0000000..923c2cd --- /dev/null +++ b/demo/object_op_demo/get_object_url_demo.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} \ No newline at end of file diff --git a/demo/object_op_demo/head_object_demo.cpp b/demo/object_op_demo/head_object_demo.cpp new file mode 100644 index 0000000..acbee5d --- /dev/null +++ b/demo/object_op_demo/head_object_demo.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#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 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); +} \ No newline at end of file diff --git a/demo/object_op_demo/multi_get_object_demo.cpp b/demo/object_op_demo/multi_get_object_demo.cpp new file mode 100644 index 0000000..1ab9e7d --- /dev/null +++ b/demo/object_op_demo/multi_get_object_demo.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#include +#include +#include +#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(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); +} \ No newline at end of file diff --git a/demo/object_op_demo/multi_put_object_demo.cpp b/demo/object_op_demo/multi_put_object_demo.cpp new file mode 100644 index 0000000..b99fc19 --- /dev/null +++ b/demo/object_op_demo/multi_put_object_demo.cpp @@ -0,0 +1,338 @@ +#include +#include +#include +#include +#include +#include +#include +#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 示范如何使用高级上传接口进行对象上传 + * 仅支持文件上传,不支持流式上传,封装了分块上传的各接口 + * 可通过全局设置上传线程池大小、分块大小。该上传线程池是每次上传独立的。 + */ +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); + 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(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 个分块为例 + std::vector etags; + std::vector part_numbers; + std::string upload_id = init_resp.GetUploadId(); + { + uint64_t part_number = 1; + // 模拟上传分块数据,这里以 1M 为例 + std::vector data(1024 * 1024, '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); + qcloud_cos::UploadPartDataResp resp; + qcloud_cos::CosResult result = cos.UploadPartData(req, &resp); + 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; + std::istringstream iss("The last part can be smaller than 1MB"); + qcloud_cos::UploadPartDataReq req(bucket_name, object_name, upload_id, iss); + req.SetPartNumber(part_number); + 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; +} +int main() { + qcloud_cos::CosAPI cos = InitCosAPI(); + CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR); + MultiUploadObjectDemo(cos); + AsyncMultiPutObjectDemo(cos); + AsyncPutObjectDemo(cos); + PutPartDemo(cos); +} \ No newline at end of file diff --git a/demo/object_op_demo/put_get_delete_object_tagging_demo.cpp b/demo/object_op_demo/put_get_delete_object_tagging_demo.cpp new file mode 100644 index 0000000..e0970c0 --- /dev/null +++ b/demo/object_op_demo/put_get_delete_object_tagging_demo.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#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 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 tagset = resp.GetTagSet(); + for (std::vector::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); +} \ No newline at end of file diff --git a/demo/object_op_demo/put_get_object_acl_demo.cpp b/demo/object_op_demo/put_get_object_acl_demo.cpp new file mode 100644 index 0000000..4a7cf83 --- /dev/null +++ b/demo/object_op_demo/put_get_object_acl_demo.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} \ No newline at end of file diff --git a/demo/object_op_demo/put_object_demo.cpp b/demo/object_op_demo/put_object_demo.cpp new file mode 100644 index 0000000..51c813c --- /dev/null +++ b/demo/object_op_demo/put_object_demo.cpp @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/demo/object_op_demo/restore_object_demo.cpp b/demo/object_op_demo/restore_object_demo.cpp new file mode 100644 index 0000000..2bdcd93 --- /dev/null +++ b/demo/object_op_demo/restore_object_demo.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} \ No newline at end of file diff --git a/demo/object_op_demo/select_objec_demo.cpp b/demo/object_op_demo/select_objec_demo.cpp new file mode 100644 index 0000000..ebb7a98 --- /dev/null +++ b/demo/object_op_demo/select_objec_demo.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} \ No newline at end of file diff --git a/include/request/auditing_req.h b/include/request/auditing_req.h index 5079890..c6b32ab 100644 --- a/include/request/auditing_req.h +++ b/include/request/auditing_req.h @@ -2862,7 +2862,7 @@ class Conf { class GetImageAuditingReq : public ObjectReq { public: - GetImageAuditingReq(const std::string& bucket_name) + explicit GetImageAuditingReq(const std::string& bucket_name) : ObjectReq(bucket_name, "") { AddParam("ci-process", "sensitive-content-recognition"); SetMethod("GET"); @@ -2927,7 +2927,7 @@ class GetImageAuditingReq : public ObjectReq { class BatchImageAuditingReq : public BucketReq { public: - BatchImageAuditingReq(const std::string& bucket_name) + explicit BatchImageAuditingReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("POST"); SetPath("/image/auditing"); @@ -2951,7 +2951,7 @@ class BatchImageAuditingReq : public BucketReq { class DescribeAuditingJobReq : public BucketReq { public: - DescribeAuditingJobReq(const std::string& bucket_name) + explicit DescribeAuditingJobReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetHttps(); @@ -2963,7 +2963,7 @@ class DescribeAuditingJobReq : public BucketReq { class DescribeImageAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeImageAuditingJobReq(const std::string& bucket_name) + explicit DescribeImageAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/image/auditing"); } @@ -2972,7 +2972,7 @@ class DescribeImageAuditingJobReq : public DescribeAuditingJobReq { class CreateAuditingJobReq : public BucketReq { public: - CreateAuditingJobReq(const std::string& bucket_name) + explicit CreateAuditingJobReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("POST"); SetHttps(); @@ -2991,7 +2991,7 @@ class CreateAuditingJobReq : public BucketReq { class CreateVideoAuditingJobReq : public CreateAuditingJobReq { public: - CreateVideoAuditingJobReq(const std::string& bucket_name) + explicit CreateVideoAuditingJobReq(const std::string& bucket_name) : CreateAuditingJobReq(bucket_name) { SetPath("/video/auditing"); } @@ -3012,7 +3012,7 @@ class CreateVideoAuditingJobReq : public CreateAuditingJobReq { class DescribeVideoAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeVideoAuditingJobReq(const std::string& bucket_name) + explicit DescribeVideoAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/video/auditing"); } @@ -3021,7 +3021,7 @@ class DescribeVideoAuditingJobReq : public DescribeAuditingJobReq { class CreateAudioAuditingJobReq : public CreateAuditingJobReq { public: - CreateAudioAuditingJobReq(const std::string& bucket_name) + explicit CreateAudioAuditingJobReq(const std::string& bucket_name) : CreateAuditingJobReq(bucket_name) { SetPath("/audio/auditing"); } @@ -3041,7 +3041,7 @@ class CreateAudioAuditingJobReq : public CreateAuditingJobReq { class DescribeAudioAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeAudioAuditingJobReq(const std::string& bucket_name) + explicit DescribeAudioAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/audio/auditing"); } @@ -3050,7 +3050,7 @@ class DescribeAudioAuditingJobReq : public DescribeAuditingJobReq { class CreateTextAuditingJobReq : public CreateAuditingJobReq { public: - CreateTextAuditingJobReq(const std::string& bucket_name) + explicit CreateTextAuditingJobReq(const std::string& bucket_name) : CreateAuditingJobReq(bucket_name) { SetPath("/text/auditing"); } @@ -3071,7 +3071,7 @@ class CreateTextAuditingJobReq : public CreateAuditingJobReq { class DescribeTextAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeTextAuditingJobReq(const std::string& bucket_name) + explicit DescribeTextAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/text/auditing"); } @@ -3080,7 +3080,7 @@ class DescribeTextAuditingJobReq : public DescribeAuditingJobReq { class CreateDocumentAuditingJobReq : public CreateAuditingJobReq { public: - CreateDocumentAuditingJobReq(const std::string& bucket_name) + explicit CreateDocumentAuditingJobReq(const std::string& bucket_name) : CreateAuditingJobReq(bucket_name) { SetPath("/document/auditing"); } @@ -3099,7 +3099,7 @@ class CreateDocumentAuditingJobReq : public CreateAuditingJobReq { class DescribeDocumentAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeDocumentAuditingJobReq(const std::string& bucket_name) + explicit DescribeDocumentAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/document/auditing"); } @@ -3108,7 +3108,7 @@ class DescribeDocumentAuditingJobReq : public DescribeAuditingJobReq { class CreateWebPageAuditingJobReq : public CreateAuditingJobReq { public: - CreateWebPageAuditingJobReq(const std::string& bucket_name) + explicit CreateWebPageAuditingJobReq(const std::string& bucket_name) : CreateAuditingJobReq(bucket_name) { SetPath("/webpage/auditing"); } @@ -3129,7 +3129,7 @@ class CreateWebPageAuditingJobReq : public CreateAuditingJobReq { class DescribeWebPageAuditingJobReq : public DescribeAuditingJobReq { public: - DescribeWebPageAuditingJobReq(const std::string& bucket_name) + explicit DescribeWebPageAuditingJobReq(const std::string& bucket_name) : DescribeAuditingJobReq(bucket_name) { SetPath("/webpage/auditing"); } diff --git a/include/request/bucket_req.h b/include/request/bucket_req.h index 318821f..35a3436 100644 --- a/include/request/bucket_req.h +++ b/include/request/bucket_req.h @@ -18,7 +18,7 @@ namespace qcloud_cos { class BucketReq : public BaseReq { public: BucketReq() : m_bucket_name("") {} - BucketReq(const std::string& bucket_name) : m_bucket_name(bucket_name) {} + explicit BucketReq(const std::string& bucket_name) : m_bucket_name(bucket_name) {} virtual ~BucketReq() {} // getter and setter @@ -34,7 +34,7 @@ class BucketReq : public BaseReq { class HeadBucketReq : public BucketReq { public: - HeadBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit HeadBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { m_method = "HEAD"; } @@ -43,7 +43,7 @@ class HeadBucketReq : public BucketReq { class PutBucketReq : public BucketReq { public: - PutBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); } @@ -86,7 +86,7 @@ class PutBucketReq : public BucketReq { class GetBucketReq : public BucketReq { public: - GetBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); } @@ -120,7 +120,7 @@ class GetBucketReq : public BucketReq { class ListMultipartUploadReq : public BucketReq { public: - ListMultipartUploadReq(const std::string& bucket_name) + explicit ListMultipartUploadReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -154,7 +154,7 @@ class ListMultipartUploadReq : public BucketReq { class DeleteBucketReq : public BucketReq { public: - DeleteBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit DeleteBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); } @@ -163,7 +163,7 @@ class DeleteBucketReq : public BucketReq { class GetBucketVersioningReq : public BucketReq { public: - GetBucketVersioningReq(const std::string& bucket_name) + explicit GetBucketVersioningReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -175,7 +175,7 @@ class GetBucketVersioningReq : public BucketReq { class PutBucketVersioningReq : public BucketReq { public: - PutBucketVersioningReq(const std::string& bucket_name) + explicit PutBucketVersioningReq(const std::string& bucket_name) : BucketReq(bucket_name), m_status(true) { SetMethod("PUT"); SetPath("/"); @@ -197,7 +197,7 @@ class PutBucketVersioningReq : public BucketReq { class GetBucketReplicationReq : public BucketReq { public: - GetBucketReplicationReq(const std::string& bucket_name) + explicit GetBucketReplicationReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -209,7 +209,7 @@ class GetBucketReplicationReq : public BucketReq { class PutBucketReplicationReq : public BucketReq { public: - PutBucketReplicationReq(const std::string& bucket_name) + explicit PutBucketReplicationReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); @@ -237,7 +237,7 @@ class PutBucketReplicationReq : public BucketReq { class DeleteBucketReplicationReq : public BucketReq { public: - DeleteBucketReplicationReq(const std::string& bucket_name) + explicit DeleteBucketReplicationReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("Delete"); SetPath("/"); @@ -249,7 +249,7 @@ class DeleteBucketReplicationReq : public BucketReq { class GetBucketLifecycleReq : public BucketReq { public: - GetBucketLifecycleReq(const std::string& bucket_name) + explicit GetBucketLifecycleReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -261,7 +261,7 @@ class GetBucketLifecycleReq : public BucketReq { class PutBucketLifecycleReq : public BucketReq { public: - PutBucketLifecycleReq(const std::string& bucket_name) + explicit PutBucketLifecycleReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); @@ -282,7 +282,7 @@ class PutBucketLifecycleReq : public BucketReq { class DeleteBucketLifecycleReq : public BucketReq { public: - DeleteBucketLifecycleReq(const std::string& bucket_name) + explicit DeleteBucketLifecycleReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); SetPath("/"); @@ -294,7 +294,7 @@ class DeleteBucketLifecycleReq : public BucketReq { class GetBucketACLReq : public BucketReq { public: - GetBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("acl", ""); @@ -305,7 +305,7 @@ class GetBucketACLReq : public BucketReq { class PutBucketACLReq : public BucketReq { public: - PutBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("acl", ""); @@ -364,7 +364,7 @@ class PutBucketACLReq : public BucketReq { class GetBucketPolicyReq : public BucketReq { public: - GetBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("policy", ""); @@ -375,7 +375,7 @@ class GetBucketPolicyReq : public BucketReq { class PutBucketPolicyReq : public BucketReq { public: - PutBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("policy", ""); @@ -386,7 +386,7 @@ class PutBucketPolicyReq : public BucketReq { class DeleteBucketPolicyReq : public BucketReq { public: - DeleteBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit DeleteBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); SetPath("/"); AddParam("policy", ""); @@ -397,7 +397,7 @@ class DeleteBucketPolicyReq : public BucketReq { class DeleteBucketACLReq : public BucketReq { public: - DeleteBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit DeleteBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); } @@ -406,7 +406,7 @@ class DeleteBucketACLReq : public BucketReq { class GetBucketCORSReq : public BucketReq { public: - GetBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("cors", ""); @@ -417,7 +417,7 @@ class GetBucketCORSReq : public BucketReq { class PutBucketCORSReq : public BucketReq { public: - PutBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("cors", ""); @@ -438,7 +438,7 @@ class PutBucketCORSReq : public BucketReq { class DeleteBucketCORSReq : public BucketReq { public: - DeleteBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit DeleteBucketCORSReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); SetPath("/"); AddParam("cors", ""); @@ -449,7 +449,7 @@ class DeleteBucketCORSReq : public BucketReq { class GetBucketLocationReq : public BucketReq { public: - GetBucketLocationReq(const std::string& bucket_name) + explicit GetBucketLocationReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -461,7 +461,7 @@ class GetBucketLocationReq : public BucketReq { class GetBucketObjectVersionsReq : public BucketReq { public: - GetBucketObjectVersionsReq(const std::string& bucket_name) + explicit GetBucketObjectVersionsReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -503,7 +503,7 @@ class GetBucketObjectVersionsReq : public BucketReq { class PutBucketLoggingReq : public BucketReq { public: - PutBucketLoggingReq(const std::string& bucket_name) + explicit PutBucketLoggingReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u) { SetMethod("PUT"); SetPath("/"); @@ -526,7 +526,7 @@ class PutBucketLoggingReq : public BucketReq { class GetBucketLoggingReq : public BucketReq { public: - GetBucketLoggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketLoggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("logging", ""); @@ -536,7 +536,7 @@ class GetBucketLoggingReq : public BucketReq { class PutBucketDomainReq : public BucketReq { public: - PutBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("domain", ""); @@ -552,7 +552,7 @@ class PutBucketDomainReq : public BucketReq { class GetBucketDomainReq : public BucketReq { public: - GetBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketDomainReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("domain", ""); @@ -562,7 +562,7 @@ class GetBucketDomainReq : public BucketReq { class PutBucketWebsiteReq : public BucketReq { public: - PutBucketWebsiteReq(const std::string& bucket_name) + explicit PutBucketWebsiteReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u), m_suffix(""), @@ -632,7 +632,7 @@ class PutBucketWebsiteReq : public BucketReq { class GetBucketWebsiteReq : public BucketReq { public: - GetBucketWebsiteReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketWebsiteReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("Get"); SetPath("/"); AddParam("website", ""); @@ -643,7 +643,7 @@ class GetBucketWebsiteReq : public BucketReq { class DeleteBucketWebsiteReq : public BucketReq { public: - DeleteBucketWebsiteReq(const std::string& bucket_name) + explicit DeleteBucketWebsiteReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); SetPath("/"); @@ -655,7 +655,7 @@ class DeleteBucketWebsiteReq : public BucketReq { class PutBucketTaggingReq : public BucketReq { public: - PutBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("tagging", ""); @@ -683,7 +683,7 @@ class PutBucketTaggingReq : public BucketReq { class GetBucketTaggingReq : public BucketReq { public: - GetBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("tagging", ""); @@ -693,7 +693,7 @@ class GetBucketTaggingReq : public BucketReq { class DeleteBucketTaggingReq : public BucketReq { public: - DeleteBucketTaggingReq(const std::string& bucket_name) + explicit DeleteBucketTaggingReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("DELETE"); SetPath("/"); @@ -705,7 +705,7 @@ class DeleteBucketTaggingReq : public BucketReq { class PutBucketInventoryReq : public BucketReq { public: - PutBucketInventoryReq(const std::string& bucket_name) + explicit PutBucketInventoryReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u) { SetMethod("PUT"); SetPath("/"); @@ -742,7 +742,7 @@ class PutBucketInventoryReq : public BucketReq { class GetBucketInventoryReq : public BucketReq { public: - GetBucketInventoryReq(const std::string& bucket_name) + explicit GetBucketInventoryReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u) { SetMethod("GET"); SetPath("/"); @@ -768,7 +768,7 @@ class GetBucketInventoryReq : public BucketReq { class ListBucketInventoryConfigurationsReq : public BucketReq { public: - ListBucketInventoryConfigurationsReq(const std::string& bucket_name) + explicit ListBucketInventoryConfigurationsReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u) { SetMethod("GET"); SetPath("/"); @@ -794,7 +794,7 @@ class ListBucketInventoryConfigurationsReq : public BucketReq { class DeleteBucketInventoryReq : public BucketReq { public: - DeleteBucketInventoryReq(const std::string& bucket_name) + explicit DeleteBucketInventoryReq(const std::string& bucket_name) : BucketReq(bucket_name), m_mask(0x00000000u), m_id("") { SetMethod("DELETE"); SetPath("/"); @@ -821,7 +821,7 @@ class DeleteBucketInventoryReq : public BucketReq { /// \brief: 列举直播通道请求 class ListLiveChannelReq : public BucketReq { public: - ListLiveChannelReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit ListLiveChannelReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("live", ""); @@ -837,7 +837,7 @@ class ListLiveChannelReq : public BucketReq { /// \brief: 配置存储桶智能分层特性 class PutBucketIntelligentTieringReq : public BucketReq { public: - PutBucketIntelligentTieringReq(const std::string& bucket_name) + explicit PutBucketIntelligentTieringReq(const std::string& bucket_name) : BucketReq(bucket_name), m_status(false), m_days(30) { SetMethod("PUT"); SetPath("/"); @@ -862,7 +862,7 @@ class PutBucketIntelligentTieringReq : public BucketReq { /// \brief: 获取存储桶智能分层配置 class GetBucketIntelligentTieringReq : public BucketReq { public: - GetBucketIntelligentTieringReq(const std::string& bucket_name) + explicit GetBucketIntelligentTieringReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); @@ -873,7 +873,7 @@ class GetBucketIntelligentTieringReq : public BucketReq { class PutBucketRefererReq : public BucketReq { public: - PutBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit PutBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/"); AddParam("referer", ""); @@ -908,7 +908,7 @@ class PutBucketRefererReq : public BucketReq { class GetBucketRefererReq : public BucketReq { public: - GetBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) { + explicit GetBucketRefererReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/"); AddParam("referer", ""); diff --git a/include/request/data_process_req.h b/include/request/data_process_req.h index c4ee083..13662b3 100644 --- a/include/request/data_process_req.h +++ b/include/request/data_process_req.h @@ -1812,7 +1812,7 @@ class DocPreviewReq : public GetObjectByFileReq { class DescribeQueuesReq : public BucketReq { public: - DescribeQueuesReq(const std::string bucket_name) + explicit DescribeQueuesReq(const std::string bucket_name) :BucketReq(bucket_name) { m_method = "GET"; @@ -1845,7 +1845,7 @@ class DescribeQueuesReq : public BucketReq { class UpdateQueueReq : public BucketReq { public: - UpdateQueueReq(const std::string& bucket_name) + explicit UpdateQueueReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/queue"); @@ -1874,7 +1874,7 @@ class UpdateQueueReq : public BucketReq { class CreateDocProcessJobsReq : public BucketReq { public: - CreateDocProcessJobsReq(const std::string& bucket_name) + explicit CreateDocProcessJobsReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("POST"); SetPath("/doc_jobs"); @@ -1900,7 +1900,7 @@ class CreateDocProcessJobsReq : public BucketReq { class DescribeDocProcessJobReq : public BucketReq { public: - DescribeDocProcessJobReq(const std::string& bucket_name) + explicit DescribeDocProcessJobReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/doc_jobs"); @@ -1912,7 +1912,7 @@ class DescribeDocProcessJobReq : public BucketReq { class DescribeDocProcessJobsReq : public BucketReq { public: - DescribeDocProcessJobsReq(const std::string& bucket_name) + explicit DescribeDocProcessJobsReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/doc_jobs"); @@ -1950,7 +1950,7 @@ class DescribeDocProcessJobsReq : public BucketReq { class DescribeDocProcessQueuesReq : public DescribeQueuesReq { public: - DescribeDocProcessQueuesReq(const std::string& bucket_name) + explicit DescribeDocProcessQueuesReq(const std::string& bucket_name) : DescribeQueuesReq(bucket_name) { SetPath("/docqueue"); } @@ -1959,7 +1959,7 @@ class DescribeDocProcessQueuesReq : public DescribeQueuesReq { class UpdateDocProcessQueueReq : public UpdateQueueReq { public: - UpdateDocProcessQueueReq(const std::string& bucket_name) + explicit UpdateDocProcessQueueReq(const std::string& bucket_name) : UpdateQueueReq(bucket_name) { SetPath("/docqueue"); } @@ -2113,7 +2113,7 @@ class GetPm3u8Req : public GetObjectByFileReq { class DescribeMediaQueuesReq : public DescribeQueuesReq { public: - DescribeMediaQueuesReq(const std::string bucket_name) + explicit DescribeMediaQueuesReq(const std::string bucket_name) : DescribeQueuesReq(bucket_name) { m_path = "/queue"; } @@ -2131,7 +2131,7 @@ class DescribeMediaQueuesReq : public DescribeQueuesReq { class UpdateMediaQueueReq : public UpdateQueueReq { public: - UpdateMediaQueueReq(const std::string& bucket_name) + explicit UpdateMediaQueueReq(const std::string& bucket_name) : UpdateQueueReq(bucket_name) { SetPath("/docqueue"); } @@ -2140,7 +2140,7 @@ class UpdateMediaQueueReq : public UpdateQueueReq { class CreateDataProcessJobsReq : public BucketReq { public: - CreateDataProcessJobsReq(const std::string& bucket_name) + explicit CreateDataProcessJobsReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("POST"); SetPath("/jobs"); @@ -2169,7 +2169,7 @@ class CreateDataProcessJobsReq : public BucketReq { class DescribeDataProcessJobReq : public BucketReq { public: - DescribeDataProcessJobReq(const std::string& bucket_name) + explicit DescribeDataProcessJobReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("GET"); SetPath("/jobs"); @@ -2181,7 +2181,7 @@ class DescribeDataProcessJobReq : public BucketReq { class CancelDataProcessJobReq : public BucketReq { public: - CancelDataProcessJobReq(const std::string& bucket_name) + explicit CancelDataProcessJobReq(const std::string& bucket_name) : BucketReq(bucket_name) { SetMethod("PUT"); SetPath("/jobs"); diff --git a/include/request/object_req.h b/include/request/object_req.h index a65a839..cdbe7fa 100644 --- a/include/request/object_req.h +++ b/include/request/object_req.h @@ -431,7 +431,7 @@ class DeleteObjectReq : public ObjectReq { class DeleteObjectsReq : public BaseReq { public: - DeleteObjectsReq(const std::string& bucket_name) + explicit DeleteObjectsReq(const std::string& bucket_name) : m_is_quiet(false), m_bucket_name(bucket_name) { SetMethod("POST"); AddParam("delete", ""); diff --git a/include/response/object_resp.h b/include/response/object_resp.h index c666238..7287819 100644 --- a/include/response/object_resp.h +++ b/include/response/object_resp.h @@ -253,6 +253,9 @@ class CompleteMultiUploadResp : public BaseResp { 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 { @@ -263,6 +266,7 @@ class CompleteMultiUploadResp : public BaseResp { std::string m_location; // Object的外网访问域名 std::string m_bucket; std::string m_key; + std::string m_etag; }; class AbortMultiUploadResp : public BaseResp { diff --git a/include/trsf/async_context.h b/include/trsf/async_context.h index 307e099..aa02c65 100644 --- a/include/trsf/async_context.h +++ b/include/trsf/async_context.h @@ -7,7 +7,7 @@ namespace qcloud_cos { class AsyncContext { public: - AsyncContext(const SharedTransferHandler& handler) : m_handler(handler) {} + explicit AsyncContext(const SharedTransferHandler& handler) : m_handler(handler) {} /// @brief 取消操作 void Cancel() { return m_handler->Cancel(); } diff --git a/include/trsf/async_task.h b/include/trsf/async_task.h index 6d705fa..f9c531e 100644 --- a/include/trsf/async_task.h +++ b/include/trsf/async_task.h @@ -11,7 +11,7 @@ using TaskFunc = std::function; class AsyncTask : public Poco::Task { public: - AsyncTask(TaskFunc &&f) : Task("AsyncTask"), _f(f) {} + explicit AsyncTask(TaskFunc &&f) : Task("AsyncTask"), _f(f) {} ~AsyncTask() {} void runTask() { _f(); } diff --git a/include/util/lru_cache.h b/include/util/lru_cache.h index dfcf1e7..05978cc 100644 --- a/include/util/lru_cache.h +++ b/include/util/lru_cache.h @@ -14,7 +14,7 @@ class LruCache { using KeyValuePair = std::pair; using ListIterator = typename std::list::iterator; - LruCache(size_t size) : m_max_size(size) {} + explicit LruCache(size_t size) : m_max_size(size) {} ~LruCache() {} diff --git a/src/cos_sys_config.cpp b/src/cos_sys_config.cpp index e2ac48d..2eef1a4 100644 --- a/src/cos_sys_config.cpp +++ b/src/cos_sys_config.cpp @@ -41,10 +41,12 @@ 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; diff --git a/src/op/object_op.cpp b/src/op/object_op.cpp index dc61506..436496e 100644 --- a/src/op/object_op.cpp +++ b/src/op/object_op.cpp @@ -892,8 +892,16 @@ CosResult ObjectOp::CompleteMultiUpload(const CompleteMultiUploadReq& req, std::map additional_params; additional_params.insert(std::make_pair("uploadId", req.GetUploadId())); - return NormalAction(host, path, req, additional_headers, additional_params, - req_body, true, resp); + CosResult result = NormalAction(host, path, req, additional_headers, additional_params, + req_body, true, resp); + if (result.IsSucc() && resp->GetEtag().empty()) { + result.SetFail(); + result.SetErrorCode("ServerError"); + result.SetErrorMsg("Complete Fail"); + } else { + resp->AddEtagToHeader(); + } + return result; } CosResult ObjectOp::AbortMultiUpload(const AbortMultiUploadReq& req, @@ -997,7 +1005,13 @@ CosResult ObjectOp::PutObjectCopy(const PutObjectCopyReq& req, std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), req.GetBucketName(), change_backup_domain); std::string path = req.GetPath(); - return NormalAction(host, path, req, "", true, resp); + CosResult result = NormalAction(host, path, req, "", true, resp); + if (result.IsSucc() && resp->GetEtag().empty()) { + result.SetFail(); + result.SetErrorCode("ServerError"); + result.SetErrorMsg("Complete Fail"); + } + return result; } CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_domain) { @@ -2171,7 +2185,7 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, handler->UpdateStatus(TransferStatus::IN_PROGRESS); } - unsigned pool_size = CosSysConfig::GetUploadThreadPoolSize(); + unsigned pool_size = CosSysConfig::GetDownThreadPoolSize(); unsigned slice_size = CosSysConfig::GetDownSliceSize(); unsigned max_task_num = (file_size - resume_offset) / slice_size + 1; if (max_task_num < pool_size) { diff --git a/src/response/object_resp.cpp b/src/response/object_resp.cpp index 8b30b5f..c247eb9 100644 --- a/src/response/object_resp.cpp +++ b/src/response/object_resp.cpp @@ -181,6 +181,7 @@ void MultiPutObjectResp::CopyFrom(const CompleteMultiUploadResp& resp) { m_location = resp.GetLocation(); m_bucket = resp.GetBucket(); m_key = resp.GetKey(); + SetEtag(resp.GetEtag()); } bool ListPartsResp::ParseFromXmlString(const std::string& body) { @@ -414,6 +415,7 @@ void CopyResp::CopyFrom(const PutObjectCopyResp& resp) { InternalCopyFrom(resp); m_resp_tag = "PutObjectCopy"; m_etag = resp.GetEtag(); + SetEtag(resp.GetEtag()); m_last_modified = resp.GetLastModified(); m_version_id = resp.GetVersionId(); } @@ -425,6 +427,7 @@ void CopyResp::CopyFrom(const CompleteMultiUploadResp& resp) { m_location = resp.GetLocation(); m_bucket = resp.GetBucket(); m_key = resp.GetKey(); + SetEtag(resp.GetEtag()); } bool DeleteObjectsResp::ParseFromXmlString(const std::string& body) { diff --git a/src/util/file_util.cpp b/src/util/file_util.cpp index eeffb98..a3d5734 100644 --- a/src/util/file_util.cpp +++ b/src/util/file_util.cpp @@ -75,6 +75,7 @@ std::string FileUtil::GetDirectory(const std::string& path) { uint64_t FileUtil::GetFileCrc64(const std::string& file) { std::fstream f(file, std::ios::in | std::ios::binary); const static int buffer_size = 2048; + // NOCA:VariableLengthArrays(设计如此) char buffer[buffer_size]; uint64_t crc64 = 0; while (f.good()) { @@ -92,6 +93,7 @@ uint64_t FileUtil::GetFileCrc64(const std::string& file) { #if defined(_WIN32) uint64_t FileUtil::GetFileCrc64(const std::wstring& file) { std::fstream f(file, std::ios::in | std::ios::binary); + // NOCA:VariableLengthArrays(设计如此) const static int buffer_size = 2048; char buffer[buffer_size]; uint64_t crc64 = 0;