#ifndef SERVICELOGIC_INL #define SERVICELOGIC_INL #include "BoostLog.h" #include "ServiceLogic.h" #include "WeChatContext/WeChatContext.h" #include #include #include #include #include #include #include namespace ServiceLogic { template static void onGetBlogImage(SharedStatePtr state, StringRequest &&request, Send &&send) { using namespace boost::beast; boost::urls::url url(request.target()); if (url.path().size() < 12) return; auto file = url.path().substr(12); auto root = state->notebookRoot(); auto path = ResponseUtility::pathCat(root, file); boost::nowide::ifstream ifs(path, boost::nowide::ifstream::binary); std::vector file_string(std::istreambuf_iterator{ifs}, std::istreambuf_iterator{}); boost::beast::error_code ec; http::response> s; s.set(http::field::server, BOOST_BEAST_VERSION_STRING); s.set(http::field::content_type, ResponseUtility::mimeType(path)); s.keep_alive(request.keep_alive()); s.body() = std::move(file_string); s.prepare_payload(); return send(std::move(s)); } template static void onGetBlogContent(SharedStatePtr state, StringRequest &&request, Send &&send, const std::string &prefix) { using namespace boost::beast; boost::urls::url url(request.target()); auto file = url.path().substr(prefix.length()); auto root = state->notebookRoot(); auto path = ResponseUtility::pathCat(root, file); LOG(info) << "get file: " << path; if (!std::filesystem::exists(path)) { return send(notFound(request)); } boost::nowide::ifstream ifs(path); std::string file_string(std::istreambuf_iterator{ifs}, std::istreambuf_iterator{}); http::response s; s.set(http::field::server, BOOST_BEAST_VERSION_STRING); s.set(http::field::content_type, "text/markdown;charset=UTF-8"); s.keep_alive(request.keep_alive()); s.body() = file_string; s.prepare_payload(); return send(std::move(s)); } template void onDownload(SharedStatePtr state, StringRequest &&request, Send &&send) { LOG(info) << "onDownload"; using namespace boost::beast; std::string_view file; if (request.target() == "/download") { auto requestData = boost::json::parse(request.body()); file = requestData.as_object()["file"].as_string(); } else { file = request.target().substr(9); } auto path = ResponseUtility::pathCat(state->fileRoot(), file); LOG(info) << "get file: " << path; // Attempt to open the file boost::beast::error_code ec; http::file_body::value_type body; body.open(path.c_str(), boost::beast::file_mode::scan, ec); // Handle the case where the file doesn't exist if (ec == boost::system::errc::no_such_file_or_directory) { return send(notFound(request)); } else if (ec) { // Handle an unknown error return send(serverError(request, ec.message())); } // Cache the size since we need it after the move auto const size = body.size(); // Respond to GET request http::response 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::content_description, file); res.set(http::field::accept_charset, "utf-8"); res.content_length(size); res.keep_alive(request.keep_alive()); return send(std::move(res)); } template static void onWechat(SharedStatePtr state, const StringRequest &request, Send &&send) { using namespace boost::beast; boost::urls::url url(request.target()); auto context = Amass::Singleton::instance(); http::response response; if (request.count("Content-Type") > 0 && request.at("Content-Type") == "text/xml") { response.body() = context->reply(request.body()); } else { auto query = url.params(); if (auto iterator = query.find("echostr"); iterator != query.end()) { response.body() = (*iterator)->value; } } boost::beast::error_code ec; response.set(http::field::server, BOOST_BEAST_VERSION_STRING); response.set(http::field::content_type, "text/xml;charset=UTF-8"); response.keep_alive(request.keep_alive()); response.prepare_payload(); return send(std::move(response)); } } // namespace ServiceLogic #endif // SERVICELOGIC_INL