Older/ServiceLogic.cpp
2025-02-27 12:57:55 +00:00

78 lines
3.5 KiB
C++

#include "ServiceLogic.h"
#include "HttpSession.h"
#include "Settings.h"
#include <sstream>
namespace ServiceLogic {
using namespace boost::beast;
boost::beast::http::response<boost::beast::http::string_body>
serverError(const boost::beast::http::request<boost::beast::http::string_body> &request, std::string_view errorMessage) {
using namespace boost::beast;
http::response<http::string_body> res{http::status::internal_server_error, request.version()};
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(http::field::content_type, "text/html");
res.keep_alive(request.keep_alive());
std::ostringstream oss;
oss << "An error occurred: '" << errorMessage << "'";
res.body() = oss.str();
res.prepare_payload();
return res;
}
http::response<http::string_body> badRequest(const http::request<http::string_body> &request, std::string_view why) {
http::response<http::string_body> res{http::status::bad_request, request.version()};
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(http::field::content_type, "text/html");
res.keep_alive(request.keep_alive());
res.body() = std::string(why);
res.prepare_payload();
return res;
}
void live2dBackend() {
using namespace Core;
auto application = Singleton<Older::Application>::instance();
application->insertUrl("/api/v1/live2d/{path*}", [](Older::HttpSession &session, const Older::Application::Request &request,
const boost::urls::matches &matches) {
auto settings = Singleton<Older::Settings>::instance();
using namespace boost::beast;
boost::urls::url_view view(request.target());
auto target = view.path();
// LOG(info) << target;
if (target.find("..") != boost::beast::string_view::npos) {
session.reply(ServiceLogic::badRequest(request, "Illegal request-target"));
return;
}
std::string path = ResponseUtility::pathCat(settings->live2dModelsRoot(), matches["path"]);
if (target.back() == '/') path.append("index.html");
if (std::filesystem::is_directory(path)) path.append("/index.html");
boost::beast::error_code ec;
http::file_body::value_type body;
body.open(path.c_str(), boost::beast::file_mode::scan, ec);
if (ec == boost::beast::errc::no_such_file_or_directory) {
std::ostringstream oss;
oss << "The resource '" << target << "' was not found.";
LOG(error) << oss.str();
session.errorReply(request, http::status::not_found, oss.str());
return;
} else if (ec) {
session.reply(ServiceLogic::serverError(request, ec.message()));
return;
}
auto const size = body.size();
http::response<http::file_body> res{std::piecewise_construct, std::make_tuple(std::move(body)),
std::make_tuple(http::status::ok, request.version())};
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(http::field::content_type, ResponseUtility::mimeType(path));
// res.set(http::field::access_control_allow_origin, "*");
res.set(http::field::cache_control, "max-age=2592000");
res.set(http::field::expires, "Fri, 22 Nov 2124 13:30:28 GMT");
res.content_length(size);
res.keep_alive(request.keep_alive());
session.reply(std::move(res));
});
}
} // namespace ServiceLogic