/// /// \file Utility.cc /// \author K. Isom /// \date 2023-10-24 /// \brief Common utility functions for packaging. /// /// Copyright 2023 K. Isom /// /// Permission to use, copy, modify, and/or distribute this software for /// any purpose with or without fee is hereby granted, provided that /// the above copyright notice and this permission notice appear in all /// copies. /// /// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL /// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED /// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE /// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL /// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA /// OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER /// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR /// PERFORMANCE OF THIS SOFTWARE. /// #include #include #include #include #include #include #include #include #include "Utility.h" namespace { std::string getUserPass() { return scsl::SimpleConfig::GetGlobal("http_user") + ":" + scsl::SimpleConfig::GetGlobal("http_password"); } } Result PutFile(std::string url, std::string path) { const curlpp::Cleanup clearerr; static std::string userPass; auto verbose = false; curlpp::Easy request; if (scsl::SimpleConfig::GetGlobal("verbose") == "true") { verbose = true; } if (userPass.empty()) { userPass = getUserPass(); } try { std::list header; header.emplace_back("Content-Type: application/octet-stream"); if (!std::filesystem::exists(path)) { std::cerr << "[!] " << path << " does not exist!\n"; return Result::CurlFailed; } auto fileSize = static_cast(std::filesystem::file_size(path)); std::ifstream uploadFile(path); if (!uploadFile.good()) { std::cerr << "[!] " << path << " does not exist!\n"; return Result::CurlFailed; } request.setOpt(new curlpp::options::Url(url)); if (verbose) { request.setOpt(new curlpp::options::Verbose(true)); } request.setOpt(new curlpp::options::UserPwd(userPass)); request.setOpt(new curlpp::Options::ReadStream(&uploadFile)); request.setOpt(new curlpp::Options::InfileSize(fileSize)); request.setOpt(new curlpp::Options::Upload(true)); request.perform(); } catch (curlpp::LogicError &e) { std::cerr << e.what() << "\n"; return Result::CurlFailed; } catch (curlpp::RuntimeError &e) { std::cerr << e.what() << "\n"; return Result::CurlFailed; } auto httpStatus = curlpp::infos::ResponseCode::get(request); switch (httpStatus) { case 201: return Result::Created; case 400: return Result::BadPackage; case 409: return Result::DuplicatePackage; default: return Result::CurlFailed; } } Result DeleteFile(std::string url) { const curlpp::Cleanup clearerr; static std::string userPass; bool verbose = false; curlpp::Easy request; if (scsl::SimpleConfig::GetGlobal("verbose") == "true") { verbose = true; } if (userPass.empty()) { userPass = getUserPass(); } try { request.setOpt(new curlpp::options::Url(url)); if (verbose) { request.setOpt(new curlpp::options::Verbose(true)); } request.setOpt(new curlpp::options::UserPwd(userPass)); request.setOpt(new curlpp::Options::CustomRequest ("DELETE")); request.perform(); } catch (curlpp::LogicError &e) { std::cerr << e.what() << "\n"; return Result::CurlFailed; } catch (curlpp::RuntimeError &e) { std::cerr << e.what() << "\n"; return Result::CurlFailed; } auto httpStatus = curlpp::infos::ResponseCode::get(request); switch (httpStatus) { case 204: return Result::Deleted; case 404: return Result::NotFound; default: return Result::CurlFailed; } } std::string ResultToString(Result result) { switch (result) { case Result::Created: return "OK: created"; case Result::BadPackage: return "FAILED: bad package"; case Result::DuplicatePackage: return "FAILED: duplicate package?"; case Result::Deleted: return "OK: deleted"; case Result::NotFound: return "FAILED: not found"; case Result::CurlFailed: return "FAILED: curl failed"; default: return "FAILED: unhandled error"; } } bool ResultSuccess(Result result) { return (result == Result::Created || result == Result::Deleted); }