diff --git a/repertory/librepertory/include/comm/curl/requests/http_put_file.hpp b/repertory/librepertory/include/comm/curl/requests/http_put_file.hpp index 1c3faa27..90ae3772 100644 --- a/repertory/librepertory/include/comm/curl/requests/http_put_file.hpp +++ b/repertory/librepertory/include/comm/curl/requests/http_put_file.hpp @@ -39,8 +39,8 @@ struct http_put_file final : http_request_base { std::shared_ptr reader; std::string source_path; - [[nodiscard]] auto - set_method(CURL *curl, stop_type &stop_requested) const -> bool override; + [[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const + -> bool override; private: mutable std::shared_ptr read_info{}; diff --git a/repertory/librepertory/include/comm/curl/requests/http_request_base.hpp b/repertory/librepertory/include/comm/curl/requests/http_request_base.hpp index 9049c754..8851372c 100644 --- a/repertory/librepertory/include/comm/curl/requests/http_request_base.hpp +++ b/repertory/librepertory/include/comm/curl/requests/http_request_base.hpp @@ -26,9 +26,7 @@ #include "utils/file.hpp" namespace repertory::curl::requests { -using read_callback = size_t (*)(char *, size_t, size_t, void *); - -using response_callback = +using curl_response_callback = std::function; struct read_file_info final { @@ -37,19 +35,8 @@ struct read_file_info final { std::uint64_t offset{}; }; -inline const auto read_file_data = static_cast( - [](char *buffer, size_t size, size_t nitems, void *instream) -> size_t { - auto *read_info = reinterpret_cast(instream); - std::size_t bytes_read{}; - auto ret = - read_info->file->read(reinterpret_cast(buffer), - size * nitems, read_info->offset, &bytes_read); - if (ret) { - read_info->offset += bytes_read; - } - return ret && not read_info->stop_requested ? bytes_read - : CURL_READFUNC_ABORT; - }); +[[nodiscard]] auto curl_file_reader(char *buffer, size_t size, size_t nitems, + void *instream) -> size_t; struct http_request_base { http_request_base() = default; @@ -68,14 +55,15 @@ struct http_request_base { std::string path{}; http_query_parameters query{}; std::optional range{}; - std::optional response_handler; + std::optional response_handler; std::optional response_headers; std::optional total_size{}; [[nodiscard]] virtual auto get_path() const -> std::string { return path; } - [[nodiscard]] virtual auto - set_method(CURL *curl, stop_type &stop_requested) const -> bool = 0; + [[nodiscard]] virtual auto set_method(CURL *curl, + stop_type &stop_requested) const + -> bool = 0; }; } // namespace repertory::curl::requests diff --git a/repertory/librepertory/src/comm/curl/requests/http_put_file.cpp b/repertory/librepertory/src/comm/curl/requests/http_put_file.cpp index 76e4baa3..00260697 100644 --- a/repertory/librepertory/src/comm/curl/requests/http_put_file.cpp +++ b/repertory/librepertory/src/comm/curl/requests/http_put_file.cpp @@ -21,21 +21,23 @@ */ #include "comm/curl/requests/http_put_file.hpp" +#include "utils/error_utils.hpp" #include "utils/string.hpp" namespace repertory::curl::requests { auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const -> bool { - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + REPERTORY_USES_FUNCTION_NAME(); + + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_INFILE, nullptr); if (source_path.empty()) { - curl_easy_setopt(curl, CURLOPT_INFILE, nullptr); curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0L); return true; } if (reader) { - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_READDATA, reader.get()); curl_easy_setopt( curl, CURLOPT_READFUNCTION, @@ -51,19 +53,19 @@ auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const }); if (not*read_info->file) { + utils::error::raise_url_error(function_name, get_path(), source_path, + std::runtime_error("failed to open file")); return false; } - auto file_size = read_info->file->size(); + auto file_size = read_info->file->size().value_or(0U); if (file_size == 0U) { - curl_easy_setopt(curl, CURLOPT_INFILE, nullptr); curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0L); return true; } - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get()); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, curl_file_reader); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size); return true; diff --git a/repertory/librepertory/src/comm/curl/requests/http_request_base.cpp b/repertory/librepertory/src/comm/curl/requests/http_request_base.cpp new file mode 100644 index 00000000..27db70ad --- /dev/null +++ b/repertory/librepertory/src/comm/curl/requests/http_request_base.cpp @@ -0,0 +1,43 @@ +/* + Copyright <2018-2024> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#include "comm/curl/requests/http_request_base.hpp" + +#include "utils/file.hpp" +#include "utils/string.hpp" + +namespace repertory::curl::requests { +auto curl_file_reader(char *buffer, size_t size, size_t nitems, void *instream) + -> size_t { + auto *read_info = reinterpret_cast(instream); + + std::size_t bytes_read{}; + auto ret = + read_info->file->read(reinterpret_cast(buffer), + size * nitems, read_info->offset, &bytes_read); + if (ret) { + read_info->offset += bytes_read; + } + + return ret && not read_info->stop_requested ? bytes_read + : CURL_READFUNC_ABORT; +} +} // namespace repertory::curl::requests