add file surport.
This commit is contained in:
parent
fd432b29f6
commit
d0773d8b98
@ -49,8 +49,9 @@ void HttpSession::doRead() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpSession::onRead(boost::beast::error_code ec, std::size_t) {
|
void HttpSession::onRead(boost::beast::error_code ec, std::size_t) {
|
||||||
|
using namespace boost::beast;
|
||||||
// This means they closed the connection
|
// This means they closed the connection
|
||||||
if (ec == boost::beast::http::error::end_of_stream) {
|
if (ec == http::error::end_of_stream) {
|
||||||
m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
|
m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -62,22 +63,28 @@ void HttpSession::onRead(boost::beast::error_code ec, std::size_t) {
|
|||||||
|
|
||||||
auto &request = m_parser->get();
|
auto &request = m_parser->get();
|
||||||
// See if it is a WebSocket Upgrade
|
// See if it is a WebSocket Upgrade
|
||||||
if (boost::beast::websocket::is_upgrade(request)) {
|
if (websocket::is_upgrade(request)) {
|
||||||
// Create a websocket session, transferring ownership
|
// Create a websocket session, transferring ownership
|
||||||
// of both the socket and the HTTP request.
|
// of both the socket and the HTTP request.
|
||||||
auto session = std::make_shared<WebSocketSession>(m_stream.release_socket(), m_state);
|
auto session = std::make_shared<WebSocketSession>(m_stream.release_socket(), m_state);
|
||||||
session->run(m_parser->release());
|
session->run(m_parser->release());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boost::urls::url_view view(request.target());
|
auto path = boost::urls::parse_path(request.target());
|
||||||
auto path = boost::urls::parse_path(view.path());
|
if (!path) {
|
||||||
TemplateMatches matches;
|
LOG(error) << request.target() << "failed, error: " << path.error().message();
|
||||||
|
errorReply(request, http::status::bad_request, "Illegal request-target");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::urls::matches matches;
|
||||||
auto handler = m_state->find(*path, matches);
|
auto handler = m_state->find(*path, matches);
|
||||||
if (handler) {
|
if (handler) {
|
||||||
(*handler)(*this, request, matches);
|
(*handler)(*this, request, matches);
|
||||||
} else {
|
} else {
|
||||||
auto message = "The resource '" + std::string(path->buffer()) + "' was not found.";
|
std::ostringstream oss;
|
||||||
errorReply(request, boost::beast::http::status::not_found, message);
|
oss << "The resource '" << request.target() << "' was not found.";
|
||||||
|
auto message = oss.str();
|
||||||
|
errorReply(request, http::status::not_found, message);
|
||||||
LOG(error) << message;
|
LOG(error) << message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
using Request = boost::beast::http::request<boost::beast::http::string_body>;
|
using Request = boost::beast::http::request<boost::beast::http::string_body>;
|
||||||
HttpSession(boost::asio::ip::tcp::socket &&socket, std::shared_ptr<SharedState> const &state);
|
HttpSession(boost::asio::ip::tcp::socket &&socket, std::shared_ptr<SharedState> const &state);
|
||||||
template <typename Response>
|
template <typename Response>
|
||||||
void reply(const Response &&response) {
|
void reply(Response &&response) {
|
||||||
using ResponseType = typename std::decay_t<decltype(response)>;
|
using ResponseType = typename std::decay_t<decltype(response)>;
|
||||||
auto sp = std::make_shared<ResponseType>(std::forward<decltype(response)>(response));
|
auto sp = std::make_shared<ResponseType>(std::forward<decltype(response)>(response));
|
||||||
boost::beast::http::async_write(
|
boost::beast::http::async_write(
|
||||||
|
@ -2,20 +2,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace ServiceLogic {
|
namespace ServiceLogic {
|
||||||
|
using namespace boost::beast;
|
||||||
boost::beast::http::response<boost::beast::http::string_body>
|
|
||||||
notFound(const boost::beast::http::request<boost::beast::http::string_body> &request) {
|
|
||||||
using namespace boost::beast;
|
|
||||||
http::response<http::string_body> res{http::status::not_found, 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 << "The resource '" << request.target() << "' was not found.";
|
|
||||||
res.body() = oss.str();
|
|
||||||
res.prepare_payload();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::beast::http::response<boost::beast::http::string_body>
|
boost::beast::http::response<boost::beast::http::string_body>
|
||||||
serverError(const boost::beast::http::request<boost::beast::http::string_body> &request,
|
serverError(const boost::beast::http::request<boost::beast::http::string_body> &request,
|
||||||
@ -31,4 +18,15 @@ serverError(const boost::beast::http::request<boost::beast::http::string_body> &
|
|||||||
res.prepare_payload();
|
res.prepare_payload();
|
||||||
return res;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ServiceLogic
|
} // namespace ServiceLogic
|
||||||
|
@ -16,9 +16,6 @@ using StringRequest = boost::beast::http::request<boost::beast::http::string_bod
|
|||||||
|
|
||||||
namespace ServiceLogic {
|
namespace ServiceLogic {
|
||||||
|
|
||||||
template <class Send>
|
|
||||||
static void onDownload(SharedStatePtr /*state*/, StringRequest &&request, Send &&send);
|
|
||||||
|
|
||||||
template <class Send>
|
template <class Send>
|
||||||
static void onGetBlogList(SharedStatePtr state, StringRequest &&request, Send &&send);
|
static void onGetBlogList(SharedStatePtr state, StringRequest &&request, Send &&send);
|
||||||
|
|
||||||
@ -31,14 +28,13 @@ static void onGetBlogImage(SharedStatePtr state, StringRequest &&request, Send &
|
|||||||
template <class Send>
|
template <class Send>
|
||||||
static void onWechat(SharedStatePtr state, StringRequest &&request, Send &&send);
|
static void onWechat(SharedStatePtr state, StringRequest &&request, Send &&send);
|
||||||
|
|
||||||
// Returns a not found response
|
|
||||||
boost::beast::http::response<boost::beast::http::string_body>
|
|
||||||
notFound(const boost::beast::http::request<boost::beast::http::string_body> &request);
|
|
||||||
|
|
||||||
// Returns a server error response
|
// Returns a server error response
|
||||||
boost::beast::http::response<boost::beast::http::string_body>
|
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);
|
serverError(const boost::beast::http::request<boost::beast::http::string_body> &request, std::string_view errorMessage);
|
||||||
|
|
||||||
|
boost::beast::http::response<boost::beast::http::string_body>
|
||||||
|
badRequest(const boost::beast::http::request<boost::beast::http::string_body> &request, std::string_view why);
|
||||||
|
|
||||||
template <class ResponseBody, class RequestBody>
|
template <class ResponseBody, class RequestBody>
|
||||||
boost::beast::http::response<ResponseBody> make_200(const boost::beast::http::request<RequestBody> &request,
|
boost::beast::http::response<ResponseBody> make_200(const boost::beast::http::request<RequestBody> &request,
|
||||||
typename ResponseBody::value_type body,
|
typename ResponseBody::value_type body,
|
||||||
|
@ -14,94 +14,6 @@
|
|||||||
|
|
||||||
namespace ServiceLogic {
|
namespace ServiceLogic {
|
||||||
|
|
||||||
template <class Send>
|
|
||||||
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<char> file_string(std::istreambuf_iterator<char>{ifs}, std::istreambuf_iterator<char>{});
|
|
||||||
boost::beast::error_code ec;
|
|
||||||
http::response<boost::beast::http::vector_body<char>> 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 <class Send>
|
|
||||||
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<char>{ifs}, std::istreambuf_iterator<char>{});
|
|
||||||
http::response<boost::beast::http::string_body> 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 <class Send>
|
|
||||||
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<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::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 <class Send>
|
template <class Send>
|
||||||
static void onWechat(SharedStatePtr state, const StringRequest &request, Send &&send) {
|
static void onWechat(SharedStatePtr state, const StringRequest &request, Send &&send) {
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
|
@ -5,56 +5,75 @@
|
|||||||
#include "WebsocketSession.h"
|
#include "WebsocketSession.h"
|
||||||
|
|
||||||
SharedState::SharedState(boost::asio::io_context &ioContext, std::string doc_root)
|
SharedState::SharedState(boost::asio::io_context &ioContext, std::string doc_root)
|
||||||
: m_ioContext(ioContext), m_router{std::make_shared<UrlRouter<Handler>>()}, m_docRoot(std::move(doc_root)) {
|
: m_ioContext(ioContext), m_router{std::make_shared<boost::urls::router<Handler>>()},
|
||||||
|
m_docRoot(std::move(doc_root)) {
|
||||||
|
|
||||||
m_router->insert("/", [](HttpSession &session, const Request &request, const TemplateMatches &matches) {
|
m_router->insert("/{path*}",[this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
// Send content message to client and wait to receive next request
|
using namespace boost::beast;
|
||||||
session.reply(ServiceLogic::make_200<boost::beast::http::string_body>(request, "Main page\n", "text/html"));
|
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(m_docRoot, target);
|
||||||
|
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.";
|
||||||
|
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.content_length(size);
|
||||||
|
res.keep_alive(request.keep_alive());
|
||||||
|
session.reply(std::move(res));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_router->insert("/wechat/{session*}",
|
m_router->insert("/wechat/{session*}",
|
||||||
[this](HttpSession &session, const Request &request, const TemplateMatches &matches) {
|
[this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
ServiceLogic::onWechat(shared_from_this(), request,
|
ServiceLogic::onWechat(shared_from_this(), request,
|
||||||
[&session](auto &&response) { session.reply(std::move(response)); });
|
[&session](auto &&response) { session.reply(std::move(response)); });
|
||||||
});
|
});
|
||||||
|
|
||||||
// m_router->all(R"(^/download/.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) {
|
m_router->insert("/api/v1/tasklist",[this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
// ServiceLogic::onDownload(shared_from_this(), std::move(request),
|
using namespace boost::beast;
|
||||||
// [&context](auto &&response) { context.send(std::move(response)); });
|
http::response<boost::beast::http::string_body> s;
|
||||||
// });
|
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||||
// m_router->all(R"(^/blog/list$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) {
|
s.set(http::field::content_type, "text/markdown;charset=UTF-8");
|
||||||
// ServiceLogic::onGetBlogList(shared_from_this(), std::move(request),
|
s.keep_alive(request.keep_alive());
|
||||||
// [&context](auto &&response) { context.send(response); });
|
s.body() = "{}";
|
||||||
// });
|
s.prepare_payload();
|
||||||
|
session.reply(std::move(s));
|
||||||
|
});
|
||||||
|
|
||||||
// m_router->all(R"(^/blog/image/.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) {
|
m_router->insert("/trigger-ci.hook", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
// ServiceLogic::onGetBlogImage(shared_from_this(), std::move(request),
|
|
||||||
// [&context](auto &&response) { context.send(std::move(response)); });
|
|
||||||
// });
|
|
||||||
// m_router->all(R"(^/blog/content.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context)
|
|
||||||
// {
|
|
||||||
// ServiceLogic::onGetBlogContent(
|
|
||||||
// shared_from_this(), std::move(request), [&context](auto &&response) { context.send(std::move(response));
|
|
||||||
// },
|
|
||||||
// "/blog/content");
|
|
||||||
// });
|
|
||||||
|
|
||||||
m_router->insert(
|
|
||||||
"/trigger-ci.hook", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) {
|
|
||||||
LOG(info) << "webhook: " << request;
|
LOG(info) << "webhook: " << request;
|
||||||
session.reply(ServiceLogic::make_200<boost::beast::http::string_body>(request, "Main page\n", "text/html"));
|
session.reply(ServiceLogic::make_200<boost::beast::http::string_body>(request, "Main page\n", "text/html"));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_router->insert("/notify", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) {
|
m_router->insert("/notify", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
auto corp = Amass::Singleton<CorporationContext>::instance();
|
auto corp = Amass::Singleton<CorporationContext>::instance();
|
||||||
corp->notify(request);
|
corp->notify(request);
|
||||||
session.reply(
|
session.reply(
|
||||||
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const SharedState::Handler *SharedState::find(boost::urls::segments_encoded_view path,
|
const SharedState::Handler *SharedState::find(boost::urls::segments_encoded_view path,
|
||||||
TemplateMatchStorageBase &matches) const noexcept {
|
boost::urls::matches_base &matches) const noexcept {
|
||||||
return m_router->find(path, matches);
|
return m_router->find(path, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,15 +86,6 @@ void SharedState::setFileRoot(const std::string_view &root) {
|
|||||||
m_fileRoot = root;
|
m_fileRoot = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view SharedState::notebookRoot() const {
|
|
||||||
return m_notebookRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedState::setNotebookRoot(const std::string_view &root) {
|
|
||||||
if (m_notebookRoot == root) return;
|
|
||||||
m_notebookRoot = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedState::join(WebSocketSession *session) {
|
void SharedState::join(WebSocketSession *session) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
sessions_.insert(session);
|
sessions_.insert(session);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#ifndef SHAREDSTATE_H
|
#ifndef SHAREDSTATE_H
|
||||||
#define SHAREDSTATE_H
|
#define SHAREDSTATE_H
|
||||||
|
|
||||||
#include "TemplateMatchs.h"
|
#include "router.hpp"
|
||||||
#include "UrlRouter.h"
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
#include <boost/beast/http/string_body.hpp>
|
#include <boost/beast/http/string_body.hpp>
|
||||||
#include <boost/smart_ptr.hpp>
|
#include <boost/smart_ptr.hpp>
|
||||||
@ -15,7 +14,7 @@ class HttpSession;
|
|||||||
class WebSocketSession;
|
class WebSocketSession;
|
||||||
|
|
||||||
// Represents the shared server state
|
// Represents the shared server state
|
||||||
class SharedState:public std::enable_shared_from_this<SharedState> {
|
class SharedState : public std::enable_shared_from_this<SharedState> {
|
||||||
|
|
||||||
// This mutex synchronizes all access to sessions_
|
// This mutex synchronizes all access to sessions_
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
@ -25,10 +24,10 @@ class SharedState:public std::enable_shared_from_this<SharedState> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using Request = boost::beast::http::request<boost::beast::http::string_body>;
|
using Request = boost::beast::http::request<boost::beast::http::string_body>;
|
||||||
using Handler = std::function<void(HttpSession &, const Request &, const TemplateMatches &)>;
|
using Handler = std::function<void(HttpSession &, const Request &, const boost::urls::matches &)>;
|
||||||
SharedState(boost::asio::io_context &ioContext,std::string doc_root);
|
SharedState(boost::asio::io_context &ioContext, std::string doc_root);
|
||||||
|
|
||||||
const Handler *find(boost::urls::segments_encoded_view path, TemplateMatchStorageBase &matches) const noexcept ;
|
const Handler *find(boost::urls::segments_encoded_view path, boost::urls::matches_base &matches) const noexcept;
|
||||||
|
|
||||||
inline std::string_view docRoot() const noexcept {
|
inline std::string_view docRoot() const noexcept {
|
||||||
return m_docRoot;
|
return m_docRoot;
|
||||||
@ -40,9 +39,6 @@ public:
|
|||||||
}
|
}
|
||||||
void setFileRoot(const std::string_view &root);
|
void setFileRoot(const std::string_view &root);
|
||||||
|
|
||||||
std::string_view notebookRoot() const;
|
|
||||||
void setNotebookRoot(const std::string_view &root);
|
|
||||||
|
|
||||||
void join(WebSocketSession *session);
|
void join(WebSocketSession *session);
|
||||||
void leave(WebSocketSession *session);
|
void leave(WebSocketSession *session);
|
||||||
|
|
||||||
@ -53,11 +49,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::asio::io_context &m_ioContext;
|
boost::asio::io_context &m_ioContext;
|
||||||
std::shared_ptr <UrlRouter<Handler>> m_router;
|
std::shared_ptr<boost::urls::router<Handler>> m_router;
|
||||||
std::string m_docRoot;
|
std::string m_docRoot;
|
||||||
std::string m_galleryRoot = "/root/photos";
|
std::string m_galleryRoot = "/root/photos";
|
||||||
std::string m_fileRoot;
|
std::string m_fileRoot;
|
||||||
std::string m_notebookRoot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using SharedStatePtr = std::shared_ptr<SharedState>;
|
using SharedStatePtr = std::shared_ptr<SharedState>;
|
||||||
|
@ -88,15 +88,6 @@ int main(int argc, char const *argv[]) {
|
|||||||
std::exit(104);
|
std::exit(104);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto notebookRoot = ptree.get<std::string>("notebookRoot");
|
|
||||||
if (notebookRoot.empty()) {
|
|
||||||
LOG(fatal) << "please set notebookRoot.";
|
|
||||||
std::exit(105);
|
|
||||||
} else if (!std::filesystem::exists(notebookRoot)) {
|
|
||||||
LOG(fatal) << "notebook root: " << notebookRoot << " is not exists...";
|
|
||||||
std::exit(106);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!port) {
|
if (!port) {
|
||||||
LOG(fatal) << "port is not a number.";
|
LOG(fatal) << "port is not a number.";
|
||||||
std::exit(255);
|
std::exit(255);
|
||||||
@ -114,7 +105,6 @@ int main(int argc, char const *argv[]) {
|
|||||||
|
|
||||||
auto state = listener->state();
|
auto state = listener->state();
|
||||||
state->setFileRoot(fileRoot);
|
state->setFileRoot(fileRoot);
|
||||||
state->setNotebookRoot(notebookRoot);
|
|
||||||
|
|
||||||
auto wechatContext = Amass::Singleton<WeChatContext>::instance<Amass::Construct>(*ioContext->ioContext());
|
auto wechatContext = Amass::Singleton<WeChatContext>::instance<Amass::Construct>(*ioContext->ioContext());
|
||||||
auto corpContext = Amass::Singleton<CorporationContext>::instance<Amass::Construct>(*ioContext->ioContext());
|
auto corpContext = Amass::Singleton<CorporationContext>::instance<Amass::Construct>(*ioContext->ioContext());
|
||||||
@ -123,7 +113,6 @@ int main(int argc, char const *argv[]) {
|
|||||||
LOG(info) << "working directory: " << prefix.generic_string();
|
LOG(info) << "working directory: " << prefix.generic_string();
|
||||||
LOG(info) << "server: " << server << ",port: " << *port;
|
LOG(info) << "server: " << server << ",port: " << *port;
|
||||||
LOG(info) << "document root: " << state->docRoot();
|
LOG(info) << "document root: " << state->docRoot();
|
||||||
LOG(info) << "notebook root: " << state->notebookRoot();
|
|
||||||
|
|
||||||
// Capture SIGINT and SIGTERM to perform a clean shutdown
|
// Capture SIGINT and SIGTERM to perform a clean shutdown
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -172,9 +161,6 @@ void initSettings() {
|
|||||||
if (ptree.find("fileRoot") == ptree.not_found()) {
|
if (ptree.find("fileRoot") == ptree.not_found()) {
|
||||||
ptree.put("fileRoot", ".");
|
ptree.put("fileRoot", ".");
|
||||||
}
|
}
|
||||||
if (ptree.find("notebookRoot") == ptree.not_found()) {
|
|
||||||
ptree.put("notebookRoot", ".");
|
|
||||||
}
|
|
||||||
if (ptree.find("threads") == ptree.not_found()) {
|
if (ptree.find("threads") == ptree.not_found()) {
|
||||||
ptree.put("threads", std::thread::hardware_concurrency());
|
ptree.put("threads", std::thread::hardware_concurrency());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user