diff --git a/include/providers/encrypt/encrypt_provider.hpp b/include/providers/encrypt/encrypt_provider.hpp index dfc3c027..a707dad7 100644 --- a/include/providers/encrypt/encrypt_provider.hpp +++ b/include/providers/encrypt/encrypt_provider.hpp @@ -207,7 +207,7 @@ public: } [[nodiscard]] auto start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool override; + i_file_manager *mgr) -> bool override; void stop() override; diff --git a/include/providers/i_provider.hpp b/include/providers/i_provider.hpp index 7c981f22..239dd23b 100644 --- a/include/providers/i_provider.hpp +++ b/include/providers/i_provider.hpp @@ -143,7 +143,7 @@ public: -> api_error = 0; [[nodiscard]] virtual auto start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool = 0; + i_file_manager *mgr) -> bool = 0; virtual void stop() = 0; diff --git a/include/providers/s3/s3_provider.hpp b/include/providers/s3/s3_provider.hpp index f5ce8b17..2ff78853 100644 --- a/include/providers/s3/s3_provider.hpp +++ b/include/providers/s3/s3_provider.hpp @@ -194,7 +194,7 @@ public: -> api_error override; [[nodiscard]] auto start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool override; + i_file_manager *mgr) -> bool override; void stop() override; diff --git a/include/providers/sia/sia_provider.hpp b/include/providers/sia/sia_provider.hpp index 45cada5c..6acde062 100644 --- a/include/providers/sia/sia_provider.hpp +++ b/include/providers/sia/sia_provider.hpp @@ -185,7 +185,7 @@ public: -> api_error override; [[nodiscard]] auto start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool override; + i_file_manager *mgr) -> bool override; void stop() override; diff --git a/src/providers/encrypt/encrypt_provider.cpp b/src/providers/encrypt/encrypt_provider.cpp index 77dead5c..bdc6117e 100644 --- a/src/providers/encrypt/encrypt_provider.cpp +++ b/src/providers/encrypt/encrypt_provider.cpp @@ -763,7 +763,7 @@ void encrypt_provider::remove_deleted_files() { } auto encrypt_provider::start(api_item_added_callback /*api_item_added*/, - i_file_manager * /*fm*/) -> bool { + i_file_manager * /*mgr*/) -> bool { if (not is_online()) { return false; } diff --git a/src/providers/s3/s3_provider.cpp b/src/providers/s3/s3_provider.cpp index 3f26e540..b7d357a5 100644 --- a/src/providers/s3/s3_provider.cpp +++ b/src/providers/s3/s3_provider.cpp @@ -31,6 +31,7 @@ #include "types/s3.hpp" #include "types/startup_exception.hpp" #include "utils/encryption.hpp" +#include "utils/encrypting_reader.hpp" #include "utils/error_utils.hpp" #include "utils/file_utils.hpp" #include "utils/path_utils.hpp" @@ -398,7 +399,60 @@ auto s3_provider::get_api_path_from_source(const std::string &source_path, auto s3_provider::get_directory_item_count(const std::string &api_path) const -> std::uint64_t { - // TODO implement this + try { + const auto cfg = config_.get_s3_config(); + const auto is_encrypted = not cfg.encryption_token.empty(); + std::string key; + if (is_encrypted) { + auto res = get_item_meta(api_path, META_KEY, key); + if (res != api_error::success) { + return 0U; + } + } + + const auto object_name = + api_path == "/" + ? "" + : utils::path::create_api_path(is_encrypted ? key : api_path); + + std::string response_data{}; + long response_code{}; + auto prefix = object_name.empty() ? object_name : object_name + "/"; + + if (not get_object_list(comm_, config_.get_s3_config(), response_data, + response_code, "/", prefix)) { + return 0U; + } + + if (response_code == http_error_codes::not_found) { + return 0U; + } + + if (response_code != http_error_codes::ok) { + return 0U; + } + + pugi::xml_document doc; + auto res = doc.load_string(response_data.c_str()); + if (res.status != pugi::xml_parse_status::status_ok) { + return 0U; + } + + auto node_list = + doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix"); + std::uint64_t ret = node_list.size(); + + node_list = doc.select_nodes("/ListBucketResult/Contents"); + ret += node_list.size(); + if (not prefix.empty()) { + --ret; + } + + return ret; + } catch (const std::exception &e) { + utils::error::raise_error(__FUNCTION__, e, "exception occurred"); + } + return 0U; } @@ -469,16 +523,25 @@ auto s3_provider::get_directory_items(const std::string &api_path, if (res == api_error::item_not_found) { if (directory) { res = create_path_directories(child_api_path, child_object_name); + if (res != api_error::success) { + return res; + } } else { auto file = create_api_file(child_api_path, child_object_name, dir_item.size); res = add_if_not_found(file, child_object_name); + if (res != api_error::success) { + return res; + } } + + res = get_item_meta(child_api_path, dir_item.meta); } if (res != api_error::success) { return res; } + list.push_back(std::move(dir_item)); return api_error::success; }; @@ -1309,12 +1372,12 @@ auto s3_provider::set_item_meta(const std::string &api_path, } auto s3_provider::start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool { + i_file_manager *mgr) -> bool { event_system::instance().raise("s3_provider"); utils::db::create_rocksdb(config_, DB_NAME, db_); api_item_added_ = api_item_added; - fm_ = fm; + fm_ = mgr; api_meta_map meta{}; if (get_item_meta("/", meta) == api_error::item_not_found) { diff --git a/src/providers/sia/sia_provider.cpp b/src/providers/sia/sia_provider.cpp index ade2193f..a283f735 100644 --- a/src/providers/sia/sia_provider.cpp +++ b/src/providers/sia/sia_provider.cpp @@ -1242,12 +1242,12 @@ auto sia_provider::set_item_meta(const std::string &api_path, } auto sia_provider::start(api_item_added_callback api_item_added, - i_file_manager *fm) -> bool { + i_file_manager *mgr) -> bool { event_system::instance().raise("sia_provider"); utils::db::create_rocksdb(config_, DB_NAME, db_); api_item_added_ = api_item_added; - fm_ = fm; + fm_ = mgr; api_meta_map meta{}; if (get_item_meta("/", meta) == api_error::item_not_found) {