Skip to content

Commit

Permalink
[coro_http][breakchange] async_upload support offset
Browse files Browse the repository at this point in the history
  • Loading branch information
poor-circle committed Aug 8, 2024
1 parent 69e653e commit fbcde01
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions include/ylt/standalone/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,14 +878,16 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
}

async_simple::coro::Lazy<void> send_file_no_chunked_with_copy(
std::string_view source, std::error_code &ec, std::size_t length) {
std::string_view source, std::error_code &ec, std::size_t length,
std::size_t offset) {
if (length <= 0) {
co_return;
}
std::string file_data;
detail::resize(file_data, std::min(max_single_part_size_, length));
coro_io::coro_file file{};
file.open(source, std::ios::in);
file.seek(offset, std::ios::cur);
if (!file.is_open()) {
ec = std::make_error_code(std::errc::bad_file_descriptor);
co_return;
Expand Down Expand Up @@ -923,15 +925,15 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
};
async_simple::coro::Lazy<void> send_file_without_copy(
const std::filesystem::path &source, std::error_code &ec,
std::size_t length) {
std::size_t length, std::size_t offset) {
fd_guard guard(source.c_str());
if (guard.fd < 0) [[unlikely]] {
ec = std::make_error_code(std::errc::bad_file_descriptor);
co_return;
}
std::size_t actual_len = 0;
std::tie(ec, actual_len) =
co_await coro_io::async_sendfile(socket_->impl_, guard.fd, 0, length);
std::tie(ec, actual_len) = co_await coro_io::async_sendfile(
socket_->impl_, guard.fd, offset, length);
if (ec) [[unlikely]] {
co_return;
}
Expand Down Expand Up @@ -1009,7 +1011,8 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
template <typename S, typename Source>
async_simple::coro::Lazy<resp_data> async_upload(
S uri, http_method method, Source source /* file */,
int64_t content_length = -1,
uint64_t offset = 0 /*file offset*/,
int64_t content_length = -1 /*upload size*/,
req_content_type content_type = req_content_type::text,
std::unordered_map<std::string, std::string> headers = {}) {
std::error_code ec{};
Expand Down Expand Up @@ -1053,6 +1056,12 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
co_return resp_data{std::make_error_code(std::errc::invalid_argument),
404};
}
content_length -= offset;
if (content_length < 0) {
CINATRA_LOG_ERROR << "the offset is larger than the end of file";
co_return resp_data{std::make_error_code(std::errc::invalid_argument),
404};
}
}

assert(content_length >= 0);
Expand Down Expand Up @@ -1091,6 +1100,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
}

if constexpr (is_stream_file) {
source->seekg(offset, std::ios::cur);
std::string file_data;
detail::resize(file_data, std::min<std::size_t>(max_single_part_size_,
content_length));
Expand Down Expand Up @@ -1119,15 +1129,17 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
if (!has_init_ssl_) {
#endif
co_await send_file_without_copy(std::filesystem::path{source}, ec,
content_length);
content_length, offset);
#ifdef CINATRA_ENABLE_SSL
}
else {
co_await send_file_no_chunked_with_copy(source, ec, content_length);
co_await send_file_no_chunked_with_copy(source, ec, content_length,
offset);
}
#endif
#else
co_await send_file_no_chunked_with_copy(source, ec, content_length);
co_await send_file_no_chunked_with_copy(source, ec, content_length,
offset);
#endif
}
else {
Expand Down

0 comments on commit fbcde01

Please sign in to comment.