mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-02 13:47:56 +02:00
Added my web app implementation to the drogon module. Just renamed it and made it compile.
This commit is contained in:
parent
9e0621daf0
commit
c4c9d34e35
@ -5,6 +5,7 @@ Import("env")
|
|||||||
|
|
||||||
env_mod.core_sources = []
|
env_mod.core_sources = []
|
||||||
|
|
||||||
|
env_mod.add_source_files(env_mod.core_sources, "*.cpp")
|
||||||
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/*.cc")
|
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/*.cc")
|
||||||
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/inc/http/*.cc")
|
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/inc/http/*.cc")
|
||||||
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/ssl_funcs/*.cc")
|
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/ssl_funcs/*.cc")
|
||||||
|
13
modules/drogon/handler_instance.cpp
Normal file
13
modules/drogon/handler_instance.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "handler_instance.h"
|
||||||
|
|
||||||
|
#include "request.h"
|
||||||
|
#include "core/object.h"
|
||||||
|
|
||||||
|
DHandlerInstance::DHandlerInstance() {
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHandlerInstance::DHandlerInstance(std::function<void(Object *, DRequest *)> p_handler_func, Object *p_instance) {
|
||||||
|
handler_func = p_handler_func;
|
||||||
|
instance = p_instance;
|
||||||
|
}
|
17
modules/drogon/handler_instance.h
Normal file
17
modules/drogon/handler_instance.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef DHANDLER_INSTANCE_H
|
||||||
|
#define DHANDLER_INSTANCE_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class Object;
|
||||||
|
class DRequest;
|
||||||
|
|
||||||
|
struct DHandlerInstance {
|
||||||
|
std::function<void(Object *, DRequest *)> handler_func;
|
||||||
|
Object *instance;
|
||||||
|
|
||||||
|
DHandlerInstance();
|
||||||
|
DHandlerInstance(std::function<void(Object *, DRequest *)> p_handler_func, Object *p_instance = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
309
modules/drogon/request.cpp
Normal file
309
modules/drogon/request.cpp
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
#include "request.h"
|
||||||
|
|
||||||
|
#include "web_application.h"
|
||||||
|
|
||||||
|
void DRequest::compile_body() {
|
||||||
|
compiled_body.reserve(body.size() + head.size() + 13 + 14 + 15);
|
||||||
|
|
||||||
|
//13
|
||||||
|
compiled_body += "<html>"
|
||||||
|
"<head>";
|
||||||
|
|
||||||
|
compiled_body += head;
|
||||||
|
|
||||||
|
//14
|
||||||
|
compiled_body += "</head>"
|
||||||
|
"<body>";
|
||||||
|
|
||||||
|
compiled_body += body;
|
||||||
|
compiled_body += footer;
|
||||||
|
|
||||||
|
//15
|
||||||
|
compiled_body += "</body>"
|
||||||
|
"</html>";
|
||||||
|
|
||||||
|
response->setBody(compiled_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::compile_and_send_body() {
|
||||||
|
compile_body();
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::next_stage() {
|
||||||
|
if (current_middleware_index == (*middleware_stack).size()) {
|
||||||
|
handler_instance.handler_func(handler_instance.instance, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DHandlerInstance &hi = (*middleware_stack)[current_middleware_index++];
|
||||||
|
|
||||||
|
hi.handler_func(hi.instance, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::send() {
|
||||||
|
//if (connection_closed) {
|
||||||
|
// DRequestPool::return_request(this);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (http_parser->isKeepAlive()) {
|
||||||
|
response->addHeadValue("Connection", "Keep-Alive");
|
||||||
|
|
||||||
|
std::string result = response->getResult();
|
||||||
|
|
||||||
|
session->send(result.c_str(), result.size());
|
||||||
|
} else {
|
||||||
|
response->addHeadValue("Connection", "Close");
|
||||||
|
|
||||||
|
std::string result = response->getResult();
|
||||||
|
|
||||||
|
HttpSession::Ptr lsession = session;
|
||||||
|
|
||||||
|
session->send(result.c_str(), result.size(), [lsession]() { lsession->postShutdown(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequestPool::return_request(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::send_file(const std::string &p_file_path) {
|
||||||
|
//if (connection_closed) {
|
||||||
|
// DRequestPool::return_request(this);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
file_path = p_file_path;
|
||||||
|
|
||||||
|
FILE *f = fopen(file_path.c_str(), "rb");
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
printf("send_file: Error: Download: file doesn't exists! %s\n", file_path.c_str());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
file_size = ftell(f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
response->addHeadValue("Connection", "Close");
|
||||||
|
std::string result = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n";
|
||||||
|
|
||||||
|
application->register_request_update(this);
|
||||||
|
|
||||||
|
session->send(result.c_str(), result.size(), [this]() { this->_file_chunk_sent(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::send_error(int error_code) {
|
||||||
|
application->send_error(error_code, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::reset() {
|
||||||
|
application = nullptr;
|
||||||
|
http_parser = nullptr;
|
||||||
|
session = nullptr;
|
||||||
|
current_middleware_index = 0;
|
||||||
|
middleware_stack = nullptr;
|
||||||
|
_path_stack.clear();
|
||||||
|
_path_stack_pointer = 0;
|
||||||
|
file_size = 0;
|
||||||
|
current_file_progress = 0;
|
||||||
|
connection_closed = false;
|
||||||
|
|
||||||
|
head.clear();
|
||||||
|
body.clear();
|
||||||
|
footer.clear();
|
||||||
|
compiled_body.clear();
|
||||||
|
|
||||||
|
if (response)
|
||||||
|
delete response;
|
||||||
|
|
||||||
|
response = new HttpResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::setup_url_stack() {
|
||||||
|
std::string path = http_parser->getPath();
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
std::string st;
|
||||||
|
while ((pos = path.find("/")) != std::string::npos) {
|
||||||
|
st = path.substr(0, pos);
|
||||||
|
|
||||||
|
if (st.size() != 0)
|
||||||
|
_path_stack.push_back(st);
|
||||||
|
|
||||||
|
path.erase(0, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.size() != 0)
|
||||||
|
_path_stack.push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DRequest::get_path() const {
|
||||||
|
std::string path = "";
|
||||||
|
|
||||||
|
for (uint32_t i = _path_stack_pointer; i < _path_stack.size(); ++i) {
|
||||||
|
path += _path_stack[i];
|
||||||
|
path += "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &DRequest::get_path_full() const {
|
||||||
|
return http_parser->getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &DRequest::get_path_segment(const uint32_t i) const {
|
||||||
|
return _path_stack[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &DRequest::get_current_path_segment() const {
|
||||||
|
if (_path_stack_pointer >= _path_stack.size()) {
|
||||||
|
//for convenience
|
||||||
|
static const std::string e_str = "";
|
||||||
|
return e_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _path_stack[_path_stack_pointer];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DRequest::get_path_segment_count() const {
|
||||||
|
return _path_stack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DRequest::get_current_segment_index() const {
|
||||||
|
return _path_stack_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DRequest::get_remaining_segment_count() const {
|
||||||
|
if (_path_stack_pointer > _path_stack.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _path_stack.size() - _path_stack_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::pop_path() {
|
||||||
|
_path_stack_pointer -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::push_path() {
|
||||||
|
_path_stack_pointer += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::update() {
|
||||||
|
if (file_next) {
|
||||||
|
file_next = false;
|
||||||
|
_progress_send_file();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequest::DRequest() {
|
||||||
|
response = nullptr;
|
||||||
|
|
||||||
|
//This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower
|
||||||
|
//It is a tradeoff on server memory though, as every active download will consume this amount of memory
|
||||||
|
//where the file is bigger than this number
|
||||||
|
file_chunk_size = 1 << 21; //2MB
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequest::~DRequest() {
|
||||||
|
delete response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::_progress_send_file() {
|
||||||
|
if (connection_closed) {
|
||||||
|
DRequestPool::return_request(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_file_progress >= file_size) {
|
||||||
|
session->postShutdown();
|
||||||
|
|
||||||
|
DRequestPool::return_request(this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(file_path.c_str(), "rb");
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
printf("Error: Download: In progress file doesn't exists anymore! %s\n", file_path.c_str());
|
||||||
|
|
||||||
|
application->unregister_request_update(this);
|
||||||
|
|
||||||
|
session->postShutdown();
|
||||||
|
|
||||||
|
DRequestPool::return_request(this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, current_file_progress, SEEK_SET);
|
||||||
|
|
||||||
|
long nfp = current_file_progress + file_chunk_size;
|
||||||
|
|
||||||
|
long csize = file_chunk_size;
|
||||||
|
if (nfp >= file_size) {
|
||||||
|
csize = (file_size - current_file_progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.resize(csize);
|
||||||
|
|
||||||
|
fread(&body[0], 1, csize, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
current_file_progress = nfp;
|
||||||
|
|
||||||
|
session->send(body.c_str(), body.size(), [this]() { this->_file_chunk_sent(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequest::_file_chunk_sent() {
|
||||||
|
file_next = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequest *DRequestPool::get_request() {
|
||||||
|
_mutex.lock();
|
||||||
|
|
||||||
|
DRequest *request;
|
||||||
|
|
||||||
|
if (_requests.size() == 0) {
|
||||||
|
_mutex.unlock();
|
||||||
|
|
||||||
|
request = new DRequest();
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = _requests[_requests.size() - 1];
|
||||||
|
_requests.pop_back();
|
||||||
|
|
||||||
|
_mutex.unlock();
|
||||||
|
|
||||||
|
request->reset();
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRequestPool::return_request(DRequest *request) {
|
||||||
|
_mutex.lock();
|
||||||
|
_requests.push_back(request);
|
||||||
|
_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequestPool::DRequestPool() {
|
||||||
|
}
|
||||||
|
|
||||||
|
DRequestPool::~DRequestPool() {
|
||||||
|
for (uint32_t i = 0; i < _requests.size(); ++i) {
|
||||||
|
delete _requests[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
_requests.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::mutex DRequestPool::_mutex;
|
||||||
|
std::vector<DRequest *> DRequestPool::_requests;
|
83
modules/drogon/request.h
Normal file
83
modules/drogon/request.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#ifndef DREQUEST_H
|
||||||
|
#define REQUEST_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <brynet/net/http/HttpFormat.hpp>
|
||||||
|
#include <brynet/net/http/HttpService.hpp>
|
||||||
|
|
||||||
|
#include "handler_instance.h"
|
||||||
|
|
||||||
|
class DWebApplication;
|
||||||
|
|
||||||
|
class DRequest {
|
||||||
|
public:
|
||||||
|
HTTPParser::Ptr http_parser;
|
||||||
|
HttpSession::Ptr session;
|
||||||
|
HttpResponse *response;
|
||||||
|
DWebApplication *application;
|
||||||
|
|
||||||
|
uint32_t current_middleware_index;
|
||||||
|
DHandlerInstance handler_instance;
|
||||||
|
std::vector<DHandlerInstance> *middleware_stack;
|
||||||
|
|
||||||
|
std::string head;
|
||||||
|
std::string body;
|
||||||
|
std::string footer;
|
||||||
|
std::string compiled_body;
|
||||||
|
|
||||||
|
std::string file_path;
|
||||||
|
long file_size;
|
||||||
|
long current_file_progress;
|
||||||
|
long file_chunk_size;
|
||||||
|
bool file_next;
|
||||||
|
|
||||||
|
bool connection_closed;
|
||||||
|
|
||||||
|
void compile_body();
|
||||||
|
void compile_and_send_body();
|
||||||
|
void next_stage();
|
||||||
|
void send();
|
||||||
|
void send_file(const std::string &p_file_path);
|
||||||
|
void send_error(int error_code);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void setup_url_stack();
|
||||||
|
std::string get_path() const;
|
||||||
|
const std::string &get_path_full() const;
|
||||||
|
const std::string &get_path_segment(const uint32_t i) const;
|
||||||
|
const std::string &get_current_path_segment() const;
|
||||||
|
uint32_t get_path_segment_count() const;
|
||||||
|
uint32_t get_current_segment_index() const;
|
||||||
|
uint32_t get_remaining_segment_count() const;
|
||||||
|
void pop_path();
|
||||||
|
void push_path();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
DRequest();
|
||||||
|
~DRequest();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _progress_send_file();
|
||||||
|
void _file_chunk_sent();
|
||||||
|
|
||||||
|
std::vector<std::string> _path_stack;
|
||||||
|
uint32_t _path_stack_pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DRequestPool {
|
||||||
|
public:
|
||||||
|
static DRequest *get_request();
|
||||||
|
static void return_request(DRequest *request);
|
||||||
|
|
||||||
|
DRequestPool();
|
||||||
|
~DRequestPool();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static std::mutex _mutex;
|
||||||
|
static std::vector<DRequest *> _requests;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
140
modules/drogon/web_application.cpp
Normal file
140
modules/drogon/web_application.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#include "web_application.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "request.h"
|
||||||
|
|
||||||
|
#include "core/file_cache.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void DWebApplication::load_settings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::setup_routes() {
|
||||||
|
default_error_handler_func = DWebApplication::default_fallback_error_handler;
|
||||||
|
|
||||||
|
error_handler_map[404] = DWebApplication::default_404_error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::setup_middleware() {
|
||||||
|
middlewares.push_back(DHandlerInstance([this](Object *instance, DRequest *request){ this->default_routing_middleware(instance, request); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::default_routing_middleware(Object *instance, DRequest *request) {
|
||||||
|
std::string path = request->http_parser->getPath();
|
||||||
|
|
||||||
|
if (FileCache::get_singleton()->wwwroot_has_file(path)) {
|
||||||
|
send_file(path, request);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHandlerInstance handler_data;
|
||||||
|
|
||||||
|
//std::function<void(Object *, Request *)> func;
|
||||||
|
|
||||||
|
//if (path == "/") {
|
||||||
|
if (request->get_path_segment_count() == 0) {
|
||||||
|
//quick shortcut
|
||||||
|
handler_data = index_func;
|
||||||
|
} else {
|
||||||
|
const std::string main_route = request->get_current_path_segment();
|
||||||
|
|
||||||
|
handler_data = main_route_map[main_route];
|
||||||
|
|
||||||
|
request->push_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler_data.handler_func) {
|
||||||
|
send_error(404, request);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->handler_instance = handler_data;
|
||||||
|
request->next_stage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::default_fallback_error_handler(int error_code, DRequest *request) {
|
||||||
|
request->response->setBody(default_generic_error_body);
|
||||||
|
request->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::default_404_error_handler(int error_code, DRequest *request) {
|
||||||
|
request->response->setBody(default_error_404_body);
|
||||||
|
request->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::handle_request(DRequest *request) {
|
||||||
|
request->middleware_stack = &middlewares;
|
||||||
|
|
||||||
|
//note that middlewares handle the routing -> DWebApplication::default_routing_middleware by default
|
||||||
|
request->next_stage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::send_error(int error_code, DRequest *request) {
|
||||||
|
std::function<void(int, DRequest *)> func = error_handler_map[error_code];
|
||||||
|
|
||||||
|
if (!func) {
|
||||||
|
default_error_handler_func(error_code, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func(error_code, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::send_file(const std::string &path, DRequest *request) {
|
||||||
|
std::string fp = FileCache::get_singleton()->wwwroot + path;
|
||||||
|
|
||||||
|
request->send_file(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::migrate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::register_request_update(DRequest *request) {
|
||||||
|
std::lock_guard<std::mutex> lock(_update_registered_requests_mutex);
|
||||||
|
|
||||||
|
_update_registered_requests.push_back(request);
|
||||||
|
}
|
||||||
|
void DWebApplication::unregister_request_update(DRequest *request) {
|
||||||
|
std::lock_guard<std::mutex> lock(_update_registered_requests_mutex);
|
||||||
|
|
||||||
|
std::size_t s = _update_registered_requests.size();
|
||||||
|
for (std::size_t i = 0; i < s; ++i) {
|
||||||
|
DRequest *r = _update_registered_requests[i];
|
||||||
|
|
||||||
|
if (r == request) {
|
||||||
|
_update_registered_requests[i] = _update_registered_requests[s - 1];
|
||||||
|
|
||||||
|
_update_registered_requests.pop_back();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWebApplication::update() {
|
||||||
|
for (std::size_t i = 0; i < _update_registered_requests.size(); ++i) {
|
||||||
|
DRequest *r = _update_registered_requests[i];
|
||||||
|
|
||||||
|
r->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWebApplication::DWebApplication() {
|
||||||
|
}
|
||||||
|
|
||||||
|
DWebApplication::~DWebApplication() {
|
||||||
|
main_route_map.clear();
|
||||||
|
error_handler_map.clear();
|
||||||
|
middlewares.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DWebApplication::default_error_404_body = "<html><body>404 :(</body></html>";
|
||||||
|
std::string DWebApplication::default_generic_error_body = "<html><body>Internal server error! :(</body></html>";
|
56
modules/drogon/web_application.h
Normal file
56
modules/drogon/web_application.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#ifndef DWEB_APPLICATION_H
|
||||||
|
#define WEB_APPLICATION_H
|
||||||
|
|
||||||
|
#include "core/object.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "handler_instance.h"
|
||||||
|
|
||||||
|
class DRequest;
|
||||||
|
|
||||||
|
class DWebApplication {
|
||||||
|
public:
|
||||||
|
static std::string default_error_404_body;
|
||||||
|
static std::string default_generic_error_body;
|
||||||
|
|
||||||
|
void handle_request(DRequest *request);
|
||||||
|
void send_error(int error_code, DRequest *request);
|
||||||
|
void send_file(const std::string &path, DRequest *request);
|
||||||
|
|
||||||
|
static void default_fallback_error_handler(int error_code, DRequest *request);
|
||||||
|
static void default_404_error_handler(int error_code, DRequest *request);
|
||||||
|
|
||||||
|
virtual void load_settings();
|
||||||
|
virtual void setup_routes();
|
||||||
|
virtual void setup_middleware();
|
||||||
|
|
||||||
|
void default_routing_middleware(Object *instance, DRequest *request);
|
||||||
|
|
||||||
|
virtual void migrate();
|
||||||
|
|
||||||
|
void register_request_update(DRequest *request);
|
||||||
|
void unregister_request_update(DRequest *request);
|
||||||
|
void update();
|
||||||
|
|
||||||
|
DWebApplication();
|
||||||
|
virtual ~DWebApplication();
|
||||||
|
|
||||||
|
public:
|
||||||
|
DHandlerInstance index_func;
|
||||||
|
std::map<std::string, DHandlerInstance> main_route_map;
|
||||||
|
std::vector<DHandlerInstance> middlewares;
|
||||||
|
|
||||||
|
std::map<int, std::function<void(int, DRequest *)> > error_handler_map;
|
||||||
|
std::function<void(int, DRequest *)> default_error_handler_func;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::mutex _update_registered_requests_mutex;
|
||||||
|
std::vector<DRequest *> _update_registered_requests;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user