mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-04-20 01:43:12 +02:00
Made Request a base inheritable class, and made DRequest inherit from it. Also added BryRequest for the brynet backend. Also made DWebApplication inherit from WebApplication.
This commit is contained in:
parent
f03b983de2
commit
29dabe752f
163
core/bry_http/bry_request.cpp
Normal file
163
core/bry_http/bry_request.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
#include "bry_request.h"
|
||||
|
||||
#include "web_application.h"
|
||||
|
||||
void BryRequest::send() {
|
||||
//if (connection_closed) {
|
||||
// RequestPool::return_request(this);
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (http_parser->isKeepAlive()) {
|
||||
response->addHeadValue("Connection", "Keep-Alive");
|
||||
|
||||
response->setBody(compiled_body);
|
||||
|
||||
std::string result = response->getResult();
|
||||
|
||||
session->send(result.c_str(), result.size());
|
||||
} else {
|
||||
response->addHeadValue("Connection", "Close");
|
||||
|
||||
response->setBody(compiled_body);
|
||||
|
||||
std::string result = response->getResult();
|
||||
|
||||
HttpSession::Ptr lsession = session;
|
||||
|
||||
session->send(result.c_str(), result.size(), [lsession]() { lsession->postShutdown(); });
|
||||
}
|
||||
|
||||
pool();
|
||||
}
|
||||
|
||||
void BryRequest::send_file(const std::string &p_file_path) {
|
||||
//if (connection_closed) {
|
||||
// RequestPool::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 BryRequest::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;
|
||||
|
||||
//todo fix
|
||||
//response = new HttpResponse();
|
||||
}
|
||||
|
||||
void BryRequest::update() {
|
||||
if (file_next) {
|
||||
file_next = false;
|
||||
_progress_send_file();
|
||||
}
|
||||
}
|
||||
|
||||
BryRequest *BryRequest::get() {
|
||||
return _request_pool.get_request();
|
||||
}
|
||||
void BryRequest::pool(BryRequest *request) {
|
||||
return _request_pool.return_request(request);
|
||||
}
|
||||
void BryRequest::pool() {
|
||||
BryRequest::pool(this);
|
||||
}
|
||||
|
||||
BryRequest::BryRequest() :
|
||||
Request() {
|
||||
response = nullptr;
|
||||
}
|
||||
|
||||
BryRequest::~BryRequest() {
|
||||
delete response;
|
||||
}
|
||||
|
||||
void BryRequest::_progress_send_file() {
|
||||
if (connection_closed) {
|
||||
pool();
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_file_progress >= file_size) {
|
||||
session->postShutdown();
|
||||
|
||||
pool();
|
||||
|
||||
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();
|
||||
|
||||
pool();
|
||||
|
||||
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 BryRequest::_file_chunk_sent() {
|
||||
file_next = true;
|
||||
}
|
||||
|
||||
RequestPool<BryRequest> BryRequest::_request_pool;
|
47
core/bry_http/bry_request.h
Normal file
47
core/bry_http/bry_request.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef BRY_REQUEST_H
|
||||
#define BRY_REQUEST_H
|
||||
|
||||
#include "core/http/request.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <brynet/net/http/HttpFormat.hpp>
|
||||
#include <brynet/net/http/HttpService.hpp>
|
||||
|
||||
#include "core/http/handler_instance.h"
|
||||
|
||||
class WebApplication;
|
||||
|
||||
class BryRequest : public Request {
|
||||
public:
|
||||
HTTPParser::Ptr http_parser;
|
||||
HttpSession::Ptr session;
|
||||
HttpResponse *response;
|
||||
|
||||
void send();
|
||||
void send_file(const std::string &p_file_path);
|
||||
void reset();
|
||||
|
||||
void update();
|
||||
|
||||
static BryRequest *get();
|
||||
static void pool(BryRequest *request);
|
||||
void pool();
|
||||
|
||||
BryRequest();
|
||||
~BryRequest();
|
||||
|
||||
protected:
|
||||
void _progress_send_file();
|
||||
void _file_chunk_sent();
|
||||
|
||||
std::vector<std::string> _path_stack;
|
||||
uint32_t _path_stack_pointer;
|
||||
|
||||
private:
|
||||
static RequestPool<BryRequest> _request_pool;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
#include "http_server.h"
|
||||
|
||||
#include "core/http/web_application.h"
|
||||
#include "core/http/request.h"
|
||||
#include "bry_request.h"
|
||||
|
||||
#define LOG_VERBOSE 0
|
||||
|
||||
@ -12,7 +12,7 @@ void HTTPServer::http_callback_handler(Request *request) {
|
||||
void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session) {
|
||||
std::unique_lock<std::mutex> lock(_request_map_mutex, std::defer_lock);
|
||||
|
||||
Request *request = RequestPool::get_request();
|
||||
BryRequest *request = BryRequest::get();
|
||||
|
||||
HttpSession *s = session.get();
|
||||
|
||||
|
@ -22,7 +22,7 @@ void Request::compile_body() {
|
||||
compiled_body += "</body>"
|
||||
"</html>";
|
||||
|
||||
response->setBody(compiled_body);
|
||||
//response->setBody(compiled_body);
|
||||
}
|
||||
|
||||
void Request::compile_and_send_body() {
|
||||
@ -47,51 +47,11 @@ void Request::send() {
|
||||
// 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(); });
|
||||
}
|
||||
|
||||
RequestPool::return_request(this);
|
||||
//RequestPool::return_request(this);
|
||||
}
|
||||
|
||||
void Request::send_file(const std::string &p_file_path) {
|
||||
//if (connection_closed) {
|
||||
// RequestPool::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(); });
|
||||
//RequestPool::return_request(this);
|
||||
}
|
||||
|
||||
void Request::send_error(int error_code) {
|
||||
@ -100,8 +60,6 @@ void Request::send_error(int error_code) {
|
||||
|
||||
void Request::reset() {
|
||||
application = nullptr;
|
||||
http_parser = nullptr;
|
||||
session = nullptr;
|
||||
current_middleware_index = 0;
|
||||
middleware_stack = nullptr;
|
||||
_path_stack.clear();
|
||||
@ -114,15 +72,16 @@ void Request::reset() {
|
||||
body.clear();
|
||||
footer.clear();
|
||||
compiled_body.clear();
|
||||
}
|
||||
|
||||
if (response)
|
||||
delete response;
|
||||
|
||||
response = new HttpResponse();
|
||||
std::string Request::parser_get_path() {
|
||||
return "";
|
||||
//return http_parser->getPath();
|
||||
}
|
||||
|
||||
void Request::setup_url_stack() {
|
||||
std::string path = http_parser->getPath();
|
||||
_full_path = parser_get_path();
|
||||
std::string path = parser_get_path();
|
||||
|
||||
size_t pos = 0;
|
||||
std::string st;
|
||||
@ -151,7 +110,7 @@ std::string Request::get_path() const {
|
||||
}
|
||||
|
||||
const std::string &Request::get_path_full() const {
|
||||
return http_parser->getPath();
|
||||
return _full_path;
|
||||
}
|
||||
|
||||
const std::string &Request::get_path_segment(const uint32_t i) const {
|
||||
@ -193,15 +152,12 @@ void Request::push_path() {
|
||||
}
|
||||
|
||||
void Request::update() {
|
||||
if (file_next) {
|
||||
file_next = false;
|
||||
_progress_send_file();
|
||||
}
|
||||
}
|
||||
|
||||
void Request::pool() {
|
||||
}
|
||||
|
||||
Request::Request() {
|
||||
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
|
||||
@ -211,99 +167,4 @@ Request::Request() {
|
||||
}
|
||||
|
||||
Request::~Request() {
|
||||
delete response;
|
||||
}
|
||||
|
||||
void Request::_progress_send_file() {
|
||||
if (connection_closed) {
|
||||
RequestPool::return_request(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_file_progress >= file_size) {
|
||||
session->postShutdown();
|
||||
|
||||
RequestPool::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();
|
||||
|
||||
RequestPool::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 Request::_file_chunk_sent() {
|
||||
file_next = true;
|
||||
}
|
||||
|
||||
Request *RequestPool::get_request() {
|
||||
_mutex.lock();
|
||||
|
||||
Request *request;
|
||||
|
||||
if (_requests.size() == 0) {
|
||||
_mutex.unlock();
|
||||
|
||||
request = new Request();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
request = _requests[_requests.size() - 1];
|
||||
_requests.pop_back();
|
||||
|
||||
_mutex.unlock();
|
||||
|
||||
request->reset();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
void RequestPool::return_request(Request *request) {
|
||||
_mutex.lock();
|
||||
_requests.push_back(request);
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
RequestPool::RequestPool() {
|
||||
}
|
||||
|
||||
RequestPool::~RequestPool() {
|
||||
for (uint32_t i = 0; i < _requests.size(); ++i) {
|
||||
delete _requests[i];
|
||||
}
|
||||
|
||||
_requests.clear();
|
||||
}
|
||||
|
||||
std::mutex RequestPool::_mutex;
|
||||
std::vector<Request *> RequestPool::_requests;
|
||||
|
@ -4,18 +4,12 @@
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <brynet/net/http/HttpFormat.hpp>
|
||||
#include <brynet/net/http/HttpService.hpp>
|
||||
|
||||
#include "handler_instance.h"
|
||||
|
||||
class WebApplication;
|
||||
|
||||
class Request {
|
||||
public:
|
||||
HTTPParser::Ptr http_parser;
|
||||
HttpSession::Ptr session;
|
||||
HttpResponse *response;
|
||||
WebApplication *application;
|
||||
|
||||
uint32_t current_middleware_index;
|
||||
@ -35,17 +29,18 @@ public:
|
||||
|
||||
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();
|
||||
virtual void compile_body();
|
||||
virtual void compile_and_send_body();
|
||||
virtual void next_stage();
|
||||
virtual void send();
|
||||
virtual void send_file(const std::string &p_file_path);
|
||||
virtual void send_error(int error_code);
|
||||
virtual void reset();
|
||||
virtual std::string parser_get_path();
|
||||
|
||||
void setup_url_stack();
|
||||
std::string get_path() const;
|
||||
const std::string &get_path_full() const;
|
||||
virtual 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;
|
||||
@ -54,30 +49,76 @@ public:
|
||||
void pop_path();
|
||||
void push_path();
|
||||
|
||||
void update();
|
||||
virtual void update();
|
||||
virtual void pool();
|
||||
|
||||
Request();
|
||||
~Request();
|
||||
virtual ~Request();
|
||||
|
||||
protected:
|
||||
void _progress_send_file();
|
||||
void _file_chunk_sent();
|
||||
|
||||
std::string _full_path;
|
||||
std::vector<std::string> _path_stack;
|
||||
uint32_t _path_stack_pointer;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class RequestPool {
|
||||
public:
|
||||
static Request *get_request();
|
||||
static void return_request(Request *request);
|
||||
T *get_request();
|
||||
void return_request(T *request);
|
||||
|
||||
RequestPool();
|
||||
~RequestPool();
|
||||
|
||||
protected:
|
||||
static std::mutex _mutex;
|
||||
static std::vector<Request *> _requests;
|
||||
std::mutex _mutex;
|
||||
std::vector<T *> _requests;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T *RequestPool<T>::get_request() {
|
||||
_mutex.lock();
|
||||
|
||||
T *request;
|
||||
|
||||
if (_requests.size() == 0) {
|
||||
_mutex.unlock();
|
||||
|
||||
request = new T();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
request = _requests[_requests.size() - 1];
|
||||
_requests.pop_back();
|
||||
|
||||
_mutex.unlock();
|
||||
|
||||
request->reset();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void RequestPool<T>::return_request(T *request) {
|
||||
_mutex.lock();
|
||||
_requests.push_back(request);
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
RequestPool<T>::RequestPool() {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
RequestPool<T>::~RequestPool() {
|
||||
for (uint32_t i = 0; i < _requests.size(); ++i) {
|
||||
delete _requests[i];
|
||||
}
|
||||
|
||||
_requests.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -26,7 +26,7 @@ void WebApplication::setup_middleware() {
|
||||
}
|
||||
|
||||
void WebApplication::default_routing_middleware(Object *instance, Request *request) {
|
||||
std::string path = request->http_parser->getPath();
|
||||
std::string path = request->get_path_full();
|
||||
|
||||
if (FileCache::get_singleton()->wwwroot_has_file(path)) {
|
||||
send_file(path, request);
|
||||
@ -61,12 +61,13 @@ void WebApplication::default_routing_middleware(Object *instance, Request *reque
|
||||
}
|
||||
|
||||
void WebApplication::default_fallback_error_handler(int error_code, Request *request) {
|
||||
request->response->setBody(default_generic_error_body);
|
||||
request->compiled_body = default_generic_error_body;
|
||||
|
||||
request->send();
|
||||
}
|
||||
|
||||
void WebApplication::default_404_error_handler(int error_code, Request *request) {
|
||||
request->response->setBody(default_error_404_body);
|
||||
request->compiled_body = default_error_404_body;
|
||||
request->send();
|
||||
}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
#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;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#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
|
@ -2,49 +2,6 @@
|
||||
|
||||
#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);
|
||||
|
||||
//request->response->setBody("<p>Hello, world!</p>");
|
||||
//request->response->setExpiredTime(0);
|
||||
//request->callback(request->response);
|
||||
}
|
||||
|
||||
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);
|
||||
@ -54,7 +11,7 @@ void DRequest::send() {
|
||||
//response->setExpiredTime(0);
|
||||
callback(response);
|
||||
|
||||
DRequestPool::return_request(this);
|
||||
pool();
|
||||
}
|
||||
|
||||
void DRequest::send_file(const std::string &p_file_path) {
|
||||
@ -84,10 +41,8 @@ void DRequest::send_file(const std::string &p_file_path) {
|
||||
|
||||
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);
|
||||
pool();
|
||||
}
|
||||
|
||||
void DRequest::reset() {
|
||||
@ -111,81 +66,6 @@ void DRequest::reset() {
|
||||
//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 {
|
||||
static std::string a = "";
|
||||
return a;
|
||||
//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;
|
||||
@ -193,6 +73,16 @@ void DRequest::update() {
|
||||
}
|
||||
}
|
||||
|
||||
DRequest *DRequest::get() {
|
||||
return _request_pool.get_request();
|
||||
}
|
||||
void DRequest::pool(DRequest *request) {
|
||||
return _request_pool.return_request(request);
|
||||
}
|
||||
void DRequest::pool() {
|
||||
DRequest::pool(this);
|
||||
}
|
||||
|
||||
DRequest::DRequest() {
|
||||
|
||||
//This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower
|
||||
@ -259,45 +149,5 @@ 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;
|
||||
RequestPool<DRequest> DRequest::_request_pool;
|
@ -1,64 +1,36 @@
|
||||
#ifndef DREQUEST_H
|
||||
#define DREQUEST_H
|
||||
|
||||
#include "core/http/request.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "http/HttpRequestImpl.h"
|
||||
#include "http/HttpResponse.h"
|
||||
|
||||
#include "handler_instance.h"
|
||||
#include "core/http/handler_instance.h"
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
class DWebApplication;
|
||||
|
||||
class DRequest {
|
||||
class DRequest : public Request {
|
||||
public:
|
||||
HttpResponsePtr response;
|
||||
HttpRequestImplPtr request;
|
||||
std::function<void(const HttpResponsePtr &)> callback;
|
||||
|
||||
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();
|
||||
|
||||
static DRequest *get();
|
||||
static void pool(DRequest *request);
|
||||
void pool();
|
||||
|
||||
DRequest();
|
||||
~DRequest();
|
||||
|
||||
@ -68,19 +40,9 @@ protected:
|
||||
|
||||
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;
|
||||
private:
|
||||
static RequestPool<DRequest> _request_pool;
|
||||
};
|
||||
|
||||
#endif
|
@ -31,16 +31,16 @@ void DWebApplication::load_settings() {
|
||||
}
|
||||
|
||||
void DWebApplication::setup_routes() {
|
||||
default_error_handler_func = DWebApplication::default_fallback_error_handler;
|
||||
default_error_handler_func = WebApplication::default_fallback_error_handler;
|
||||
|
||||
error_handler_map[404] = DWebApplication::default_404_error_handler;
|
||||
error_handler_map[404] = WebApplication::default_404_error_handler;
|
||||
}
|
||||
|
||||
void DWebApplication::setup_middleware() {
|
||||
middlewares.push_back(DHandlerInstance([this](Object *instance, DRequest *request) { this->default_routing_middleware(instance, request); }));
|
||||
middlewares.push_back(HandlerInstance([this](Object *instance, Request *request) { this->default_routing_middleware(instance, request); }));
|
||||
}
|
||||
|
||||
void DWebApplication::default_routing_middleware(Object *instance, DRequest *request) {
|
||||
void DWebApplication::default_routing_middleware(Object *instance, Request *request) {
|
||||
/*
|
||||
std::string path = request->http_parser->getPath();
|
||||
|
||||
@ -77,17 +77,7 @@ void DWebApplication::default_routing_middleware(Object *instance, DRequest *req
|
||||
*/
|
||||
}
|
||||
|
||||
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) {
|
||||
void DWebApplication::handle_request(Request *request) {
|
||||
request->middleware_stack = &middlewares;
|
||||
|
||||
//note that middlewares handle the routing -> DWebApplication::default_routing_middleware by default
|
||||
@ -102,11 +92,11 @@ void DWebApplication::handle_request(DRequest *request) {
|
||||
//request->response->setExpiredTime(0);
|
||||
//request->callback(request->response);
|
||||
|
||||
DRequestPool::return_request(request);
|
||||
request->pool();
|
||||
}
|
||||
|
||||
void DWebApplication::send_error(int error_code, DRequest *request) {
|
||||
std::function<void(int, DRequest *)> func = error_handler_map[error_code];
|
||||
void DWebApplication::send_error(int error_code, Request *request) {
|
||||
std::function<void(int, Request *)> func = error_handler_map[error_code];
|
||||
|
||||
if (!func) {
|
||||
default_error_handler_func(error_code, request);
|
||||
@ -116,7 +106,7 @@ void DWebApplication::send_error(int error_code, DRequest *request) {
|
||||
func(error_code, request);
|
||||
}
|
||||
|
||||
void DWebApplication::send_file(const std::string &path, DRequest *request) {
|
||||
void DWebApplication::send_file(const std::string &path, Request *request) {
|
||||
std::string fp = FileCache::get_singleton()->wwwroot + path;
|
||||
|
||||
request->send_file(fp);
|
||||
@ -125,17 +115,17 @@ void DWebApplication::send_file(const std::string &path, DRequest *request) {
|
||||
void DWebApplication::migrate() {
|
||||
}
|
||||
|
||||
void DWebApplication::register_request_update(DRequest *request) {
|
||||
void DWebApplication::register_request_update(Request *request) {
|
||||
std::lock_guard<std::mutex> lock(_update_registered_requests_mutex);
|
||||
|
||||
_update_registered_requests.push_back(request);
|
||||
}
|
||||
void DWebApplication::unregister_request_update(DRequest *request) {
|
||||
void DWebApplication::unregister_request_update(Request *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];
|
||||
Request *r = _update_registered_requests[i];
|
||||
|
||||
if (r == request) {
|
||||
_update_registered_requests[i] = _update_registered_requests[s - 1];
|
||||
@ -149,7 +139,7 @@ void DWebApplication::unregister_request_update(DRequest *request) {
|
||||
|
||||
void DWebApplication::update() {
|
||||
for (std::size_t i = 0; i < _update_registered_requests.size(); ++i) {
|
||||
DRequest *r = _update_registered_requests[i];
|
||||
Request *r = _update_registered_requests[i];
|
||||
|
||||
r->update();
|
||||
}
|
||||
@ -654,7 +644,7 @@ void DWebApplication::on_async_request(const HttpRequestImplPtr &req, std::funct
|
||||
//resp->setExpiredTime(0);
|
||||
//callback(resp);
|
||||
|
||||
DRequest *request = DRequestPool::get_request();
|
||||
DRequest *request = DRequest::get();
|
||||
request->application = this;
|
||||
request->response = HttpResponse::newHttpResponse();
|
||||
request->request = std::shared_ptr<drogon::HttpRequestImpl>(req);
|
||||
@ -807,6 +797,3 @@ DWebApplication::~DWebApplication() {
|
||||
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>";
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef DWEB_APPLICATION_H
|
||||
#define DWEB_APPLICATION_H
|
||||
|
||||
#include "core/http/web_application.h"
|
||||
|
||||
#include "core/object.h"
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@ -9,7 +11,7 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "handler_instance.h"
|
||||
#include "core/http/handler_instance.h"
|
||||
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/net/Resolver.h>
|
||||
@ -25,34 +27,26 @@
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
class DRequest;
|
||||
class Request;
|
||||
|
||||
class DWebApplication {
|
||||
class DWebApplication : WebApplication {
|
||||
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);
|
||||
void handle_request(Request *request);
|
||||
void send_error(int error_code, Request *request);
|
||||
void send_file(const std::string &path, Request *request);
|
||||
|
||||
virtual void load_settings();
|
||||
virtual void setup_routes();
|
||||
virtual void setup_middleware();
|
||||
|
||||
void default_routing_middleware(Object *instance, DRequest *request);
|
||||
void default_routing_middleware(Object *instance, Request *request);
|
||||
|
||||
virtual void migrate();
|
||||
|
||||
void register_request_update(DRequest *request);
|
||||
void unregister_request_update(DRequest *request);
|
||||
void register_request_update(Request *request);
|
||||
void unregister_request_update(Request *request);
|
||||
void update();
|
||||
|
||||
//-------
|
||||
|
||||
void add_listener(const std::string &ip, uint16_t port,
|
||||
bool useSSL = false, const std::string &certFile = "", const std::string &keyFile = "", bool useOldTLS = false,
|
||||
const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {});
|
||||
@ -169,17 +163,9 @@ public:
|
||||
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;
|
||||
std::vector<Request *> _update_registered_requests;
|
||||
|
||||
// We use a uuid string as session id;
|
||||
// set sessionTimeout_=0 to make location session valid forever based on
|
||||
|
Loading…
Reference in New Issue
Block a user