1616#else
1717#include < unistd.h>
1818#endif
19+ #ifdef USE_OPENSSL_MD5
20+ #include < openssl/md5.h>
21+ #endif
1922
2023#include " Poco/DigestStream.h"
2124#include " Poco/DirectoryIterator.h"
@@ -854,9 +857,10 @@ CosResult ObjectOp::UploadObjectResumableSingleThreadSync(const PutObjectByFileR
854857 std::vector<uint64_t > part_numbers;
855858
856859 PutObjectByFileResp upload_resp;
860+ uint64_t crc64_origin = 0 ;
857861 CosResult upload_result =
858862 SingleThreadUpload (req, resume_uploadid, already_exist_parts, resume_flag,
859- &etags, &part_numbers, &upload_resp);
863+ &etags, &part_numbers, &upload_resp, crc64_origin );
860864
861865 // Notice the cancel way not need to abort the uploadid
862866 if (!upload_result.IsSucc ()) {
@@ -885,16 +889,6 @@ CosResult ObjectOp::UploadObjectResumableSingleThreadSync(const PutObjectByFileR
885889 // check crc64 if needed
886890 if (req.CheckCRC64 () && comp_result.IsSucc () &&
887891 !comp_resp.GetXCosHashCrc64Ecma ().empty ()) {
888- uint64_t crc64_origin = 0 ;
889- #if defined(_WIN32)
890- if (req.IsWideCharPath ()) {
891- crc64_origin = FileUtil::GetFileCrc64 (req.GetWideCharLocalFilePath ());
892- } else {
893- crc64_origin = FileUtil::GetFileCrc64 (req.GetLocalFilePath ());
894- }
895- #else
896- crc64_origin = FileUtil::GetFileCrc64 (req.GetLocalFilePath ());
897- #endif
898892 uint64_t crc64_server_resp =
899893 StringUtil::StringToUint64 (comp_resp.GetXCosHashCrc64Ecma ());
900894 if (crc64_server_resp != crc64_origin) {
@@ -1915,7 +1909,8 @@ CosResult ObjectOp::SingleThreadUpload(
19151909 const PutObjectByFileReq& req, const std::string& upload_id,
19161910 const std::vector<std::string>& already_exist_parts, bool resume_flag,
19171911 std::vector<std::string>* etags_ptr,
1918- std::vector<uint64_t >* part_numbers_ptr, PutObjectByFileResp* resp) {
1912+ std::vector<uint64_t >* part_numbers_ptr, PutObjectByFileResp* resp,
1913+ uint64_t & crc64) {
19191914 CosResult result;
19201915 std::string path = " /" + req.GetObjectName ();
19211916 std::string host = CosSysConfig::GetHost (GetAppId (), m_config->GetRegion (),
@@ -1976,6 +1971,7 @@ CosResult ObjectOp::SingleThreadUpload(
19761971 SDK_LOG_DBG (" upload data, part_size=%" PRIu64
19771972 " , file_size=%" PRIu64, part_size, file_size);
19781973
1974+ crc64 = 0 ;
19791975 // 3. 单线程upload
19801976 {
19811977 uint64_t part_number = 1 ;
@@ -1990,6 +1986,10 @@ CosResult ObjectOp::SingleThreadUpload(
19901986 " , offset=%" PRIu64 " , len=%" PRIu64,
19911987 part_number, file_size, offset, read_len);
19921988
1989+ // 提前计算整个文件的crc64,用于整个合并分块完成后做crc64校验
1990+ crc64 = CRC64::CalcCRC (crc64, static_cast <void *>(file_content_buf),
1991+ static_cast <size_t >(read_len));
1992+
19931993 // Check the resume
19941994
19951995 if (resume_flag && !already_exist_parts[part_number].empty ()) {
@@ -2013,6 +2013,15 @@ CosResult ObjectOp::SingleThreadUpload(
20132013 if (req.GetHeader (" x-cos-traffic-limit" ) != " " ) {
20142014 upload_part_req.SetTrafficLimit (req.GetHeader (" x-cos-traffic-limit" ));
20152015 }
2016+
2017+ #ifdef USE_OPENSSL_MD5
2018+ // 提前计算Content-MD5
2019+ unsigned char digest[MD5_DIGEST_LENGTH];
2020+ MD5 ((const unsigned char *)file_content_buf, read_len, digest);
2021+ std::string digest_str ((const char *)digest, MD5_DIGEST_LENGTH);
2022+ upload_part_req.AddHeader (" Content-MD5" , CodecUtil::Base64Encode (digest_str));
2023+ #endif
2024+
20162025 qcloud_cos::UploadPartDataResp upload_part_resp;
20172026 qcloud_cos::CosResult upload_part_result = UploadPartData (upload_part_req, &upload_part_resp);
20182027
0 commit comments