mirror of
https://github.com/Icinga/icinga2.git
synced 2026-06-13 10:40:11 -04:00
Merge pull request #10864 from Icinga/fix-http-message-sendfile-failbit-handling
Some checks failed
Container Image / Container Image (push) Has been cancelled
Linux / alpine:bash (push) Has been cancelled
Linux / amazonlinux:2 (push) Has been cancelled
Linux / amazonlinux:2023 (push) Has been cancelled
Linux / debian:11 (linux/386) (push) Has been cancelled
Linux / debian:11 (push) Has been cancelled
Linux / debian:12 (linux/386) (push) Has been cancelled
Linux / debian:12 (push) Has been cancelled
Linux / debian:13 (push) Has been cancelled
Linux / fedora:41 (push) Has been cancelled
Linux / fedora:42 (push) Has been cancelled
Linux / fedora:43 (push) Has been cancelled
Linux / fedora:44 (push) Has been cancelled
Linux / opensuse/leap:15.6 (push) Has been cancelled
Linux / opensuse/leap:16.0 (push) Has been cancelled
Linux / registry.suse.com/bci/bci-base:16.0 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.6 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.7 (push) Has been cancelled
Linux / rockylinux/rockylinux:10 (push) Has been cancelled
Linux / rockylinux:8 (push) Has been cancelled
Linux / rockylinux:9 (push) Has been cancelled
Linux / ubuntu:22.04 (push) Has been cancelled
Linux / ubuntu:24.04 (push) Has been cancelled
Linux / ubuntu:25.04 (push) Has been cancelled
Linux / ubuntu:25.10 (push) Has been cancelled
Linux / ubuntu:26.04 (push) Has been cancelled
Windows / Windows (push) Has been cancelled
Some checks failed
Container Image / Container Image (push) Has been cancelled
Linux / alpine:bash (push) Has been cancelled
Linux / amazonlinux:2 (push) Has been cancelled
Linux / amazonlinux:2023 (push) Has been cancelled
Linux / debian:11 (linux/386) (push) Has been cancelled
Linux / debian:11 (push) Has been cancelled
Linux / debian:12 (linux/386) (push) Has been cancelled
Linux / debian:12 (push) Has been cancelled
Linux / debian:13 (push) Has been cancelled
Linux / fedora:41 (push) Has been cancelled
Linux / fedora:42 (push) Has been cancelled
Linux / fedora:43 (push) Has been cancelled
Linux / fedora:44 (push) Has been cancelled
Linux / opensuse/leap:15.6 (push) Has been cancelled
Linux / opensuse/leap:16.0 (push) Has been cancelled
Linux / registry.suse.com/bci/bci-base:16.0 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.6 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.7 (push) Has been cancelled
Linux / rockylinux/rockylinux:10 (push) Has been cancelled
Linux / rockylinux:8 (push) Has been cancelled
Linux / rockylinux:9 (push) Has been cancelled
Linux / ubuntu:22.04 (push) Has been cancelled
Linux / ubuntu:24.04 (push) Has been cancelled
Linux / ubuntu:25.04 (push) Has been cancelled
Linux / ubuntu:25.10 (push) Has been cancelled
Linux / ubuntu:26.04 (push) Has been cancelled
Windows / Windows (push) Has been cancelled
Fix handling the `std::ifstream::failbit` in `OutgoingHttpMessage`
This commit is contained in:
commit
91eeb41ff1
4 changed files with 32 additions and 4 deletions
|
|
@ -81,9 +81,12 @@ bool ConfigFilesHandler::HandleRequest(
|
|||
response.result(http::status::ok);
|
||||
response.set(http::field::content_type, "application/octet-stream");
|
||||
response.SendFile(path, yc);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
|
||||
DiagnosticInformation(ex));
|
||||
} catch (const std::ios_base::failure& ex) {
|
||||
if (response.HasSerializationStarted()) {
|
||||
throw;
|
||||
}
|
||||
|
||||
HttpUtility::SendJsonError(response, params, 500, "Could not read file.", DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ void OutgoingHttpMessage<isRequest, Body, StreamVariant>::SendFile(
|
|||
)
|
||||
{
|
||||
std::ifstream fp(path.CStr(), std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
|
||||
fp.exceptions(std::ifstream::badbit | std::ifstream::eofbit);
|
||||
fp.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit);
|
||||
|
||||
std::uint64_t remaining = fp.tellg();
|
||||
fp.seekg(0);
|
||||
|
|
|
|||
|
|
@ -86,6 +86,16 @@ void HttpUtility::SendJsonBody(HttpApiResponse& response, const Dictionary::Ptr&
|
|||
void HttpUtility::SendJsonError(HttpApiResponse& response,
|
||||
const Dictionary::Ptr& params, int code, const String& info, const String& diagnosticInformation)
|
||||
{
|
||||
if (response.HasSerializationStarted()) {
|
||||
std::ostringstream err;
|
||||
err << "Impossible to send error response after streaming has started: error: '" << code << "', status: '"
|
||||
<< info << "'";
|
||||
if (!diagnosticInformation.IsEmpty()) {
|
||||
err << ", diagnostic_information: '" << diagnosticInformation << "'";
|
||||
}
|
||||
BOOST_THROW_EXCEPTION(std::logic_error{err.str()});
|
||||
}
|
||||
|
||||
Dictionary::Ptr result = new Dictionary({ { "error", code } });
|
||||
|
||||
if (!info.IsEmpty()) {
|
||||
|
|
|
|||
|
|
@ -353,4 +353,19 @@ BOOST_AUTO_TEST_CASE(response_sendfile)
|
|||
BOOST_REQUIRE_EQUAL(ss.str(), parser.get().body());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_sendfile_invalid_path)
|
||||
{
|
||||
auto future = SpawnSynchronizedCoroutine([this](boost::asio::yield_context yc) {
|
||||
HttpApiResponse response(server);
|
||||
|
||||
response.result(http::status::ok);
|
||||
BOOST_REQUIRE_THROW(response.SendFile("", yc), std::ios_base::failure);
|
||||
});
|
||||
|
||||
auto status = future.wait_for(10s);
|
||||
if (status != std::future_status::ready) {
|
||||
BOOST_FAIL("Exception not thrown.");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue