a bit better way to treah handlers
This commit is contained in:
parent
f0d205dee7
commit
3fe6d25448
@ -46,6 +46,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
|||||||
target_compile_options(${PROJECT_NAME} PRIVATE ${COMPILE_OPTIONS})
|
target_compile_options(${PROJECT_NAME} PRIVATE ${COMPILE_OPTIONS})
|
||||||
|
|
||||||
add_subdirectory(server)
|
add_subdirectory(server)
|
||||||
|
add_subdirectory(handler)
|
||||||
add_subdirectory(request)
|
add_subdirectory(request)
|
||||||
add_subdirectory(response)
|
add_subdirectory(response)
|
||||||
add_subdirectory(stream)
|
add_subdirectory(stream)
|
||||||
|
13
handler/CMakeLists.txt
Normal file
13
handler/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
set(HEADERS
|
||||||
|
handler.h
|
||||||
|
info.h
|
||||||
|
env.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
handler.cpp
|
||||||
|
info.cpp
|
||||||
|
env.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
17
handler/env.cpp
Normal file
17
handler/env.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "env.h"
|
||||||
|
|
||||||
|
Handler::Env::Env():
|
||||||
|
Handler("env", Request::Method::get)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Handler::Env::handle(Request& request) {
|
||||||
|
nlohmann::json body = nlohmann::json::object();
|
||||||
|
request.printEnvironment(body);
|
||||||
|
|
||||||
|
Response res(request);
|
||||||
|
res.setBody(body);
|
||||||
|
res.send();
|
||||||
|
}
|
16
handler/env.h
Normal file
16
handler/env.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "handler.h"
|
||||||
|
|
||||||
|
namespace Handler {
|
||||||
|
|
||||||
|
class Env : public Handler::Handler {
|
||||||
|
public:
|
||||||
|
Env();
|
||||||
|
virtual void handle(Request& request);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
11
handler/handler.cpp
Normal file
11
handler/handler.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "handler.h"
|
||||||
|
|
||||||
|
Handler::Handler::Handler(const std::string& path, Request::Method method):
|
||||||
|
path(path),
|
||||||
|
method(method)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Handler::Handler::~Handler() {}
|
26
handler/handler.h
Normal file
26
handler/handler.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "request/request.h"
|
||||||
|
#include "response/response.h"
|
||||||
|
|
||||||
|
namespace Handler {
|
||||||
|
|
||||||
|
class Handler {
|
||||||
|
protected:
|
||||||
|
Handler(const std::string& path, Request::Method method);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Handler();
|
||||||
|
|
||||||
|
virtual void handle(Request& request) = 0;
|
||||||
|
|
||||||
|
const std::string path;
|
||||||
|
const Request::Method method;
|
||||||
|
};
|
||||||
|
}
|
18
handler/info.cpp
Normal file
18
handler/info.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
Handler::Info::Info():
|
||||||
|
Handler("info", Request::Method::get)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Handler::Info::handle(Request& request) {
|
||||||
|
Response res(request);
|
||||||
|
nlohmann::json body = nlohmann::json::object();
|
||||||
|
body["type"] = PROJECT_NAME;
|
||||||
|
body["version"] = PROJECT_VERSION;
|
||||||
|
|
||||||
|
res.setBody(body);
|
||||||
|
res.send();
|
||||||
|
}
|
17
handler/info.h
Normal file
17
handler/info.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "handler.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
namespace Handler {
|
||||||
|
|
||||||
|
class Info : public Handler {
|
||||||
|
public:
|
||||||
|
Info();
|
||||||
|
void handle(Request& request) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
#include "response/response.h"
|
||||||
|
|
||||||
constexpr static const char* GET("GET");
|
constexpr static const char* GET("GET");
|
||||||
|
|
||||||
constexpr static const char* REQUEST_METHOD("REQUEST_METHOD");
|
constexpr static const char* REQUEST_METHOD("REQUEST_METHOD");
|
||||||
@ -16,9 +18,18 @@ constexpr static const char* SERVER_NAME("SERVER_NAME");
|
|||||||
//
|
//
|
||||||
// constexpr static const char* SCRIPT_NAME("SCRIPT_NAME");
|
// constexpr static const char* SCRIPT_NAME("SCRIPT_NAME");
|
||||||
|
|
||||||
|
constexpr std::array<
|
||||||
|
std::pair<std::string_view, Request::Method>,
|
||||||
|
static_cast<uint8_t>(Request::Method::unknown)
|
||||||
|
> methods = {{
|
||||||
|
{"GET", Request::Method::get},
|
||||||
|
{"POST", Request::Method::post}
|
||||||
|
}};
|
||||||
|
|
||||||
Request::Request ():
|
Request::Request ():
|
||||||
state(State::initial),
|
state(State::initial),
|
||||||
raw()
|
raw(),
|
||||||
|
response(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Request::~Request() {
|
Request::~Request() {
|
||||||
@ -36,12 +47,17 @@ void Request::terminate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Request::isGet() const {
|
Request::Method Request::method() const {
|
||||||
if (state != State::accepted)
|
if (state == State::initial)
|
||||||
throw std::runtime_error("An attempt to read request type on a wrong request state");
|
throw std::runtime_error("An attempt to read request method on not accepted request");
|
||||||
|
|
||||||
std::string_view method(FCGX_GetParam(REQUEST_METHOD, raw.envp));
|
std::string_view method(FCGX_GetParam(REQUEST_METHOD, raw.envp));
|
||||||
return method == GET;
|
for (const auto& pair : methods) {
|
||||||
|
if (pair.first == method)
|
||||||
|
return pair.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Request::Method::unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Request::wait(int socketDescriptor) {
|
bool Request::wait(int socketDescriptor) {
|
||||||
@ -59,20 +75,61 @@ bool Request::wait(int socketDescriptor) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStream Request::getOutputStream() {
|
OStream Request::getOutputStream(const Response* response) {
|
||||||
if (state != State::accepted)
|
validateResponse(response);
|
||||||
throw std::runtime_error("An attempt to request output stream on a wrong request state");
|
|
||||||
|
|
||||||
return OStream(raw.out);
|
return OStream(raw.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
OStream Request::getErrorStream() {
|
OStream Request::getErrorStream(const Response* response) {
|
||||||
if (state != State::accepted)
|
validateResponse(response);
|
||||||
throw std::runtime_error("An attempt to request error stream on a wrong request state");
|
|
||||||
|
|
||||||
return OStream(raw.err);
|
return OStream(raw.err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Request::responseIsComplete(const Response* response) {
|
||||||
|
switch (state) {
|
||||||
|
case State::initial:
|
||||||
|
throw std::runtime_error("An attempt to mark the request as complete, but it wasn't even accepted yet");
|
||||||
|
break;
|
||||||
|
case State::accepted:
|
||||||
|
throw std::runtime_error("An attempt to mark the request as complete, but it wasn't responded");
|
||||||
|
break;
|
||||||
|
case State::responding:
|
||||||
|
if (Request::response != response)
|
||||||
|
throw std::runtime_error("An attempt to mark the request as complete by the different response who actually started responding");
|
||||||
|
|
||||||
|
Request::response = nullptr;
|
||||||
|
state = State::responded;
|
||||||
|
break;
|
||||||
|
case State::responded:
|
||||||
|
throw std::runtime_error("An attempt to mark the request as a complete for the second time");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Request::validateResponse(const Response* response) {
|
||||||
|
switch (state) {
|
||||||
|
case State::initial:
|
||||||
|
throw std::runtime_error("An attempt to request stream while the request wasn't even accepted yet");
|
||||||
|
break;
|
||||||
|
case State::accepted:
|
||||||
|
Request::response = response;
|
||||||
|
state = State::responding;
|
||||||
|
break;
|
||||||
|
case State::responding:
|
||||||
|
if (Request::response != response)
|
||||||
|
throw std::runtime_error("Error handling a request: first time one response started replying, then another continued");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case State::responded:
|
||||||
|
throw std::runtime_error("An attempt to request stream on a request that was already done responding");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request::State Request::currentState() const {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Request::getPath(const std::string& serverName) const {
|
std::string Request::getPath(const std::string& serverName) const {
|
||||||
if (state != State::accepted)
|
if (state != State::accepted)
|
||||||
throw std::runtime_error("An attempt to request path on a wrong request state");
|
throw std::runtime_error("An attempt to request path on a wrong request state");
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <fcgiapp.h>
|
#include <fcgiapp.h>
|
||||||
|
|
||||||
@ -13,14 +15,22 @@
|
|||||||
|
|
||||||
#include "stream/ostream.h"
|
#include "stream/ostream.h"
|
||||||
|
|
||||||
|
class Response;
|
||||||
class Request {
|
class Request {
|
||||||
public:
|
public:
|
||||||
enum class State {
|
enum class State {
|
||||||
initial,
|
initial,
|
||||||
accepted,
|
accepted,
|
||||||
|
responding,
|
||||||
responded
|
responded
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Method {
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
unknown
|
||||||
|
};
|
||||||
|
|
||||||
Request();
|
Request();
|
||||||
~Request();
|
~Request();
|
||||||
Request(const Request& other) = delete;
|
Request(const Request& other) = delete;
|
||||||
@ -30,17 +40,24 @@ public:
|
|||||||
|
|
||||||
bool wait(int socketDescriptor);
|
bool wait(int socketDescriptor);
|
||||||
void terminate();
|
void terminate();
|
||||||
bool isGet() const;
|
|
||||||
|
|
||||||
OStream getOutputStream();
|
Method method() const;
|
||||||
OStream getErrorStream();
|
State currentState() const;
|
||||||
|
|
||||||
|
OStream getOutputStream(const Response* response);
|
||||||
|
OStream getErrorStream(const Response* response);
|
||||||
|
void responseIsComplete(const Response* response);
|
||||||
|
|
||||||
std::string getPath(const std::string& serverName) const;
|
std::string getPath(const std::string& serverName) const;
|
||||||
std::string getServerName() const;
|
std::string getServerName() const;
|
||||||
void printEnvironment(std::ostream& out);
|
void printEnvironment(std::ostream& out);
|
||||||
void printEnvironment(nlohmann::json& out);
|
void printEnvironment(nlohmann::json& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void validateResponse(const Response* response);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
State state;
|
State state;
|
||||||
FCGX_Request raw;
|
FCGX_Request raw;
|
||||||
|
const Response* response;
|
||||||
};
|
};
|
||||||
|
@ -15,23 +15,25 @@ constexpr std::array<std::string_view, static_cast<uint8_t>(Response::ContentTyp
|
|||||||
"Content-type: application/json"
|
"Content-type: application/json"
|
||||||
};
|
};
|
||||||
|
|
||||||
Response::Response():
|
Response::Response(Request& request):
|
||||||
|
request(request),
|
||||||
status(Status::ok),
|
status(Status::ok),
|
||||||
type(ContentType::text),
|
type(ContentType::text),
|
||||||
body()
|
body()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Response::Response(Status status):
|
Response::Response(Request& request, Status status):
|
||||||
|
request(request),
|
||||||
status(status),
|
status(status),
|
||||||
type(ContentType::text),
|
type(ContentType::text),
|
||||||
body()
|
body()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Response::replyTo(Request& request) const {
|
void Response::send() const {
|
||||||
// OStream out = status == Status::ok ?
|
// OStream out = status == Status::ok ?
|
||||||
// request.getOutputStream() :
|
// request.getOutputStream() :
|
||||||
// request.getErrorStream();
|
// request.getErrorStream();
|
||||||
OStream out = request.getOutputStream();
|
OStream out = request.getOutputStream(this);
|
||||||
|
|
||||||
out << statusCodes[static_cast<uint8_t>(status)];
|
out << statusCodes[static_cast<uint8_t>(status)];
|
||||||
if (!body.empty())
|
if (!body.empty())
|
||||||
@ -40,6 +42,8 @@ void Response::replyTo(Request& request) const {
|
|||||||
<< '\n'
|
<< '\n'
|
||||||
<< '\n'
|
<< '\n'
|
||||||
<< body;
|
<< body;
|
||||||
|
|
||||||
|
request.responseIsComplete(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::setBody(const std::string& body) {
|
void Response::setBody(const std::string& body) {
|
||||||
|
@ -27,14 +27,15 @@ public:
|
|||||||
json,
|
json,
|
||||||
__size
|
__size
|
||||||
};
|
};
|
||||||
Response();
|
Response(Request& request);
|
||||||
Response(Status status);
|
Response(Request& request, Status status);
|
||||||
|
|
||||||
void replyTo(Request& request) const;
|
void send() const;
|
||||||
void setBody(const std::string& body);
|
void setBody(const std::string& body);
|
||||||
void setBody(const nlohmann::json& body);
|
void setBody(const nlohmann::json& body);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Request& request;
|
||||||
Status status;
|
Status status;
|
||||||
ContentType type;
|
ContentType type;
|
||||||
std::string body;
|
std::string body;
|
||||||
|
@ -4,41 +4,74 @@
|
|||||||
#include "router.h"
|
#include "router.h"
|
||||||
|
|
||||||
Router::Router():
|
Router::Router():
|
||||||
table()
|
get(),
|
||||||
{
|
post()
|
||||||
|
{}
|
||||||
|
|
||||||
}
|
void Router::addRoute(Handler handler) {
|
||||||
|
std::pair<std::map<std::string, Handler>::const_iterator, bool> result;
|
||||||
|
switch (handler->method) {
|
||||||
|
case Request::Method::get:
|
||||||
|
result = get.emplace(handler->path, std::move(handler));
|
||||||
|
break;
|
||||||
|
case Request::Method::post:
|
||||||
|
result = post.emplace(handler->path, std::move(handler));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("An attempt to register handler with unsupported method type: " + std::to_string((int)handler->method));
|
||||||
|
}
|
||||||
|
|
||||||
void Router::addRoute(const std::string& path, const Handler& handler) {
|
|
||||||
auto result = table.emplace(path, handler);
|
|
||||||
if (!result.second)
|
if (!result.second)
|
||||||
std::cerr << "could'not add route " + path + " to the routing table";
|
throw std::runtime_error("could'not add route " + handler->path + " to the routing table");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::route(const std::string& path, std::unique_ptr<Request> request, Server* server) {
|
void Router::route(const std::string& path, std::unique_ptr<Request> request) {
|
||||||
auto itr = table.find(path);
|
std::map<std::string, Handler>::const_iterator itr, end;
|
||||||
if (itr == table.end())
|
switch (request->method()) {
|
||||||
|
case Request::Method::get:
|
||||||
|
itr = get.find(path);
|
||||||
|
end = get.end();
|
||||||
|
break;
|
||||||
|
case Request::Method::post:
|
||||||
|
itr = post.find(path);
|
||||||
|
end = post.end();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return handleMethodNotAllowed(path, std::move(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itr == end)
|
||||||
return handleNotFound(path, std::move(request));
|
return handleNotFound(path, std::move(request));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bool result = itr->second(request.get(), server);
|
itr->second->handle(*request.get());
|
||||||
if (!result)
|
|
||||||
handleInternalError(std::runtime_error("handler failed to handle the request"), std::move(request));
|
if (request->currentState() != Request::State::responded)
|
||||||
|
handleInternalError(path, std::runtime_error("handler failed to handle the request"), std::move(request));
|
||||||
|
else
|
||||||
|
std::cout << "Success:\t" << path << std::endl;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
handleInternalError(e, std::move(request));
|
handleInternalError(path, e, std::move(request));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::handleNotFound(const std::string& path, std::unique_ptr<Request> request) {
|
void Router::handleNotFound(const std::string& path, std::unique_ptr<Request> request) {
|
||||||
Response notFound(Response::Status::notFound);
|
Response notFound(*request.get(), Response::Status::notFound);
|
||||||
notFound.setBody(std::string("Path \"") + path + "\" was not found");
|
notFound.setBody(std::string("Path \"") + path + "\" was not found");
|
||||||
notFound.replyTo(*request.get());
|
notFound.send();
|
||||||
std::cerr << "Not found: " << path << std::endl;
|
std::cerr << "Not found:\t" << path << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::handleInternalError(const std::exception& exception, std::unique_ptr<Request> request) {
|
void Router::handleInternalError(const std::string& path, const std::exception& exception, std::unique_ptr<Request> request) {
|
||||||
Response error(Response::Status::internalError);
|
Response error(*request.get(), Response::Status::internalError);
|
||||||
error.setBody(std::string(exception.what()));
|
error.setBody(std::string(exception.what()));
|
||||||
error.replyTo(*request.get());
|
error.send();
|
||||||
std::cerr << "Internal error: " << exception.what() << std::endl;
|
std::cerr << "Internal error:\t" << path << "\n\t" << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Router::handleMethodNotAllowed(const std::string& path, std::unique_ptr<Request> request) {
|
||||||
|
Response error(*request.get(), Response::Status::methodNotAllowed);
|
||||||
|
error.setBody(std::string("Method not allowed"));
|
||||||
|
error.send();
|
||||||
|
std::cerr << "Method not allowed:\t" << path << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -10,23 +10,25 @@
|
|||||||
|
|
||||||
#include "request/request.h"
|
#include "request/request.h"
|
||||||
#include "response/response.h"
|
#include "response/response.h"
|
||||||
|
#include "handler/handler.h"
|
||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
|
|
||||||
class Router {
|
class Router {
|
||||||
|
using Handler = std::unique_ptr<Handler::Handler>;
|
||||||
public:
|
public:
|
||||||
using Handler = std::function<bool(Request*, Server*)>;
|
|
||||||
|
|
||||||
Router();
|
Router();
|
||||||
|
|
||||||
void addRoute(const std::string& path, const Handler& handler);
|
void addRoute(Handler handler);
|
||||||
void route(const std::string& path, std::unique_ptr<Request> request, Server* server);
|
void route(const std::string& path, std::unique_ptr<Request> request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleNotFound(const std::string& path, std::unique_ptr<Request> request);
|
void handleNotFound(const std::string& path, std::unique_ptr<Request> request);
|
||||||
void handleInternalError(const std::exception& exception, std::unique_ptr<Request> request);
|
void handleInternalError(const std::string& path, const std::exception& exception, std::unique_ptr<Request> request);
|
||||||
|
void handleMethodNotAllowed(const std::string& path, std::unique_ptr<Request> request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, Handler> table;
|
std::map<std::string, Handler> get;
|
||||||
|
std::map<std::string, Handler> post;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
|
#include "handler/info.h"
|
||||||
|
#include "handler/env.h"
|
||||||
|
|
||||||
constexpr uint8_t currentDbVesion = 1;
|
constexpr uint8_t currentDbVesion = 1;
|
||||||
|
|
||||||
Server::Server():
|
Server::Server():
|
||||||
@ -23,8 +26,8 @@ Server::Server():
|
|||||||
db->connect("/run/mysqld/mysqld.sock");
|
db->connect("/run/mysqld/mysqld.sock");
|
||||||
db->migrate(currentDbVesion);
|
db->migrate(currentDbVesion);
|
||||||
|
|
||||||
router.addRoute("info", Server::info);
|
router.addRoute(std::make_unique<Handler::Info>());
|
||||||
router.addRoute("env", Server::printEnvironment);
|
router.addRoute(std::make_unique<Handler::Env>());
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {}
|
Server::~Server() {}
|
||||||
@ -49,49 +52,12 @@ void Server::handleRequest(std::unique_ptr<Request> request) {
|
|||||||
std::cout << "received server name " << serverName.value() << std::endl;
|
std::cout << "received server name " << serverName.value() << std::endl;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
std::cerr << "failed to read server name" << std::endl;
|
std::cerr << "failed to read server name" << std::endl;
|
||||||
Response error(Response::Status::internalError);
|
Response error(*request.get(), Response::Status::internalError);
|
||||||
error.replyTo(*request.get());
|
error.send();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request->isGet()) {
|
|
||||||
static const Response methodNotAllowed(Response::Status::methodNotAllowed);
|
|
||||||
methodNotAllowed.replyTo(*request.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
std::string path = request->getPath(serverName.value());
|
std::string path = request->getPath(serverName.value());
|
||||||
router.route(path.data(), std::move(request), this);
|
router.route(path.data(), std::move(request));
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Response error(Response::Status::internalError);
|
|
||||||
error.setBody(std::string(e.what()));
|
|
||||||
error.replyTo(*request.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::printEnvironment(Request* request, Server* server) {
|
|
||||||
UNUSED(server);
|
|
||||||
nlohmann::json body = nlohmann::json::object();
|
|
||||||
request->printEnvironment(body);
|
|
||||||
|
|
||||||
Response res;
|
|
||||||
res.setBody(body);
|
|
||||||
res.replyTo(*request);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::info(Request* request, Server* server) {
|
|
||||||
UNUSED(server);
|
|
||||||
Response res;
|
|
||||||
nlohmann::json body = nlohmann::json::object();
|
|
||||||
body["type"] = PROJECT_NAME;
|
|
||||||
body["version"] = PROJECT_VERSION;
|
|
||||||
|
|
||||||
res.setBody(body);
|
|
||||||
res.replyTo(*request);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
void handleRequest(std::unique_ptr<Request> request);
|
void handleRequest(std::unique_ptr<Request> request);
|
||||||
|
|
||||||
static bool info(Request* request, Server* server);
|
|
||||||
static bool printEnvironment(Request* request, Server* server);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool terminating;
|
bool terminating;
|
||||||
uint64_t requestCount;
|
uint64_t requestCount;
|
||||||
|
Loading…
Reference in New Issue
Block a user