diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index a5c129e..f82b52e 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -35,19 +35,19 @@ add_executable(select_objec_demo ${select_objec_demo_src}) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) -target_link_libraries(cos_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(put_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(get_object_url_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(head_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(get_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(delete_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(put_get_object_acl_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(put_get_delete_object_tagging_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(restore_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(copy_move_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(multi_put_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(multi_get_object_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) -target_link_libraries(select_objec_demo cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(cos_demo cossdk ssl crypto ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(put_object_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(get_object_url_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(head_object_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(get_object_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(delete_object_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(put_get_object_acl_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(put_get_delete_object_tagging_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(restore_object_demo cossdk ssl crypto ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(copy_move_object_demo cossdk ssl crypto ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(multi_put_object_demo cossdk ssl crypto ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(multi_get_object_demo cossdk ssl crypto ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) +target_link_libraries(select_objec_demo ssl crypto cossdk ${POCO_LIBS} ${OPENSSL_LIBS} ${SYSTEM_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/include/ ${POCO_INCLUDE_DIR}) diff --git a/demo/object_op_demo/get_object_demo.cpp b/demo/object_op_demo/get_object_demo.cpp index aab9355..1bee864 100644 --- a/demo/object_op_demo/get_object_demo.cpp +++ b/demo/object_op_demo/get_object_demo.cpp @@ -8,6 +8,7 @@ #include "cos_api.h" #include "cos_sys_config.h" #include "util/auth_tool.h" +#include /** * 本样例演示了如何使用 COS C++ SDK 进行简单下载和列出 @@ -22,6 +23,22 @@ std::string region = "ap-guangzhou"; std::string bucket_name = "examplebucket-12500000000"; std::string tmp_token = "token"; +/** + * 本方法为 SSL_CTX 的回调方法,用户可以在此方法中配置 SSL_CTX 信息 + */ +int SslCtxCallback(void *ssl_ctx, void *data) { + std::cout << "ssl_ctx: " << ssl_ctx << " data: " << data << std::endl; + + SSL_CTX *ctx = (SSL_CTX *)ssl_ctx; + std::cout << "ssl_ctx in" << std::endl; + SSL_CTX_use_PrivateKey_file(ctx, "/data/cert/client.key", SSL_FILETYPE_PEM); + SSL_CTX_use_certificate_chain_file(ctx, "/data/cert/client.crt"); + std::cout << "ssl_ctx out" << std::endl; + + return 0; +} + + /* * 本方法包含调用是否正常的判断,和请求结果的输出 * 可通过本方法判断是否请求成功,并输出结果信息 @@ -82,6 +99,24 @@ void GetObjectByStreamDemo(qcloud_cos::CosAPI& cos) { std::cout << os.str() << std::endl; } +/** + * 使用 https 双向认证 + */ +void GetObjectByStreamDemoWithMutualAuthentication(qcloud_cos::CosAPI& cos) { + std::string object_name = "index.html"; + std::ostringstream os; + qcloud_cos::GetObjectByStreamReq req(bucket_name, object_name, os); + req.SetHttps(); + req.SetSSLCtxCallback(SslCtxCallback, nullptr); + qcloud_cos::GetObjectByStreamResp resp; + + qcloud_cos::CosResult result = cos.GetObject(req, &resp); + std::cout << "===================GetObjectResponse=====================" << std::endl; + PrintResult(result, resp); + std::cout << "=========================================================" << std::endl; + std::cout << os.str() << std::endl; +} + void GetBucketDemo(qcloud_cos::CosAPI& cos) { qcloud_cos::GetBucketReq req(bucket_name); // 设置列出的对象名以 prefix 为前缀 @@ -127,5 +162,6 @@ int main() { CosSysConfig::SetLogLevel((LOG_LEVEL)COS_LOG_ERR); GetObjectByFileDemo(cos); GetObjectByStreamDemo(cos); + // GetObjectByStreamDemoWithMutualAuthentication(cos); GetBucketDemo(cos); } \ No newline at end of file diff --git a/include/cos_defines.h b/include/cos_defines.h index 085115b..70432bc 100644 --- a/include/cos_defines.h +++ b/include/cos_defines.h @@ -6,12 +6,13 @@ #include #include +#include #include "util/log_util.h" namespace qcloud_cos { -#define COS_CPP_SDK_VERSON "v5.5.14" +#define COS_CPP_SDK_VERSON "v5.5.15" /// 路径分隔符 const char kPathDelimiter[] = "/"; @@ -39,6 +40,8 @@ const uint64_t kPartSize1M = 1 * 1024 * 1024; /// 分块大小5G const uint64_t kPartSize5G = (uint64_t)5 * 1024 * 1024 * 1024; +using SSLCtxCallback = std::function; + const bool COS_CHANGE_BACKUP_DOMAIN = true; typedef enum log_out_type { COS_LOG_NULL = 0, diff --git a/include/op/file_copy_task.h b/include/op/file_copy_task.h index b2a6837..2871d41 100644 --- a/include/op/file_copy_task.h +++ b/include/op/file_copy_task.h @@ -7,6 +7,7 @@ #include "Poco/Foundation.h" #include "Poco/Runnable.h" +#include "cos_defines.h" namespace qcloud_cos { @@ -35,6 +36,7 @@ class FileCopyTask : public Poco::Runnable { void SetVerifyCert(bool verify_cert); void SetCaLocation(const std::string& ca_location); + void SetSslCtxCb(SSLCtxCallback cb, void *data); std::string GetErrMsg() const { return m_err_msg; } @@ -58,6 +60,8 @@ class FileCopyTask : public Poco::Runnable { bool m_verify_cert; std::string m_ca_location; + SSLCtxCallback m_ssl_ctx_cb; + void *m_user_data; }; } // namespace qcloud_cos \ No newline at end of file diff --git a/include/op/file_download_task.h b/include/op/file_download_task.h index ec426be..6aa9493 100644 --- a/include/op/file_download_task.h +++ b/include/op/file_download_task.h @@ -28,7 +28,9 @@ class FileDownTask : public Poco::Runnable { uint64_t offset = 0, unsigned char* pbuf = NULL, const size_t data_len = 0, bool verify_cert = true, - const std::string& ca_lication = ""); + const std::string& ca_lication = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); ~FileDownTask() {} @@ -40,6 +42,7 @@ class FileDownTask : public Poco::Runnable { void SetVerifyCert(bool verify_cert); void SetCaLocation(const std::string& ca_location); + void SetSslCtxCb(SSLCtxCallback cb, void *data); std::string GetTaskResp(); @@ -72,6 +75,8 @@ class FileDownTask : public Poco::Runnable { bool m_verify_cert; std::string m_ca_location; + SSLCtxCallback m_ssl_ctx_cb; + void *m_user_data; SharedConfig m_config; }; diff --git a/include/op/file_upload_task.h b/include/op/file_upload_task.h index e622552..9853a62 100644 --- a/include/op/file_upload_task.h +++ b/include/op/file_upload_task.h @@ -16,7 +16,9 @@ class FileUploadTask : public Poco::Runnable { uint64_t recv_timeout_in_ms, unsigned char* pbuf = NULL, const size_t data_len = 0, bool verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); FileUploadTask(const std::string& full_url, const std::map& headers, @@ -24,7 +26,9 @@ class FileUploadTask : public Poco::Runnable { uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, const SharedTransferHandler& handler, bool verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); FileUploadTask(const std::string& full_url, const std::map& headers, @@ -32,7 +36,9 @@ class FileUploadTask : public Poco::Runnable { uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, unsigned char* pbuf = NULL, const size_t data_len = 0, bool verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); ~FileUploadTask() {} @@ -74,6 +80,7 @@ class FileUploadTask : public Poco::Runnable { void SetVerifyCert(bool verify_cert); void SetCaLocation(const std::string& ca_location); + void SetSslCtxCb(SSLCtxCallback cb, void *data); private: std::string m_full_url; @@ -95,6 +102,8 @@ class FileUploadTask : public Poco::Runnable { bool m_verify_cert; std::string m_ca_location; + SSLCtxCallback m_ssl_ctx_cb; + void *m_user_data; }; } // namespace qcloud_cos diff --git a/include/op/object_op.h b/include/op/object_op.h index 1bbbf10..c0117db 100644 --- a/include/op/object_op.h +++ b/include/op/object_op.h @@ -440,7 +440,8 @@ class ObjectOp : public BaseOp { const std::string& range, const std::map& headers, const std::map& params, - bool verify_cert,const std::string& ca_location, + bool verify_cert,const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data, FileCopyTask* task, bool sign_header_host); /// \brief 检查是否可以走断点下载 diff --git a/include/request/base_req.h b/include/request/base_req.h index 94e5e06..d8faa71 100644 --- a/include/request/base_req.h +++ b/include/request/base_req.h @@ -82,6 +82,13 @@ class BaseReq { void SetHttps() { m_is_https = true; } bool IsHttps() const { return m_is_https; } + void SetSSLCtxCallback(const SSLCtxCallback& ssl_ctx_cb, void *user_data) { + m_ssl_ctx_cb = ssl_ctx_cb; + m_user_data = user_data; + } + const SSLCtxCallback& GetSSLCtxCallback() const { return m_ssl_ctx_cb; } + void *GetSSLCtxCbData() const { return m_user_data; } + /// \brief set whether check content md5 each request, used for close range /// download check void SetCheckMD5(bool check_md5) { mb_check_md5 = check_md5; } @@ -128,6 +135,9 @@ class BaseReq { bool mb_verify_cert; // default is true bool m_sign_header_host; // 是否对header host进行签名 std::string m_ca_location; + + SSLCtxCallback m_ssl_ctx_cb; + void* m_user_data; }; } // namespace qcloud_cos diff --git a/include/request/object_req.h b/include/request/object_req.h index eee1552..4c05894 100644 --- a/include/request/object_req.h +++ b/include/request/object_req.h @@ -1855,7 +1855,7 @@ class PutDirectoryReq : public PutObjectReq { virtual ~PutDirectoryReq() {} }; -class MoveObjectReq { +class MoveObjectReq : public ObjectReq { public: MoveObjectReq(const std::string& bucket_name, const std::string& src_object_name, diff --git a/include/util/http_sender.h b/include/util/http_sender.h index dfa17b1..349aaa2 100644 --- a/include/util/http_sender.h +++ b/include/util/http_sender.h @@ -32,7 +32,9 @@ class HttpSender { std::string* resp_body, std::string* err_msg, bool is_check_md5 = false, bool is_verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); static int SendRequest(const SharedTransferHandler& handler, const std::string& http_method, @@ -46,7 +48,9 @@ class HttpSender { std::ostream& resp_stream, std::string* err_msg, bool is_check_md5 = false, bool is_verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); static int SendRequest(const SharedTransferHandler& handler, const std::string& http_method, @@ -59,7 +63,9 @@ class HttpSender { std::string* resp_body, std::string* err_msg, bool is_check_md5 = false, bool is_verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); static int SendRequest(const SharedTransferHandler& handler, const std::string& http_method, @@ -72,7 +78,9 @@ class HttpSender { std::ostream& resp_stream, std::string* err_msg, bool is_check_md5 = false, bool is_verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); static int SendRequest(const SharedTransferHandler& handler, const std::string& http_method, @@ -87,7 +95,9 @@ class HttpSender { std::string* err_msg, uint64_t* real_byte, bool is_check_md5 = false, bool is_verify_cert = true, - const std::string& ca_location = ""); + const std::string& ca_location = "", + SSLCtxCallback ssl_ctx_cb = nullptr, + void *user_data = nullptr); }; } // namespace qcloud_cos diff --git a/src/op/base_op.cpp b/src/op/base_op.cpp index b74478f..95b51f5 100644 --- a/src/op/base_op.cpp +++ b/src/op/base_op.cpp @@ -181,7 +181,8 @@ CosResult BaseOp::NormalAction( int http_code = HttpSender::SendRequest(nullptr, req.GetMethod(), dest_url, req_params, req_headers, req_body, req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers, - &resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation()); + &resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation(), + req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); if (http_code == -1) { result.SetErrorMsg(err_msg); return result; @@ -267,7 +268,8 @@ CosResult BaseOp::DownloadAction(const std::string& host, handler, req.GetMethod(), dest_url, req_params, req_headers, "", req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers, &xml_err_str, os, &err_msg, &real_byte, req.CheckMD5(), - req.GetVerifyCert(), req.GetCaLocation()); + req.GetVerifyCert(), req.GetCaLocation(), + req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); if (http_code == -1) { result.SetErrorMsg(err_msg); resp->ParseFromHeaders(resp_headers); @@ -358,7 +360,8 @@ CosResult BaseOp::UploadAction( int http_code = HttpSender::SendRequest( handler, req.GetMethod(), dest_url, req_params, req_headers, is, req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), &resp_headers, - &resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation()); + &resp_body, &err_msg, false, req.GetVerifyCert(), req.GetCaLocation(), + req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); if (http_code == -1) { result.SetErrorMsg(err_msg); return result; diff --git a/src/op/file_copy_task.cpp b/src/op/file_copy_task.cpp index efb38bf..801b930 100644 --- a/src/op/file_copy_task.cpp +++ b/src/op/file_copy_task.cpp @@ -15,7 +15,9 @@ FileCopyTask::FileCopyTask(const std::string& full_url, m_recv_timeout_in_ms(recv_timeout_in_ms), m_is_task_success(false), m_etag(""), - m_verify_cert(true) {} + m_verify_cert(true), + m_ssl_ctx_cb(nullptr), + m_user_data(nullptr) {} bool FileCopyTask::IsTaskSuccess() const { return m_is_task_success; } @@ -46,6 +48,11 @@ void FileCopyTask::SetCaLocation(const std::string& ca_location) { m_ca_location = ca_location; } +void FileCopyTask::SetSslCtxCb(SSLCtxCallback cb, void *data) { + m_ssl_ctx_cb = cb; + m_user_data = data; +} + void FileCopyTask::run() { m_is_task_success = false; CopyTask(); @@ -61,7 +68,7 @@ void FileCopyTask::CopyTask() { m_http_status = HttpSender::SendRequest(nullptr, "PUT", m_full_url, m_params, m_headers, "", m_conn_timeout_in_ms, m_recv_timeout_in_ms, &m_resp_headers, &m_resp, &m_err_msg, - false, m_verify_cert, m_ca_location); + false, m_verify_cert, m_ca_location, m_ssl_ctx_cb, m_user_data); if (m_http_status != 200) { SDK_LOG_ERR("FileUpload: url(%s) fail, httpcode:%d, resp: %s", diff --git a/src/op/file_download_task.cpp b/src/op/file_download_task.cpp index ab4a3b3..4274bb0 100644 --- a/src/op/file_download_task.cpp +++ b/src/op/file_download_task.cpp @@ -18,7 +18,9 @@ FileDownTask::FileDownTask(const std::string& full_url, uint64_t offset, unsigned char* pbuf, const size_t data_len, bool verify_cert, - const std::string& ca_lication) + const std::string& ca_lication, + SSLCtxCallback ssl_ctx_cb, + void *user_data) : m_full_url(full_url), m_headers(headers), m_params(params), @@ -32,7 +34,9 @@ FileDownTask::FileDownTask(const std::string& full_url, m_is_task_success(false), m_real_down_len(0), m_verify_cert(verify_cert), - m_ca_location(ca_lication) {} + m_ca_location(ca_lication), + m_ssl_ctx_cb(ssl_ctx_cb), + m_user_data(user_data) {} void FileDownTask::run() { m_resp = ""; @@ -55,6 +59,11 @@ void FileDownTask::SetCaLocation(const std::string& ca_location) { m_ca_location = ca_location; } +void FileDownTask::SetSslCtxCb(SSLCtxCallback cb, void *data) { + m_ssl_ctx_cb = cb; + m_user_data = data; +} + size_t FileDownTask::GetDownLoadLen() { return m_real_down_len; } bool FileDownTask::IsTaskSuccess() { return m_is_task_success; } @@ -92,7 +101,7 @@ void FileDownTask::DownTask() { m_http_status = HttpSender::SendRequest( m_handler, "GET", m_full_url, m_params, m_headers, "", m_conn_timeout_in_ms, m_recv_timeout_in_ms, &m_resp_headers, &m_resp, - &m_err_msg, false, m_verify_cert, m_ca_location); + &m_err_msg, false, m_verify_cert, m_ca_location, m_ssl_ctx_cb, m_user_data); //} //当实际长度小于请求的数据长度时httpcode为206 if (m_http_status != 200 && m_http_status != 206) { diff --git a/src/op/file_upload_task.cpp b/src/op/file_upload_task.cpp index c06ec1a..0ff1461 100644 --- a/src/op/file_upload_task.cpp +++ b/src/op/file_upload_task.cpp @@ -14,7 +14,9 @@ FileUploadTask::FileUploadTask(const std::string& full_url, uint64_t recv_timeout_in_ms, unsigned char* pbuf, const size_t data_len, bool verify_cert, - const std::string& ca_location) + const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, + void *user_data) : m_full_url(full_url), m_conn_timeout_in_ms(conn_timeout_in_ms), m_recv_timeout_in_ms(recv_timeout_in_ms), @@ -25,7 +27,9 @@ FileUploadTask::FileUploadTask(const std::string& full_url, m_is_resume(false), m_handler(NULL), m_verify_cert(verify_cert), - m_ca_location(ca_location) {} + m_ca_location(ca_location), + m_ssl_ctx_cb(ssl_ctx_cb), + m_user_data(user_data) {} FileUploadTask::FileUploadTask( const std::string& full_url, @@ -34,7 +38,9 @@ FileUploadTask::FileUploadTask( uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, const SharedTransferHandler& handler, bool verify_cert, - const std::string& ca_location) + const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, + void *user_data) : m_full_url(full_url), m_headers(headers), m_params(params), @@ -47,7 +53,9 @@ FileUploadTask::FileUploadTask( m_is_resume(false), m_handler(handler), m_verify_cert(verify_cert), - m_ca_location(ca_location) {} + m_ca_location(ca_location), + m_ssl_ctx_cb(ssl_ctx_cb), + m_user_data(user_data) {} FileUploadTask::FileUploadTask( const std::string& full_url, @@ -56,7 +64,9 @@ FileUploadTask::FileUploadTask( uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, unsigned char* pbuf, const size_t data_len, bool verify_cert, - const std::string& ca_location) + const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, + void *user_data) : m_full_url(full_url), m_headers(headers), m_params(params), @@ -69,7 +79,9 @@ FileUploadTask::FileUploadTask( m_is_resume(false), m_handler(NULL), m_verify_cert(verify_cert), - m_ca_location(ca_location) {} + m_ca_location(ca_location), + m_ssl_ctx_cb(ssl_ctx_cb), + m_user_data(user_data) {} void FileUploadTask::run() { m_resp = ""; @@ -132,6 +144,11 @@ void FileUploadTask::SetCaLocation(const std::string& ca_location) { m_ca_location = ca_location; } +void FileUploadTask::SetSslCtxCb(SSLCtxCallback cb, void *data) { + m_ssl_ctx_cb = cb; + m_user_data = data; +} + void FileUploadTask::UploadTask() { std::string body((const char*)m_data_buf_ptr, m_data_len); // 计算上传的md5 @@ -161,7 +178,7 @@ void FileUploadTask::UploadTask() { m_http_status = HttpSender::SendRequest( m_handler, "PUT", m_full_url, m_params, m_headers, body, m_conn_timeout_in_ms, m_recv_timeout_in_ms, &m_resp_headers, &m_resp, - &m_err_msg, false, m_verify_cert, m_ca_location); + &m_err_msg, false, m_verify_cert, m_ca_location, m_ssl_ctx_cb, m_user_data); //} if (m_http_status != 200) { diff --git a/src/op/object_op.cpp b/src/op/object_op.cpp index 436496e..1033680 100644 --- a/src/op/object_op.cpp +++ b/src/op/object_op.cpp @@ -69,7 +69,9 @@ std::string ObjectOp::GetResumableUploadID(const PutObjectByFileReq& originReq, req.SetPrefix(object_name); if (originReq.IsHttps()) { req.SetHttps(); + req.SetVerifyCert(originReq.GetVerifyCert()); req.SetCaLocation(originReq.GetCaLocation()); + req.SetSSLCtxCallback(originReq.GetSSLCtxCallback(), originReq.GetSSLCtxCbData()); } ListMultipartUploadResp resp; @@ -199,7 +201,9 @@ bool ObjectOp::CheckUploadPart(const PutObjectByFileReq& req, std::string marker = StringUtil::IntToString(part_num_marker); if(req.IsHttps()){ list_req.SetHttps(); + list_req.SetVerifyCert(req.GetVerifyCert()); list_req.SetCaLocation(req.GetCaLocation()); + list_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); } list_req.SetPartNumberMarker(marker); CosResult result = ListParts(list_req, &resp); @@ -653,7 +657,9 @@ CosResult ObjectOp::MultiUploadObject(const PutObjectByFileReq& req, InitMultiUploadResp init_resp; if (req.IsHttps()) { init_req.SetHttps(); + init_req.SetVerifyCert(req.GetVerifyCert()); init_req.SetCaLocation(req.GetCaLocation()); + init_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); } init_req.AddHeaders(req.GetHeaders()); init_req.SetConnTimeoutInms(req.GetConnTimeoutInms()); @@ -742,6 +748,8 @@ CosResult ObjectOp::MultiUploadObject(const PutObjectByFileReq& req, if (req.IsHttps()) { comp_req.SetHttps(); comp_req.SetCaLocation(req.GetCaLocation()); + comp_req.SetVerifyCert(req.GetVerifyCert()); + comp_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); } comp_result = CompleteMultiUpload(comp_req, &comp_resp, change_backup_domain); @@ -1053,6 +1061,12 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ SDK_LOG_INFO("Same region[%s], use put object copy.", src_region.c_str()); PutObjectCopyReq put_copy_req(req.GetBucketName(), req.GetObjectName()); put_copy_req.AddHeaders(req.GetHeaders()); + if (req.IsHttps()) { + put_copy_req.SetHttps(); + put_copy_req.SetVerifyCert(req.GetVerifyCert()); + put_copy_req.SetCaLocation(req.GetCaLocation()); + put_copy_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } PutObjectCopyResp put_copy_resp; put_copy_req.SetConnTimeoutInms(req.GetConnTimeoutInms()); put_copy_req.SetRecvTimeoutInms(req.GetRecvTimeoutInms()); @@ -1090,6 +1104,12 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ file_size); PutObjectCopyReq put_copy_req(req.GetBucketName(), req.GetObjectName()); put_copy_req.AddHeaders(req.GetHeaders()); + if (req.IsHttps()) { + put_copy_req.SetHttps(); + put_copy_req.SetVerifyCert(req.GetVerifyCert()); + put_copy_req.SetCaLocation(req.GetCaLocation()); + put_copy_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } PutObjectCopyResp put_copy_resp; put_copy_req.SetConnTimeoutInms(req.GetConnTimeoutInms()); put_copy_req.SetRecvTimeoutInms(req.GetRecvTimeoutInms()); @@ -1108,6 +1128,12 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ init_req.SetConnTimeoutInms(req.GetConnTimeoutInms()); init_req.SetRecvTimeoutInms(req.GetRecvTimeoutInms()); init_req.AddHeaders(req.GetInitHeader()); + if (req.IsHttps()) { + init_req.SetHttps(); + init_req.SetVerifyCert(req.GetVerifyCert()); + init_req.SetCaLocation(req.GetCaLocation()); + init_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } result = InitMultiUpload(init_req, &init_resp, change_backup_domain); if (!result.IsSucc()) { @@ -1161,6 +1187,7 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ FillCopyTask(upload_id, host, path, part_number, range, part_copy_headers, req.GetParams(), req.GetVerifyCert(), req.GetCaLocation(), + req.GetSSLCtxCallback(), req.GetSSLCtxCbData(), ptask, req.SignHeaderHost()); tp.start(*ptask); part_numbers.push_back(part_number); @@ -1190,6 +1217,12 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ AbortMultiUploadReq abort_req(req.GetBucketName(), req.GetObjectName(), upload_id); AbortMultiUploadResp abort_resp; + if (req.IsHttps()) { + abort_req.SetHttps(); + abort_req.SetVerifyCert(req.GetVerifyCert()); + abort_req.SetCaLocation(req.GetCaLocation()); + abort_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } CosResult abort_result = AbortMultiUpload(abort_req, &abort_resp, change_backup_domain); if (!abort_result.IsSucc()) { @@ -1228,6 +1261,12 @@ CosResult ObjectOp::Copy(const CopyReq& req, CopyResp* resp, bool change_backup_ comp_req.SetEtags(etags); comp_req.SetPartNumbers(part_numbers); + if (req.IsHttps()) { + comp_req.SetHttps(); + comp_req.SetVerifyCert(req.GetVerifyCert()); + comp_req.SetCaLocation(req.GetCaLocation()); + comp_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } result = CompleteMultiUpload(comp_req, &comp_resp, change_backup_domain); if (result.IsSucc()) { @@ -1292,6 +1331,12 @@ ObjectOp::MultiThreadDownload(const GetObjectByFileReq& req, CosResult head_result; // 1. 调用HeadObject获取文件长度 HeadObjectReq head_req(req.GetBucketName(), req.GetObjectName()); + if (req.IsHttps()) { + head_req.SetHttps(); + head_req.SetVerifyCert(req.GetVerifyCert()); + head_req.SetCaLocation(req.GetCaLocation()); + head_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } HeadObjectResp head_resp; head_result = HeadObject(head_req, &head_resp, change_backup_domain); if (!head_result.IsSucc()) { @@ -1429,6 +1474,7 @@ ObjectOp::MultiThreadDownload(const GetObjectByFileReq& req, ptask->SetDownParams(file_content_buf[task_index], part_len, offset); ptask->SetVerifyCert(req.GetVerifyCert()); ptask->SetCaLocation(req.GetCaLocation()); + ptask->SetSslCtxCb(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); tp.start(*ptask); vec_offset[task_index] = offset; offset += part_len; @@ -1624,7 +1670,8 @@ CosResult ObjectOp::MultiThreadUpload( pptaskArr[i] = new FileUploadTask(dest_url, headers, params, req.GetConnTimeoutInms(), req.GetRecvTimeoutInms(), handler, - req.GetVerifyCert(), req.GetCaLocation()); + req.GetVerifyCert(), req.GetCaLocation(), + req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); } SDK_LOG_DBG("upload data, url=%s, poolsize=%u, part_size=%" PRIu64 @@ -1801,6 +1848,7 @@ void ObjectOp::FillCopyTask(const std::string& upload_id, const std::map& headers, const std::map& params, bool verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data, FileCopyTask* task_ptr,bool sign_header_host) { std::map req_params = params; req_params.insert(std::make_pair("uploadId", upload_id)); @@ -1832,6 +1880,7 @@ void ObjectOp::FillCopyTask(const std::string& upload_id, task_ptr->SetHeaders(req_headers); task_ptr->SetVerifyCert(verify_cert); task_ptr->SetCaLocation(ca_location); + task_ptr->SetSslCtxCb(ssl_ctx_cb, user_data); } std::string ObjectOp::GeneratePresignedUrl(const GeneratePresignedUrlReq& req) { @@ -2055,6 +2104,12 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, CosResult head_result; // 1. 调用HeadObject获取文件长度 HeadObjectReq head_req(req.GetBucketName(), req.GetObjectName()); + if (req.IsHttps()) { + head_req.SetHttps(); + head_req.SetVerifyCert(req.GetVerifyCert()); + head_req.SetCaLocation(req.GetCaLocation()); + head_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } HeadObjectResp head_resp; head_result = HeadObject(head_req, &head_resp, change_backup_domain); if (!head_result.IsSucc()) { @@ -2242,6 +2297,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, left_size = file_size - offset; part_len = slice_size < left_size ? slice_size : left_size; ptask->SetDownParams(file_content_buf[task_index], part_len, offset); + ptask->SetVerifyCert(req.GetVerifyCert()); + ptask->SetCaLocation(req.GetCaLocation()); + ptask->SetSslCtxCb(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); tp.start(*ptask); vec_offset[task_index] = offset; offset += part_len; @@ -2494,6 +2552,12 @@ CosResult ObjectOp::MoveObject(const MoveObjectReq& req, bool change_backup_doma std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), req.GetBucketName(),change_backup_domain); copy_req.SetXCosCopySource(host + "/" + req.GetSrcObjectName()); + if (req.IsHttps()) { + copy_req.SetHttps(); + copy_req.SetVerifyCert(req.GetVerifyCert()); + copy_req.SetCaLocation(req.GetCaLocation()); + copy_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } CopyResp copy_resp; // copy to dst object @@ -2507,6 +2571,12 @@ CosResult ObjectOp::MoveObject(const MoveObjectReq& req, bool change_backup_doma // delete src object CosResult del_result; DeleteObjectReq del_req(req.GetBucketName(), req.GetSrcObjectName()); + if (req.IsHttps()) { + del_req.SetHttps(); + del_req.SetVerifyCert(req.GetVerifyCert()); + del_req.SetCaLocation(req.GetCaLocation()); + del_req.SetSSLCtxCallback(req.GetSSLCtxCallback(), req.GetSSLCtxCbData()); + } DeleteObjectResp del_resp; del_result = DeleteObject(del_req, &del_resp, change_backup_domain); if (!del_result.IsSucc()) { diff --git a/src/request/base_req.cpp b/src/request/base_req.cpp index 5ddf407..88c55b3 100644 --- a/src/request/base_req.cpp +++ b/src/request/base_req.cpp @@ -15,7 +15,8 @@ namespace qcloud_cos { BaseReq::BaseReq() : m_is_https(false), mb_check_md5(true), - mb_check_crc64(false), mb_verify_cert(true), m_sign_header_host(true) { + mb_check_crc64(false), mb_verify_cert(true), m_sign_header_host(true), + m_ssl_ctx_cb(nullptr), m_user_data(nullptr) { m_recv_timeout_in_ms = CosSysConfig::GetRecvTimeoutInms(); m_conn_timeout_in_ms = CosSysConfig::GetConnTimeoutInms(); AddHeader("User-Agent", COS_CPP_SDK_HTTP_HEADER_USER_AGENT); diff --git a/src/util/http_sender.cpp b/src/util/http_sender.cpp index c715508..e856e2c 100644 --- a/src/util/http_sender.cpp +++ b/src/util/http_sender.cpp @@ -38,13 +38,14 @@ int HttpSender::SendRequest( uint64_t recv_timeout_in_ms, std::map* resp_headers, std::string* resp_body, std::string* err_msg, bool is_check_md5, - bool is_verify_cert, const std::string& ca_location) { + bool is_verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data) { std::istringstream is(req_body); std::ostringstream oss; int ret = SendRequest(handler, http_method, url_str, req_params, req_headers, is, conn_timeout_in_ms, recv_timeout_in_ms, resp_headers, oss, err_msg, is_check_md5, - is_verify_cert, ca_location); + is_verify_cert, ca_location, ssl_ctx_cb, user_data); *resp_body = oss.str(); return ret; } @@ -58,12 +59,13 @@ int HttpSender::SendRequest( uint64_t recv_timeout_in_ms, std::map* resp_headers, std::ostream& resp_stream, std::string* err_msg, bool is_check_md5, - bool is_verify_cert, const std::string& ca_location) { + bool is_verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data) { std::istringstream is(req_body); int ret = SendRequest(handler, http_method, url_str, req_params, req_headers, is, conn_timeout_in_ms, recv_timeout_in_ms, resp_headers, resp_stream, err_msg, is_check_md5, - is_verify_cert, ca_location); + is_verify_cert, ca_location, ssl_ctx_cb, user_data); return ret; } @@ -75,12 +77,13 @@ int HttpSender::SendRequest( uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, std::map* resp_headers, std::string* resp_body, std::string* err_msg, bool is_check_md5, - bool is_verify_cert, const std::string& ca_location) { + bool is_verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data) { std::ostringstream oss; int ret = SendRequest(handler, http_method, url_str, req_params, req_headers, is, conn_timeout_in_ms, recv_timeout_in_ms, resp_headers, oss, err_msg, is_check_md5, - is_verify_cert, ca_location); + is_verify_cert, ca_location, ssl_ctx_cb, user_data); *resp_body = oss.str(); return ret; } @@ -93,7 +96,8 @@ int HttpSender::SendRequest( uint64_t conn_timeout_in_ms, uint64_t recv_timeout_in_ms, std::map* resp_headers, std::ostream& resp_stream, std::string* err_msg, bool is_check_md5, - bool is_verify_cert, const std::string& ca_location) { + bool is_verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data) { Poco::Net::HTTPResponse res; try { SDK_LOG_INFO("send request to [%s]", url_str.c_str()); @@ -112,6 +116,13 @@ int HttpSender::SendRequest( new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", ca_location, verify_mode, 9, load_default_ca, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + if (ssl_ctx_cb) { + int ret = ssl_ctx_cb(context->sslContext(), user_data); + if (ret != 0) { + *err_msg = "SSL_Ctx Callback Exception Code: " + std::to_string(ret); + return -1; + } + } session.reset(new Poco::Net::HTTPSClientSession(url.getHost(), url.getPort(), context)); } else { @@ -313,7 +324,8 @@ int HttpSender::SendRequest( uint64_t recv_timeout_in_ms, std::map* resp_headers, std::string* xml_err_str, std::ostream& resp_stream, std::string* err_msg, uint64_t* real_byte, - bool is_check_md5, bool is_verify_cert, const std::string& ca_location) { + bool is_check_md5, bool is_verify_cert, const std::string& ca_location, + SSLCtxCallback ssl_ctx_cb, void *user_data) { Poco::Net::HTTPResponse res; try { SDK_LOG_INFO("send request to [%s]", url_str.c_str()); @@ -333,6 +345,13 @@ int HttpSender::SendRequest( new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", ca_location, verify_mode, 9, load_default_ca, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + if (ssl_ctx_cb) { + int ret = ssl_ctx_cb(context->sslContext(), user_data); + if (ret != 0) { + *err_msg = "SSL_Ctx Callback Exception Code: " + std::to_string(ret); + return -1; + } + } session.reset(new Poco::Net::HTTPSClientSession(url.getHost(), url.getPort(), context)); } else {