mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-23 17:47:17 +01:00
Implement basig http header parsing, and also send the request through the WebNode tree.
This commit is contained in:
parent
10150d67c8
commit
24e120142e
@ -1,14 +1,22 @@
|
||||
#include "http_parser.h"
|
||||
|
||||
#include "../http/web_server_request.h"
|
||||
|
||||
#include "./http_parser/http_parser.h"
|
||||
|
||||
Ref<WebServerRequest> HTTPParser::get_request() {
|
||||
return _request;
|
||||
#include "simple_web_server_request.h"
|
||||
|
||||
Ref<SimpleWebServerRequest> HTTPParser::get_next_request() {
|
||||
ERR_FAIL_COND_V(_requests.size() == 0, Ref<SimpleWebServerRequest>());
|
||||
|
||||
Ref<SimpleWebServerRequest> rn = _requests[0];
|
||||
|
||||
_requests.remove(0);
|
||||
|
||||
return rn;
|
||||
}
|
||||
void HTTPParser::set_request(const Ref<WebServerRequest> &val) {
|
||||
_request = val;
|
||||
|
||||
int HTTPParser::get_request_count() const {
|
||||
return _requests.size();
|
||||
}
|
||||
|
||||
bool HTTPParser::is_ready() const {
|
||||
@ -22,8 +30,6 @@ void HTTPParser::reset() {
|
||||
|
||||
//returns the index where processing was ended -> start of the next query if != data_length
|
||||
int HTTPParser::read_from_buffer(const char *p_buffer, const int p_data_length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), p_data_length);
|
||||
|
||||
int parsed_bytes = 0;
|
||||
|
||||
parsed_bytes = static_cast<int>(http_parser_execute(parser, settings, p_buffer, p_data_length));
|
||||
@ -76,50 +82,127 @@ String HTTPParser::chr_len_to_str(const char *at, size_t length) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MESSAGE_DEBUG 0
|
||||
|
||||
int HTTPParser::on_message_begin() {
|
||||
print_error("begin");
|
||||
if (_request.is_valid()) {
|
||||
ERR_PRINT("Request was valid!");
|
||||
}
|
||||
|
||||
_in_header = true;
|
||||
|
||||
_request.instance();
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("begin");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_url(const char *at, size_t length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
String s = chr_len_to_str(at, length);
|
||||
|
||||
print_error("url " + s);
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("url " + s);
|
||||
#endif
|
||||
|
||||
_request->set_parser_path(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_status(const char *at, size_t length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
String s = chr_len_to_str(at, length);
|
||||
print_error("status " + s);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("status " + s);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_header_field(const char *at, size_t length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
String s = chr_len_to_str(at, length);
|
||||
print_error("header_field " + s);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("header_field " + s);
|
||||
#endif
|
||||
|
||||
_queued_header_field = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_header_value(const char *at, size_t length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
String s = chr_len_to_str(at, length);
|
||||
print_error("header_val " + s);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("header_val " + s);
|
||||
#endif
|
||||
|
||||
_request->add_parameter(_queued_header_field, s);
|
||||
|
||||
if (_queued_header_field == "Host") {
|
||||
_request->set_host(s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_headers_complete() {
|
||||
print_error("headers_complete");
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("headers_complete");
|
||||
#endif
|
||||
|
||||
_in_header = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_body(const char *at, size_t length) {
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
String s = chr_len_to_str(at, length);
|
||||
print_error("on_body " + s);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("on_body " + s);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_message_complete() {
|
||||
print_error("msg_copmlete");
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("msg_copmlete");
|
||||
#endif
|
||||
|
||||
_requests.push_back(_request);
|
||||
_request.unref();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_chunk_header() {
|
||||
print_error("chunk_header");
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("chunk_header");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int HTTPParser::on_chunk_complete() {
|
||||
print_error("chunk_complete");
|
||||
ERR_FAIL_COND_V(!_request.is_valid(), 0);
|
||||
|
||||
#if MESSAGE_DEBUG
|
||||
ERR_PRINT("chunk_complete");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
class WebServerRequest;
|
||||
class SimpleWebServerRequest;
|
||||
struct http_parser;
|
||||
struct http_parser_settings;
|
||||
|
||||
@ -13,8 +13,8 @@ class HTTPParser : public Reference {
|
||||
GDCLASS(HTTPParser, Reference);
|
||||
|
||||
public:
|
||||
Ref<WebServerRequest> get_request();
|
||||
void set_request(const Ref<WebServerRequest> &val);
|
||||
Ref<SimpleWebServerRequest> get_next_request();
|
||||
int get_request_count() const;
|
||||
|
||||
bool is_ready() const;
|
||||
|
||||
@ -31,7 +31,8 @@ protected:
|
||||
|
||||
String _partial_data;
|
||||
|
||||
Ref<WebServerRequest> _request;
|
||||
Ref<SimpleWebServerRequest> _request;
|
||||
Vector<Ref<SimpleWebServerRequest>> _requests;
|
||||
|
||||
bool _is_ready;
|
||||
|
||||
@ -62,6 +63,9 @@ private:
|
||||
|
||||
http_parser *parser;
|
||||
http_parser_settings *settings;
|
||||
|
||||
bool _in_header;
|
||||
String _queued_header_field;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "http_parser.h"
|
||||
#include "simple_web_server_request.h"
|
||||
#include "web_server_simple.h"
|
||||
|
||||
void HTTPServerSimple::stop() {
|
||||
server->stop();
|
||||
@ -186,35 +187,30 @@ void HTTPServerSimple::poll() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (read == 0) {
|
||||
// Busy, wait next poll
|
||||
return;
|
||||
if (read > 0) {
|
||||
int buffer_start_index = 0;
|
||||
while (true) {
|
||||
char *rb = reinterpret_cast<char *>(&req_buf[buffer_start_index]);
|
||||
buffer_start_index += _http_parser->read_from_buffer(rb, read);
|
||||
|
||||
if (buffer_start_index >= read) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int buffer_start_index = 0;
|
||||
while (true) {
|
||||
char *rb = reinterpret_cast<char *>(&req_buf[buffer_start_index]);
|
||||
buffer_start_index += _http_parser->read_from_buffer(rb, read);
|
||||
if (_http_parser->get_request_count() > 0) {
|
||||
Ref<SimpleWebServerRequest> request = _http_parser->get_next_request();
|
||||
|
||||
if (_http_parser->is_ready()) {
|
||||
Ref<SimpleWebServerRequest> req;
|
||||
request->_server = this;
|
||||
|
||||
req = _http_parser->get_request();
|
||||
|
||||
//handle request
|
||||
|
||||
req.instance();
|
||||
_http_parser->set_request(req);
|
||||
_http_parser->reset();
|
||||
}
|
||||
|
||||
if (buffer_start_index >= read) {
|
||||
return;
|
||||
}
|
||||
_web_server->server_handle_request(request);
|
||||
}
|
||||
}
|
||||
|
||||
HTTPServerSimple::HTTPServerSimple() {
|
||||
_web_server = nullptr;
|
||||
|
||||
mimes["html"] = "text/html";
|
||||
mimes["js"] = "application/javascript";
|
||||
mimes["json"] = "application/json";
|
||||
@ -222,11 +218,9 @@ HTTPServerSimple::HTTPServerSimple() {
|
||||
mimes["png"] = "image/png";
|
||||
mimes["svg"] = "image/svg";
|
||||
mimes["wasm"] = "application/wasm";
|
||||
|
||||
server.instance();
|
||||
_http_parser.instance();
|
||||
Ref<SimpleWebServerRequest> req;
|
||||
req.instance();
|
||||
_http_parser->set_request(req);
|
||||
stop();
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "core/project_settings.h"
|
||||
|
||||
class HTTPParser;
|
||||
class WebServerSimple;
|
||||
|
||||
class HTTPServerSimple : public Reference {
|
||||
public:
|
||||
@ -51,6 +52,8 @@ public:
|
||||
HTTPServerSimple();
|
||||
~HTTPServerSimple();
|
||||
|
||||
WebServerSimple *_web_server;
|
||||
|
||||
private:
|
||||
Ref<TCP_Server> server;
|
||||
Map<String, String> mimes;
|
||||
|
@ -41,7 +41,11 @@ String SimpleWebServerRequest::get_file_data_str(const int index) const {
|
||||
}
|
||||
|
||||
String SimpleWebServerRequest::get_parameter(const String &key) const {
|
||||
return "";
|
||||
if (!_parameters.has(key)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return _parameters[key];
|
||||
}
|
||||
|
||||
void SimpleWebServerRequest::send_redirect(const String &location, const HTTPServerEnums::HTTPStatusCode status_code) {
|
||||
@ -61,14 +65,27 @@ void SimpleWebServerRequest::send_file(const String &p_file_path) {
|
||||
}
|
||||
|
||||
String SimpleWebServerRequest::parser_get_path() {
|
||||
return "";
|
||||
return _parser_path;
|
||||
}
|
||||
|
||||
String SimpleWebServerRequest::get_host() const {
|
||||
return "";
|
||||
return _host;
|
||||
}
|
||||
|
||||
void SimpleWebServerRequest::add_parameter(const String &key, const String &value) {
|
||||
_parameters[key] = value;
|
||||
}
|
||||
|
||||
void SimpleWebServerRequest::set_parser_path(const String &value) {
|
||||
_parser_path = value;
|
||||
}
|
||||
|
||||
void SimpleWebServerRequest::set_host(const String &value) {
|
||||
_host = value;
|
||||
}
|
||||
|
||||
SimpleWebServerRequest::SimpleWebServerRequest() {
|
||||
_server = nullptr;
|
||||
}
|
||||
|
||||
SimpleWebServerRequest::~SimpleWebServerRequest() {
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define SIMPLE_WEB_SERVER_REQUEST_H
|
||||
|
||||
#include "core/dictionary.h"
|
||||
#include "core/hash_map.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/vector.h"
|
||||
|
||||
@ -14,6 +15,7 @@ class WebServerCookie;
|
||||
class HTTPSession;
|
||||
class WebPermission;
|
||||
class WebNode;
|
||||
class HTTPServerSimple;
|
||||
|
||||
class SimpleWebServerRequest : public WebServerRequest {
|
||||
GDCLASS(SimpleWebServerRequest, WebServerRequest);
|
||||
@ -39,13 +41,23 @@ public:
|
||||
virtual String parser_get_path();
|
||||
virtual String get_host() const;
|
||||
|
||||
void add_parameter(const String &key, const String &value);
|
||||
void set_parser_path(const String &value);
|
||||
void set_host(const String &value);
|
||||
|
||||
//virtual String get_path_full() const;
|
||||
|
||||
SimpleWebServerRequest();
|
||||
~SimpleWebServerRequest();
|
||||
|
||||
HTTPServerSimple *_server;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
HashMap<String, String> _parameters;
|
||||
String _parser_path;
|
||||
String _host;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "http_server_simple.h"
|
||||
|
||||
void WebServerSimple::_start() {
|
||||
WebServer::_start();
|
||||
|
||||
const uint16_t bind_port = 8080;
|
||||
// Resolve host if needed.
|
||||
const String bind_host = "127.0.0.1";
|
||||
@ -64,12 +66,15 @@ void WebServerSimple::_start() {
|
||||
}
|
||||
|
||||
void WebServerSimple::_stop() {
|
||||
WebServer::_stop();
|
||||
|
||||
MutexLock lock(server_lock);
|
||||
server->stop();
|
||||
}
|
||||
|
||||
WebServerSimple::WebServerSimple() {
|
||||
server.instance();
|
||||
server->_web_server = this;
|
||||
server_thread.start(_server_thread_poll, this);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user