From 50696afc2e20905c09ab53c99ce75744127d30d2 Mon Sep 17 00:00:00 2001 From: "gan.wu" Date: Tue, 13 Aug 2024 11:51:47 +0800 Subject: [PATCH] =?UTF-8?q?[Feature][#13]=20=E5=88=86=E7=89=87=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=B8=80=E6=AC=A1=E4=B8=8A=E4=BC=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=9A=84=E4=B8=80=E6=AE=B5buffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ucloud/api/mput.cpp | 93 ++++++++++++++++++++++- ucloud/include/ufile-cppsdk/config.h | 2 +- ucloud/include/ufile-cppsdk/mput.h | 9 +++ ucloud/include/ufile-cppsdk/stream_util.h | 10 +++ 4 files changed, 111 insertions(+), 3 deletions(-) diff --git a/ucloud/api/mput.cpp b/ucloud/api/mput.cpp index ca01df9..9cec5f1 100644 --- a/ucloud/api/mput.cpp +++ b/ucloud/api/mput.cpp @@ -30,8 +30,12 @@ UFileMput::UFileMput() UFileMput::~UFileMput() { - if (m_file_stream && m_file_stream->is_open()) - m_file_stream->close(); + if (m_file_stream) { + if (m_file_stream->is_open()) { + m_file_stream->close(); + } + delete m_file_stream; + } } void UFileMput::SetResource(const std::string &bucket, const std::string &key) { @@ -144,6 +148,12 @@ int UFileMput::MUpload(ssize_t blk_idx) { if (ret) return ret; + if (!m_is) { + UFILE_SET_ERROR2(ERR_CPPSDK_INVALID_PARAM, + "stream has not been set up yet"); + return ERR_CPPSDK_INVALID_PARAM; + } + if (blk_idx != -1) m_blk_idx = blk_idx; @@ -226,6 +236,85 @@ int UFileMput::MUpload(ssize_t blk_idx) { return ret; } +int UFileMput::MUpload(ssize_t blk_idx, const char *data, size_t len) { + int64_t ret = InitGlobalConfig(); + if (ret) + return ret; + + m_blk_idx = blk_idx; + + if (m_mimetype == "") { + ret = MimeType(m_filename, m_mimetype); + if (ret) + return ret; + } + + UCloudStreamBuf sbuf(data, len); + std::istream iss(&sbuf); + if (!iss) { + UFILE_SET_ERROR(ERR_CPPSDK_FILE_READ); + return ERR_CPPSDK_FILE_READ; + } + + //开始上传数据 + std::string signature(""); + //构建 HTTP 头部 + m_http->Reset(); + m_http->SetVerb("PUT"); + m_http->AddHeader("Content-Type", m_mimetype); + m_http->AddHeader("Content-Length", SIZET2STR(len)); + m_http->AddHeader("User-Agent", USERAGENT); + m_http->SetURL(MUploadURL()); + + //使用 HTTP 信息构建签名 + UFileDigest digestor; + ret = digestor.SignWithRequest(m_http, HEAD_FIELD_CHECK, m_bucket, m_key, "", + signature); + if (ret) { + return ret; + } + m_http->AddHeader("Authorization", digestor.Token(signature)); + + //设置输出 + std::ostringstream oss, hss; + UCloudOStream data_stream(&oss); + UCloudOStream header_stream(&hss); + UCloudHTTPReadParam rp = + {f : NULL, is : iss, fsize : len, need_total_n : len}; + UCloudHTTPWriteParam wp = {f : NULL, os : &data_stream}; + UCloudHTTPHeaderParam hp = {f : NULL, os : &header_stream}; + ret = m_http->RoundTrip(&rp, &wp, &hp); + if (ret) { + UFILE_SET_ERROR2(ERR_CPPSDK_SEND_HTTP, UFILE_LAST_ERRMSG()); + return ERR_CPPSDK_SEND_HTTP; + } + + //解析回应 + long code = 200; + ret = m_http->ResponseCode(&code); + if (ret) { + UFILE_SET_ERROR(ERR_CPPSDK_CURL); + return ERR_CPPSDK_CURL; + } + + std::string errmsg; + if (code != 200) { + int parse_ret = UFileErrorRsp(oss.str().c_str(), &ret, errmsg); + if (parse_ret) { + UFILE_SET_ERROR(ERR_CPPSDK_CLIENT_INTERNAL); + return ERR_CPPSDK_CLIENT_INTERNAL; + } + UFILE_SET_ERROR2(ret, errmsg); + } else { + ret = ParseMuploadResult(oss.str(), hss.str()); + if (ret) { + return ret; + } + m_uploaded_size += len; + } + return ret; +} + int UFileMput::MUploadCopyPart(ssize_t blk_idx, std::string src_bucket_name, std::string src_object, size_t offset, size_t length, std::string mimetype) { diff --git a/ucloud/include/ufile-cppsdk/config.h b/ucloud/include/ufile-cppsdk/config.h index 46baa36..a937492 100644 --- a/ucloud/include/ufile-cppsdk/config.h +++ b/ucloud/include/ufile-cppsdk/config.h @@ -29,7 +29,7 @@ extern std::string UCLOUD_HOST_SUFFIX; int InitGlobalConfig(); -#define USERAGENT ("UFile C++SDK/1.1.1") +#define USERAGENT ("UFile C++SDK/1.1.2") /* * 动态修改配置 diff --git a/ucloud/include/ufile-cppsdk/mput.h b/ucloud/include/ufile-cppsdk/mput.h index d188f2b..0a79fab 100644 --- a/ucloud/include/ufile-cppsdk/mput.h +++ b/ucloud/include/ufile-cppsdk/mput.h @@ -63,6 +63,15 @@ class UFileMput : public APIBase { */ int MUpload(ssize_t blk_idx = -1); + /* + * @brief: 上传分片 + * @blk_idx: 分片编号 + * @data: 要上传的分片数据 + * @len: 分片数据的长度 + * @return: 0=成功,非0=失败 + */ + int MUpload(ssize_t blk_idx, const char *data, size_t len); + /* * @brief: copy文件分片 * @blk_idx: 分片编号 diff --git a/ucloud/include/ufile-cppsdk/stream_util.h b/ucloud/include/ufile-cppsdk/stream_util.h index c4435d3..113c649 100644 --- a/ucloud/include/ufile-cppsdk/stream_util.h +++ b/ucloud/include/ufile-cppsdk/stream_util.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace ucloud { namespace cppsdk { @@ -123,6 +124,15 @@ class MultiWriteStream : public UCloudOStream { std::vector m_osv; }; +class UCloudStreamBuf : public std::streambuf { +public: + UCloudStreamBuf(const char *data, size_t size) { + char *base = const_cast(data); + // 设置左右边界以及读指针位置 + setg(base, base, base + size); + } +}; + } // namespace utils } // namespace cppsdk } // namespace ucloud