Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ namespace OSS
void addResponseHeaders(RequestResponseHeader header, const std::string& value);
void addParameter(const std::string& key, const std::string& value);
MetaData& UserMetaData();
void setUnencodedSlash(bool value);
private:
friend class OssClientImpl;
std::string bucket_;
std::string key_;
Http::Method method_;
ObjectMetaData metaData_;
ParameterCollection parameters_;
bool unencodedSlash_;
};
}
}
9 changes: 8 additions & 1 deletion sdk/src/OssClientImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1313,9 +1313,16 @@ StringOutcome OssClientImpl::GeneratePresignedUrl(const GeneratePresignedUrlRequ
parameters["OSSAccessKeyId"] = credentials.AccessKeyId();
parameters["Signature"] = signature;

//host
std::stringstream ss;
ss << CombineHostString(endpoint_, request.bucket_, configuration().isCname);
ss << CombinePathString(endpoint_, request.bucket_, request.key_);
//path
auto path = CombinePathString(endpoint_, request.bucket_, request.key_);
if (request.unencodedSlash_) {
StringReplace(path, "%2F", "/");
}
ss << path;
//query
ss << "?";
ss << CombineQueryString(parameters);

Expand Down
1 change: 1 addition & 0 deletions sdk/src/client/ClientConfiguration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ bool DefaultRetryStrategy::shouldRetry(const Error & error, long attemptedRetrie
case (ERROR_CURL_BASE + 52): //CURLE_GOT_NOTHING
case (ERROR_CURL_BASE + 55): //CURLE_SEND_ERROR
case (ERROR_CURL_BASE + 56): //CURLE_RECV_ERROR
case (ERROR_CURL_BASE + 65): //CURLE_SEND_FAIL_REWIND
return true;
default:
break;
Expand Down
8 changes: 7 additions & 1 deletion sdk/src/model/GeneratePresignedUrlRequest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ GeneratePresignedUrlRequest::GeneratePresignedUrlRequest(const std::string &buck
GeneratePresignedUrlRequest::GeneratePresignedUrlRequest(const std::string &bucket, const std::string &key, Http::Method method):
bucket_(bucket),
key_(key),
method_(method)
method_(method),
unencodedSlash_(false)
{
//defalt 15 min
std::time_t t = std::time(nullptr) + 15*60;
Expand Down Expand Up @@ -102,3 +103,8 @@ MetaData &GeneratePresignedUrlRequest::UserMetaData()
{
return metaData_.UserMetaData();
}

void GeneratePresignedUrlRequest::setUnencodedSlash(bool value)
{
unencodedSlash_ = value;
}
18 changes: 15 additions & 3 deletions sdk/src/resumable/ResumableDownloader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@

using namespace AlibabaCloud::OSS;

struct DownloaderTransferState {
int64_t transfered;
void *userData;
};

GetObjectOutcome ResumableDownloader::Download()
{
OssError err;
Expand Down Expand Up @@ -79,9 +84,12 @@ GetObjectOutcome ResumableDownloader::Download()
getObjectReq.setRange(start, end);
getObjectReq.setFlags(getObjectReq.Flags() | REQUEST_FLAG_CHECK_CRC64 | REQUEST_FLAG_SAVE_CLIENT_CRC64);

DownloaderTransferState transferState;
auto process = request_.TransferProgress();
if (process.Handler) {
TransferProgress uploadPartProcess = { DownloadPartProcessCallback, (void *)this };
transferState.transfered = 0;
transferState.userData = (void *)this;
TransferProgress uploadPartProcess = { DownloadPartProcessCallback, (void *)&transferState };
getObjectReq.setTransferProgress(uploadPartProcess);
}
if (request_.RequestPayer() == RequestPayer::Requester) {
Expand Down Expand Up @@ -468,10 +476,14 @@ void ResumableDownloader::initRecord()

void ResumableDownloader::DownloadPartProcessCallback(size_t increment, int64_t transfered, int64_t total, void *userData)
{
UNUSED_PARAM(transfered);
UNUSED_PARAM(total);
auto transferState = (DownloaderTransferState *)userData;
auto downloader = (ResumableDownloader*)transferState->userData;
auto inc = transfered - transferState->transfered;
transferState->transfered = std::max(transfered, transferState->transfered);
inc = std::max(inc, static_cast<int64_t>(0));
increment = static_cast<size_t>(inc);

auto downloader = (ResumableDownloader*)userData;
std::lock_guard<std::mutex> lck(downloader->lock_);
downloader->consumedSize_ += increment;

Expand Down
17 changes: 14 additions & 3 deletions sdk/src/resumable/ResumableUploader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@

using namespace AlibabaCloud::OSS;

struct UploaderTransferState {
int64_t transfered;
void *userData;
};

ResumableUploader::ResumableUploader(const UploadObjectRequest& request, const OssClientImpl *client) :
ResumableBaseWorker(request.ObjectSize(), request.PartSize()),
Expand Down Expand Up @@ -101,9 +105,12 @@ PutObjectOutcome ResumableUploader::Upload()
UploadPartRequest uploadPartRequest(request_.Bucket(), request_.Key(), part.PartNumber(), uploadID_, content);
uploadPartRequest.setContentLength(length);

UploaderTransferState transferState;
auto process = request_.TransferProgress();
if (process.Handler) {
TransferProgress uploadPartProcess = { UploadPartProcessCallback, (void *)this };
transferState.transfered = 0;
transferState.userData = (void *)this;
TransferProgress uploadPartProcess = { UploadPartProcessCallback, (void *)&transferState };
uploadPartRequest.setTransferProgress(uploadPartProcess);
}
if (request_.RequestPayer() == RequestPayer::Requester) {
Expand Down Expand Up @@ -409,10 +416,14 @@ void ResumableUploader::dumpRecordInfo(AlibabaCloud::OSS::Json::Value& root)

void ResumableUploader::UploadPartProcessCallback(size_t increment, int64_t transfered, int64_t total, void *userData)
{
UNUSED_PARAM(transfered);
UNUSED_PARAM(total);
auto transferState = (UploaderTransferState *)userData;
auto uploader = (ResumableUploader*)transferState->userData;
auto inc = transfered - transferState->transfered;
transferState->transfered = std::max(transfered, transferState->transfered);
inc = std::max(inc, static_cast<int64_t>(0));
increment = static_cast<size_t>(inc);

auto uploader = (ResumableUploader*)userData;
std::lock_guard<std::mutex> lck(uploader->lock_);
uploader->consumedSize_ += increment;

Expand Down
4 changes: 3 additions & 1 deletion test/src/MultipartUpload/ResumableObjectTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ class ResumableObjectTest : public::testing::Test {
EXPECT_EQ(CreateDirectory(checkpointDir), true);
EXPECT_EQ(IsDirectoryExist(checkpointDir), true);

std::cout << "this ptr:" << this << std::endl;
TransferProgress progressCallback = { ProgressCallback, this };
UploadObjectRequest request(BucketName, key, tmpFile, checkpointDir, 102400, 1);
request.setTransferProgress(progressCallback);
Expand Down Expand Up @@ -1325,6 +1326,7 @@ class ResumableObjectTest : public::testing::Test {
EXPECT_EQ(putObjectOutcome.isSuccess(), true);
EXPECT_EQ(Client->DoesObjectExist(BucketName, sourceKey), true);

std::cout << "this ptr:" << this << std::endl;
TransferProgress progressCallback = { ProgressCallback, this };
DownloadObjectRequest request(BucketName, sourceKey, targetKey);
request.setTransferProgress(progressCallback);
Expand Down Expand Up @@ -2354,7 +2356,7 @@ class ResumableObjectTest : public::testing::Test {
std::string checkpointDir = TestUtils::GetTargetFileName("checkpoint");
EXPECT_EQ(CreateDirectory(checkpointDir), true);
EXPECT_EQ(IsDirectoryExist(checkpointDir), true);

std::cout << "this ptr:" << this << std::endl;
TransferProgress progressCallback = { ProgressCallback, this };
UploadObjectRequest request(BucketName, key, tmpFile, checkpointDir, 102400, 1);
request.setTransferProgress(progressCallback);
Expand Down
77 changes: 77 additions & 0 deletions test/src/Object/ObjectSignedUrlTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,83 @@ TEST_F(ObjectSignedUrlTest, PutObjectByUrlRequestFunctionTest)
EXPECT_TRUE(paramters.empty());
}

TEST_F(ObjectSignedUrlTest, UnencodedSlashTest)
{
std::string key = TestUtils::GetObjectKey("UnencodedSlashTest/123/456%2F/123");
std::shared_ptr<std::iostream> content = TestUtils::GetRandomStream(2048);

std::string md5 = ComputeContentMD5(*content.get());

GeneratePresignedUrlRequest request(BucketName, key, Http::Put);
request.setExpires(GetExpiresDelayS(120));
request.setContentMd5(md5);
request.setContentType("text/rtf");
request.UserMetaData()["Author"] = "oss";
request.UserMetaData()["Test"] = "test";
request.addParameter("x-param-null", "");
request.addParameter("x-param-space0", " ");
request.addParameter("x-param-value", "value");
request.addParameter("x-param-space1", " ");

auto urlOutcome = Client->GeneratePresignedUrl(request);
EXPECT_EQ(urlOutcome.isSuccess(), true);
EXPECT_TRUE(urlOutcome.result().find("UnencodedSlashTest%2F123%2F456%252F%2F123") != std::string::npos);

ObjectMetaData meta;
meta.setContentMd5(md5);
meta.setContentType("text/rtf");
meta.UserMetaData()["Author"] = "oss";
meta.UserMetaData()["Test"] = "test";

auto pOutcome = Client->PutObjectByUrl(urlOutcome.result(), content, meta);
EXPECT_EQ(pOutcome.isSuccess(), true);
EXPECT_EQ(TestUtils::ObjectExists(*Client, BucketName, key), true);

auto metaOutcome = Client->HeadObject(BucketName, key);
EXPECT_EQ(metaOutcome.isSuccess(), true);
EXPECT_STREQ(metaOutcome.result().ContentType().c_str(), "text/rtf");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("Author").c_str(), "oss");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("author").c_str(), "oss");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("Test").c_str(), "test");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("tesT").c_str(), "test");

//
request = GeneratePresignedUrlRequest(BucketName, key, Http::Put);
request.setExpires(GetExpiresDelayS(120));
request.setContentMd5(md5);
request.setContentType("text/rtf");
request.UserMetaData()["Author"] = "oss1";
request.UserMetaData()["Test"] = "test1";
request.addParameter("x-param-null", "");
request.addParameter("x-param-space0", " ");
request.addParameter("x-param-value", "value");
request.addParameter("x-param-space1", " ");
request.setUnencodedSlash(true);

urlOutcome = Client->GeneratePresignedUrl(request);
EXPECT_EQ(urlOutcome.isSuccess(), true);
EXPECT_TRUE(urlOutcome.result().find("UnencodedSlashTest/123/456%252F/123") != std::string::npos);

meta = ObjectMetaData();
meta.setContentMd5(md5);
meta.setContentType("text/rtf");
meta.UserMetaData()["Author"] = "oss1";
meta.UserMetaData()["Test"] = "test1";

pOutcome = Client->PutObjectByUrl(urlOutcome.result(), content, meta);
EXPECT_EQ(pOutcome.isSuccess(), true);
EXPECT_EQ(TestUtils::ObjectExists(*Client, BucketName, key), true);

metaOutcome = Client->HeadObject(BucketName, key);
EXPECT_EQ(metaOutcome.isSuccess(), true);
EXPECT_STREQ(metaOutcome.result().ContentType().c_str(), "text/rtf");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("Author").c_str(), "oss1");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("author").c_str(), "oss1");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("Test").c_str(), "test1");
EXPECT_STREQ(metaOutcome.result().UserMetaData().at("tesT").c_str(), "test1");
}



}
}
4 changes: 4 additions & 0 deletions test/src/Other/UtilsFunctionTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,10 @@ TEST_F(UtilsFunctionTest, StringReplaceTest)

StringReplace(test, "abcd", "A");
EXPECT_EQ(test, "1234AABCD1234");

test = "12212";
StringReplace(test, "12", "21");
EXPECT_EQ(test, "21221");
}

TEST_F(UtilsFunctionTest, UploadAndDownloadObject)
Expand Down