diff options
Diffstat (limited to 'http')
-rw-r--r-- | http/http_body.hpp | 16 | ||||
-rw-r--r-- | http/http_connection.hpp | 8 | ||||
-rw-r--r-- | http/http_response.hpp | 26 |
3 files changed, 38 insertions, 12 deletions
diff --git a/http/http_body.hpp b/http/http_body.hpp index f4bfed58ec..7be23f0809 100644 --- a/http/http_body.hpp +++ b/http/http_body.hpp @@ -220,11 +220,19 @@ class HttpBody::writer return ret; } size_t readReq = std::min(fileReadBuf.size(), maxSize); - size_t read = body.file().read(fileReadBuf.data(), readReq, ec); - if (ec) + BMCWEB_LOG_INFO("Reading {}", readReq); + boost::system::error_code readEc; + size_t read = body.file().read(fileReadBuf.data(), readReq, readEc); + if (readEc) { - BMCWEB_LOG_CRITICAL("Failed to read from file"); - return boost::none; + if (readEc != boost::system::errc::operation_would_block && + readEc != boost::system::errc::resource_unavailable_try_again) + { + BMCWEB_LOG_CRITICAL("Failed to read from file {}", + readEc.message()); + ec = readEc; + return boost::none; + } } std::string_view chunkView(fileReadBuf.data(), read); diff --git a/http/http_connection.hpp b/http/http_connection.hpp index 4d9c9806ef..fdbecd1f2e 100644 --- a/http/http_connection.hpp +++ b/http/http_connection.hpp @@ -614,11 +614,17 @@ class Connection : const boost::system::error_code& ec, std::size_t bytesTransferred) { - BMCWEB_LOG_DEBUG("{} async_write wrote {} bytes, ec=", logPtr(this), + BMCWEB_LOG_DEBUG("{} async_write wrote {} bytes, ec={}", logPtr(this), bytesTransferred, ec); cancelDeadlineTimer(); + if (ec == boost::system::errc::operation_would_block || + ec == boost::system::errc::resource_unavailable_try_again) + { + doWrite(); + return; + } if (ec) { BMCWEB_LOG_DEBUG("{} from write(2)", logPtr(this)); diff --git a/http/http_response.hpp b/http/http_response.hpp index 18266ec93d..a4c8375c82 100644 --- a/http/http_response.hpp +++ b/http/http_response.hpp @@ -3,6 +3,8 @@ #include "logging.hpp" #include "utils/hex_utils.hpp" +#include <fcntl.h> + #include <boost/beast/http/message.hpp> #include <nlohmann/json.hpp> @@ -10,6 +12,7 @@ #include <string> #include <string_view> #include <utility> + namespace crow { @@ -170,17 +173,21 @@ struct Response // This code is a throw-free equivalent to // beast::http::message::prepare_payload std::optional<uint64_t> pSize = response.body().payloadSize(); - if (!pSize) - { - return; - } + using http::status; using http::status_class; using http::to_status_class; bool is1XXReturn = to_status_class(result()) == status_class::informational; - if (*pSize > 0 && (is1XXReturn || result() == status::no_content || - result() == status::not_modified)) + if (!pSize) + { + response.chunked(true); + return; + } + response.content_length(*pSize); + + if (is1XXReturn || result() == status::no_content || + result() == status::not_modified) { BMCWEB_LOG_CRITICAL("{} Response content provided but code was " "no-content or not_modified, which aren't " @@ -189,7 +196,6 @@ struct Response response.content_length(0); return; } - response.content_length(*pSize); } void clear() @@ -299,6 +305,12 @@ struct Response bool openFd(int fd, bmcweb::EncodingType enc = bmcweb::EncodingType::Raw) { boost::beast::error_code ec; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) + int retval = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + if (retval == -1) + { + BMCWEB_LOG_ERROR("Setting O_NONBLOCK failed"); + } response.body().encodingType = enc; response.body().setFd(fd, ec); if (ec) |