[IO] Extracting Version ID in S3::URI

Extracting Version ID form query string in URI.
This commit is contained in:
Saad Ur Rahman 2022-03-14 22:16:24 -04:00
parent ec28af055f
commit 1a85e9b60d
No known key found for this signature in database
GPG Key ID: C6773CD21542E49C
2 changed files with 102 additions and 1 deletions

View File

@ -780,6 +780,28 @@ namespace S3
if (uri.getHost().empty())
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Host is empty in S3 URI.");
// Extract object version ID from query string.
{
const String version_key = "versionId";
const auto query_string = uri.getQuery();
auto start = query_string.rfind(version_key);
if (start == std::string::npos)
{
version_id = "";
}
else
{
start = query_string.find_first_of('=', start);
start = start == std::string::npos ? query_string.length() : start + 1;
auto end = query_string.find_first_of('&', start);
end = end == std::string::npos ? query_string.length() : end - start;
version_id = query_string.substr(start, end);
}
}
String name;
String endpoint_authority_from_uri;

View File

@ -3,12 +3,79 @@
#if USE_AWS_S3
# include <IO/S3Common.h>
#include <IO/S3Common.h>
namespace
{
using namespace DB;
struct TestCase
{
S3::URI uri;
String endpoint;
String bucket;
String key;
String version_id;
bool is_virtual_hosted_style;
};
const TestCase TestCases[] = {
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?firstKey=someKey&secondKey=anotherKey")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?versionId=testVersionId&anotherKey=someOtherKey")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"testVersionId",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?firstKey=someKey&versionId=testVersionId&anotherKey=someOtherKey")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"testVersionId",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?anotherKey=someOtherKey&versionId=testVersionId")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"testVersionId",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?versionId=testVersionId")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"testVersionId",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?versionId=")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?versionId&")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"",
true},
{S3::URI(Poco::URI("https://bucketname.s3.us-east-2.amazonaws.com/data?versionId")),
"https://s3.us-east-2.amazonaws.com",
"bucketname",
"data",
"",
true},
};
class S3UriTest : public testing::TestWithParam<std::string>
{
};
@ -102,6 +169,18 @@ TEST_P(S3UriTest, invalidPatterns)
ASSERT_ANY_THROW(S3::URI(Poco::URI(GetParam())));
}
TEST(S3UriTest, versionIdChecks)
{
for (const auto& test_case : TestCases)
{
ASSERT_EQ(test_case.endpoint, test_case.uri.endpoint);
ASSERT_EQ(test_case.bucket, test_case.uri.bucket);
ASSERT_EQ(test_case.key, test_case.uri.key);
ASSERT_EQ(test_case.version_id, test_case.uri.version_id);
ASSERT_EQ(test_case.is_virtual_hosted_style, test_case.uri.is_virtual_hosted_style);
}
}
INSTANTIATE_TEST_SUITE_P(
S3,
S3UriTest,