1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
/* Icinga 2 | (c) 2024 Icinga GmbH | GPLv2+ */
#include "base/defer.hpp"
#include "remote/filterutility.hpp"
#include "remote/httputility.hpp"
#include "remote/mallocinfohandler.hpp"
#include <cstddef>
#include <cstdio>
#include <string>
#ifdef HAVE_MALLOC_INFO
# include <errno.h>
# include <malloc.h>
#endif /* HAVE_MALLOC_INFO */
using namespace icinga;
REGISTER_URLHANDLER("/v1/debug/malloc_info", MallocInfoHandler);
bool MallocInfoHandler::HandleRequest(
const WaitGroup::Ptr&,
AsioTlsStream&,
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params,
boost::asio::yield_context&,
HttpServerConnection&
)
{
namespace http = boost::beast::http;
if (url->GetPath().size() != 3) {
return false;
}
if (request.method() != http::verb::get) {
return false;
}
FilterUtility::CheckPermission(user, "debug");
#ifndef HAVE_MALLOC_INFO
HttpUtility::SendJsonError(response, params, 501, "malloc_info(3) not available.");
#else /* HAVE_MALLOC_INFO */
char* buf = nullptr;
size_t bufSize = 0;
FILE* f = nullptr;
Defer release ([&f, &buf]() {
if (f) {
(void)fclose(f);
}
free(buf);
});
f = open_memstream(&buf, &bufSize);
if (!f) {
auto error (errno);
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("open_memstream")
<< boost::errinfo_errno(error));
}
if (malloc_info(0, f)) {
auto error (errno);
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("malloc_info")
<< boost::errinfo_errno(error));
}
auto closeErr (fclose(f));
f = nullptr;
if (closeErr) {
auto error (errno);
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("fclose")
<< boost::errinfo_errno(error));
}
response.result(200);
response.set(http::field::content_type, "application/xml");
response.body() = std::string(buf, bufSize);
response.content_length(response.body().size());
#endif /* HAVE_MALLOC_INFO */
return true;
}
|