Now requests have to be sent manually, with a new send() method. This makes it possible to handle requests in a full on async callback-like way.

This commit is contained in:
Relintai 2020-11-26 11:26:02 +01:00
parent 5b99261b30
commit 566717c075
5 changed files with 49 additions and 37 deletions

View File

@ -25,12 +25,14 @@ void Application::default_fallback_error_handler(int error_code, Request *reques
std::string body = "<html>Internal server error! :(</html>"; std::string body = "<html>Internal server error! :(</html>";
request->response->setBody(body); request->response->setBody(body);
request->finalized = true; request->finalized = true;
request->send();
} }
void Application::default_404_error_handler(int error_code, Request *request) { void Application::default_404_error_handler(int error_code, Request *request) {
std::string body = "<html>404 :(</html>"; std::string body = "<html>404 :(</html>";
request->response->setBody(body); request->response->setBody(body);
request->finalized = true; request->finalized = true;
request->send();
} }
void Application::handle_request(Request *request) { void Application::handle_request(Request *request) {
@ -72,8 +74,10 @@ void Application::handle_request(Request *request) {
for (uint32_t i = 0; i < middlewares.size(); ++i) { for (uint32_t i = 0; i < middlewares.size(); ++i) {
middlewares[i](request); middlewares[i](request);
if (request->finalized) if (request->finalized) {
request->send();
return; return;
}
} }
func(request); func(request);
@ -116,6 +120,7 @@ void Application::send_file(const std::string &path, Request *request) {
request->response->setBody(body); request->response->setBody(body);
request->finalized = true; request->finalized = true;
request->send();
} }
Application::Application() { Application::Application() {

View File

@ -10,8 +10,6 @@ void HTTPServer::http_callback_handler(Request *request) {
} }
void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session) { void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session) {
//(void)httpParser; needed?
Request *request = RequestPool::get_request(); Request *request = RequestPool::get_request();
request->http_parser = &httpParser; request->http_parser = &httpParser;
@ -22,22 +20,6 @@ void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const Ht
#endif #endif
http_callback_handler(request); http_callback_handler(request);
if (httpParser.isKeepAlive()) {
request->response->addHeadValue("Connection", "Keep-Alive");
std::string result = request->response->getResult();
session->send(result.c_str(), result.size());
} else {
request->response->addHeadValue("Connection", "Close");
std::string result = request->response->getResult();
session->send(result.c_str(), result.size(), [session]() { session->postShutdown(); });
}
RequestPool::return_request(request);
} }
void HTTPServer::wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload) { void HTTPServer::wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload) {
@ -66,6 +48,7 @@ void HTTPServer::initialize() {
int p_port = port; int p_port = port;
//!
if (listenBuilder) if (listenBuilder)
delete listenBuilder; delete listenBuilder;
@ -95,6 +78,7 @@ void HTTPServer::initialize() {
void HTTPServer::main_loop() { void HTTPServer::main_loop() {
while (true) { while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
if (brynet::base::app_kbhit()) { if (brynet::base::app_kbhit()) {
break; break;
} }
@ -104,6 +88,7 @@ void HTTPServer::main_loop() {
HTTPServer::HTTPServer() { HTTPServer::HTTPServer() {
port = 80; port = 80;
threads = 4; threads = 4;
listenBuilder = nullptr;
} }
HTTPServer::~HTTPServer() { HTTPServer::~HTTPServer() {

View File

@ -1,9 +1,29 @@
#include "request.h" #include "request.h"
void Request::send() {
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();
const HttpSession::Ptr lsession = (*session);
(*session)->send(result.c_str(), result.size(), [lsession]() { lsession->postShutdown(); });
}
RequestPool::return_request(this);
}
void Request::reset() { void Request::reset() {
http_parser = nullptr; http_parser = nullptr;
session = nullptr; session = nullptr;
finalized = false; finalized = false;
if (response) if (response)
delete response; delete response;
@ -12,7 +32,7 @@ void Request::reset() {
} }
Request::Request() { Request::Request() {
response = nullptr; response = nullptr;
reset(); reset();
} }
@ -43,11 +63,11 @@ Request *RequestPool::get_request() {
} }
void RequestPool::return_request(Request *request) { void RequestPool::return_request(Request *request) {
request->reset(); request->reset();
_mutex.lock(); _mutex.lock();
_requests.push_back(request); _requests.push_back(request);
_mutex.unlock(); _mutex.unlock();
} }
RequestPool::RequestPool() { RequestPool::RequestPool() {

View File

@ -1,11 +1,11 @@
#ifndef REQUEST_H #ifndef REQUEST_H
#define REQUEST_H #define REQUEST_H
#include <vector>
#include <mutex> #include <mutex>
#include <vector>
#include <brynet/net/http/HttpService.hpp>
#include <brynet/net/http/HttpFormat.hpp> #include <brynet/net/http/HttpFormat.hpp>
#include <brynet/net/http/HttpService.hpp>
using namespace brynet; using namespace brynet;
using namespace brynet::net; using namespace brynet::net;
@ -14,27 +14,28 @@ using namespace brynet::net::http;
class Request { class Request {
public: public:
const HTTPParser *http_parser; const HTTPParser *http_parser;
const HttpSession::Ptr *session; const HttpSession::Ptr *session;
HttpResponse *response; HttpResponse *response;
bool finalized; bool finalized;
void reset(); void send();
void reset();
Request(); Request();
~Request(); ~Request();
}; };
class RequestPool { class RequestPool {
public: public:
static Request *get_request(); static Request *get_request();
static void return_request(Request *request); static void return_request(Request *request);
RequestPool(); RequestPool();
~RequestPool(); ~RequestPool();
protected: protected:
static std::mutex _mutex; static std::mutex _mutex;
static std::vector<Request *> _requests; static std::vector<Request *> _requests;
}; };
#endif #endif

View File

@ -20,6 +20,7 @@ void RDNApplication::index(Request *request) {
FileCache::get_singleton()->set_cached_body("index", body); FileCache::get_singleton()->set_cached_body("index", body);
request->response->setBody(body); request->response->setBody(body);
request->send();
} }
void RDNApplication::session_middleware_func(Request *request) { void RDNApplication::session_middleware_func(Request *request) {