From bf894eebdd44742380e0df9f95c8a6a0f29c6e9b Mon Sep 17 00:00:00 2001 From: Rich Wellner Date: Mon, 18 Nov 2024 10:31:21 -0600 Subject: [PATCH 1/2] trailing / messes up signing of request --- src/S3Commands.cc | 4 +++- test/s3_tests.cc | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/S3Commands.cc b/src/S3Commands.cc index 587994b..c5cc9b6 100644 --- a/src/S3Commands.cc +++ b/src/S3Commands.cc @@ -553,9 +553,10 @@ bool AmazonS3Head::SendRequest() { // --------------------------------------------------------------------------- bool AmazonS3List::SendRequest(const std::string &continuationToken) { - query_parameters["list-type"] = "2"; // Version 2 of the object-listing API + query_parameters["list-type"] = "2"; // Version 2 of the object-listing query_parameters["delimiter"] = "/"; query_parameters["prefix"] = urlquote(object); + query_parameters["encoding-type"] = "url"; if (!continuationToken.empty()) { query_parameters["continuation-token"] = urlquote(continuationToken); } @@ -564,6 +565,7 @@ bool AmazonS3List::SendRequest(const std::string &continuationToken) { // Operation is on the bucket itself; alter the URL to remove the object hostUrl = getProtocol() + "://" + host + bucketPath; + canonicalURI = bucketPath; return SendS3Request(""); } diff --git a/test/s3_tests.cc b/test/s3_tests.cc index 099b334..f943e75 100644 --- a/test/s3_tests.cc +++ b/test/s3_tests.cc @@ -49,7 +49,8 @@ TEST(TestS3URLGeneration, Test1) { TestAmazonRequest pathReq{serviceUrl, "akf", "skf", b, o, "path", 4}; std::string generatedHostUrl = pathReq.getHostUrl(); ASSERT_EQ(generatedHostUrl, - "https://s3-service.com:443/test-bucket/test-object"); + "https://s3-service.com:443/test-bucket/test-object") + << "generatedURL: " << generatedHostUrl; // Test virtual-style URL generation TestAmazonRequest virtReq{serviceUrl, "akf", "skf", b, o, "virtual", 4}; From b6e1ecb1199d56baa04a0670e839626447ffb7ea Mon Sep 17 00:00:00 2001 From: Rich Wellner Date: Thu, 21 Nov 2024 16:57:45 -0600 Subject: [PATCH 2/2] uris used to require a trailing slash. this was wrong and is fixed in this path. --- src/S3Directory.cc | 6 +++++- src/S3FileSystem.cc | 12 +++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/S3Directory.cc b/src/S3Directory.cc index 31375b5..34ea6c8 100644 --- a/src/S3Directory.cc +++ b/src/S3Directory.cc @@ -77,9 +77,13 @@ int S3Directory::Opendir(const char *path, XrdOucEnv &env) { return -EBADF; } Reset(); + std::string realPath = path; + if (realPath.back() != '/') { + realPath = realPath + "/"; + } std::string exposedPath, object; - int rv = m_fs.parsePath(path, exposedPath, object); + int rv = m_fs.parsePath(realPath.c_str(), exposedPath, object); if (rv != 0) { return rv; } diff --git a/src/S3FileSystem.cc b/src/S3FileSystem.cc index d8d10d1..c428a2f 100644 --- a/src/S3FileSystem.cc +++ b/src/S3FileSystem.cc @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -202,9 +203,14 @@ XrdOssDF *S3FileSystem::newFile(const char *user) { int S3FileSystem::Stat(const char *path, struct stat *buff, int opts, XrdOucEnv *env) { m_log.Log(XrdHTTPServer::Debug, "Stat", "Stat'ing path", path); + std::string localPath = path; + + if (std::count(localPath.begin(), localPath.end(), '/') == 1) { + localPath = localPath + "/"; + } std::string exposedPath, object; - auto rv = parsePath(path, exposedPath, object); + auto rv = parsePath(localPath.c_str(), exposedPath, object); if (rv != 0) { return rv; } @@ -226,7 +232,7 @@ int S3FileSystem::Stat(const char *path, struct stat *buff, int opts, if (httpCode == 0) { if (m_log.getMsgMask() & XrdHTTPServer::Info) { std::stringstream ss; - ss << "Failed to stat path " << path + ss << "Failed to stat path " << localPath << "; error: " << listCommand.getErrorMessage() << " (code=" << listCommand.getErrorCode() << ")"; m_log.Log(XrdHTTPServer::Info, "Stat", ss.str().c_str()); @@ -235,7 +241,7 @@ int S3FileSystem::Stat(const char *path, struct stat *buff, int opts, } else { if (m_log.getMsgMask() & XrdHTTPServer::Info) { std::stringstream ss; - ss << "Failed to stat path " << path << "; response code " + ss << "Failed to stat path " << localPath << "; response code " << httpCode; m_log.Log(XrdHTTPServer::Info, "Stat", ss.str().c_str()); }