// // Created by WolverinDEV on 28/04/2020. // #include #include #include "LocalFileProvider.h" #include "LocalFileSystem.h" #include "LocalFileTransfer.h" using namespace ts::server; using LocalFileServer = file::LocalFileProvider; using LocalVirtualFileServer = file::LocalVirtualFileServer; std::shared_ptr server_instance{}; bool file::initialize(std::string &error, const std::string& hostnames, uint16_t port) { server_instance = std::make_shared(); if(!server_instance->initialize(error)) { server_instance = nullptr; return false; } bool any_bind{false}; for(const auto& binding : net::resolve_bindings(hostnames, port)) { if(!std::get<2>(binding).empty()) { logError(LOG_FT, "Failed to resolve binding for {}: {}", std::get<0>(binding), std::get<2>(binding)); continue; } auto result = dynamic_cast(server_instance->file_transfer()).add_network_binding({ std::get<0>(binding), std::get<1>(binding) }); switch (result) { case transfer::NetworkingBindResult::SUCCESS: any_bind = true; break; case transfer::NetworkingBindResult::OUT_OF_MEMORY: logWarning(LOG_FT, "Failed to listen to address {}: Out of memory", std::get<0>(binding)); continue; case transfer::NetworkingBindResult::FAILED_TO_LISTEN: logWarning(LOG_FT, "Failed to listen on {}: {}/{}", std::get<0>(binding), errno, strerror(errno)); continue; case transfer::NetworkingBindResult::FAILED_TO_BIND: logWarning(LOG_FT, "Failed to bind on {}: {}/{}", std::get<0>(binding), errno, strerror(errno)); continue; case transfer::NetworkingBindResult::BINDING_ALREADY_EXISTS: logWarning(LOG_FT, "Failed to bind on {}: binding already exists", std::get<0>(binding)); continue; case transfer::NetworkingBindResult::NETWORKING_NOT_INITIALIZED: logWarning(LOG_FT, "Failed to bind on {}: networking not initialized", std::get<0>(binding)); continue; case transfer::NetworkingBindResult::FAILED_TO_ALLOCATE_SOCKET: logWarning(LOG_FT, "Failed to allocate a socket for {}: {}/{}", std::get<0>(binding), errno, strerror(errno)); continue; } } return true; } void file::finalize() { auto server = std::exchange(server_instance, nullptr); if(!server) return; server->finalize(); } std::shared_ptr file::server() { return server_instance; } LocalFileServer::LocalFileProvider() { this->file_system_ = new filesystem::LocalFileSystem(); this->file_transfer_ = new transfer::LocalFileTransfer(this->file_system_); } LocalFileServer::~LocalFileProvider() { delete this->file_transfer_; delete this->file_system_; }; bool LocalFileServer::initialize(std::string &error) { if(!this->file_system_->initialize(error, "files/")) return false; if(!this->file_transfer_->start()) { error = "transfer server startup failed"; this->file_system_->finalize(); return false; } return true; } void LocalFileServer::finalize() { this->file_transfer_->stop(); this->file_system_->finalize(); } file::filesystem::AbstractProvider &LocalFileServer::file_system() { return *this->file_system_; } file::transfer::AbstractProvider &LocalFileServer::file_transfer() { return *this->file_transfer_; } std::string file::LocalFileProvider::file_base_path() const { return this->file_system_->root_path(); } std::shared_ptr LocalFileServer::register_server(ServerId server_id) { auto server = this->find_virtual_server(server_id); if(server) return server; server = std::make_shared(server_id, std::to_string(server_id)); { std::lock_guard slock{this->servers_mutex}; this->servers_.push_back(server); } return server; } void LocalFileServer::unregister_server(ServerId server_id) { auto server_unique_id = std::to_string(server_id); std::lock_guard slock{this->servers_mutex}; auto it = std::find_if(this->servers_.begin(), this->servers_.end(), [&](const std::shared_ptr& server) { return server->unique_id() == server_unique_id; }); if(it == this->servers_.end()) return; this->servers_.erase(it); } void LocalVirtualFileServer::max_networking_upload_bandwidth(int64_t value) { VirtualFileServer::max_networking_upload_bandwidth(value); this->upload_throttle.set_max_bandwidth(value); } void LocalVirtualFileServer::max_networking_download_bandwidth(int64_t value) { VirtualFileServer::max_networking_download_bandwidth(value); this->download_throttle.set_max_bandwidth(value); }