diff --git a/modules/web/http_server_simple/http_parser.cpp b/modules/web/http_server_simple/http_parser.cpp index 7d4babb11..4842258e3 100644 --- a/modules/web/http_server_simple/http_parser.cpp +++ b/modules/web/http_server_simple/http_parser.cpp @@ -2,6 +2,8 @@ #include "../http/web_server_request.h" +#include "./http_parser/http_parser.h" + Ref HTTPParser::get_request() { return _request; } @@ -22,24 +24,142 @@ void HTTPParser::reset() { 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 current_buffer_index = 0; + int parsed_bytes = 0; - _partial_data.resize(p_data_length - current_buffer_index); + parsed_bytes = static_cast(http_parser_execute(parser, settings, p_buffer, p_data_length)); - CharType *pdp = _partial_data.ptrw(); - for (int i = 0; i < current_buffer_index; ++i) { - pdp[i] = p_buffer[i + current_buffer_index]; - } - - return current_buffer_index; + return parsed_bytes; } HTTPParser::HTTPParser() { _is_ready = false; + + settings = memnew(http_parser_settings); + + settings->on_message_begin = _on_message_begin_cb; + settings->on_url = _on_url_cb; + settings->on_status = _on_status_cb; + settings->on_header_field = _on_header_field_cb; + settings->on_header_value = _on_header_value_cb; + settings->on_headers_complete = _on_headers_complete_cb; + settings->on_body = _on_body_cb; + settings->on_message_complete = _on_message_complete_cb; + settings->on_chunk_header = _on_chunk_header_cb; + settings->on_chunk_complete = _on_chunk_complete_cb; + + //parser = malloc(sizeof(http_parser)); + parser = memnew(http_parser); + http_parser_init(parser, HTTP_REQUEST); + + parser->data = this; } HTTPParser::~HTTPParser() { + memdelete(parser); + memdelete(settings); + parser = nullptr; } void HTTPParser::_bind_methods() { } + +String HTTPParser::chr_len_to_str(const char *at, size_t length) { + String ret; + ret.resize(length + 1); + + CharType *p = ret.ptrw(); + + for (int i = 0; i <= length; ++i) { + p[i] = at[i]; + } + + return ret; +} + +int HTTPParser::on_message_begin() { + print_error("begin"); + return 0; +} +int HTTPParser::on_url(const char *at, size_t length) { + String s = chr_len_to_str(at, length); + + print_error("url " + s); + return 0; +} +int HTTPParser::on_status(const char *at, size_t length) { + String s = chr_len_to_str(at, length); + print_error("status " + s); + return 0; +} +int HTTPParser::on_header_field(const char *at, size_t length) { + String s = chr_len_to_str(at, length); + print_error("header_field " + s); + return 0; +} +int HTTPParser::on_header_value(const char *at, size_t length) { + String s = chr_len_to_str(at, length); + print_error("header_val " + s); + return 0; +} +int HTTPParser::on_headers_complete() { + print_error("headers_complete"); + return 0; +} +int HTTPParser::on_body(const char *at, size_t length) { + String s = chr_len_to_str(at, length); + print_error("on_body " + s); + return 0; +} +int HTTPParser::on_message_complete() { + print_error("msg_copmlete"); + return 0; +} +int HTTPParser::on_chunk_header() { + print_error("chunk_header"); + return 0; +} +int HTTPParser::on_chunk_complete() { + print_error("chunk_complete"); + return 0; +} + +int HTTPParser::_on_message_begin_cb(http_parser *parser) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_message_begin(); +} +int HTTPParser::_on_url_cb(http_parser *parser, const char *at, size_t length) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_url(at, length); +} +int HTTPParser::_on_status_cb(http_parser *parser, const char *at, size_t length) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_status(at, length); +} +int HTTPParser::_on_header_field_cb(http_parser *parser, const char *at, size_t length) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_header_field(at, length); +} +int HTTPParser::_on_header_value_cb(http_parser *parser, const char *at, size_t length) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_header_value(at, length); +} +int HTTPParser::_on_headers_complete_cb(http_parser *parser) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_headers_complete(); +} +int HTTPParser::_on_body_cb(http_parser *parser, const char *at, size_t length) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_body(at, length); +} +int HTTPParser::_on_message_complete_cb(http_parser *parser) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_message_complete(); +} +int HTTPParser::_on_chunk_header_cb(http_parser *parser) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_chunk_header(); +} +int HTTPParser::_on_chunk_complete_cb(http_parser *parser) { + HTTPParser *p = reinterpret_cast(parser->data); + return p->on_chunk_complete(); +} diff --git a/modules/web/http_server_simple/http_parser.h b/modules/web/http_server_simple/http_parser.h index 4d663c22d..bf68db567 100644 --- a/modules/web/http_server_simple/http_parser.h +++ b/modules/web/http_server_simple/http_parser.h @@ -6,6 +6,8 @@ #include "core/reference.h" class WebServerRequest; +struct http_parser; +struct http_parser_settings; class HTTPParser : public Reference { GDCLASS(HTTPParser, Reference); @@ -32,6 +34,34 @@ protected: Ref _request; bool _is_ready; + +private: + String chr_len_to_str(const char *at, size_t length); + + int on_message_begin(); + int on_url(const char *at, size_t length); + int on_status(const char *at, size_t length); + int on_header_field(const char *at, size_t length); + int on_header_value(const char *at, size_t length); + int on_headers_complete(); + int on_body(const char *at, size_t length); + int on_message_complete(); + int on_chunk_header(); + int on_chunk_complete(); + + static int _on_message_begin_cb(http_parser *parser); + static int _on_url_cb(http_parser *parser, const char *at, size_t length); + static int _on_status_cb(http_parser *parser, const char *at, size_t length); + static int _on_header_field_cb(http_parser *parser, const char *at, size_t length); + static int _on_header_value_cb(http_parser *parser, const char *at, size_t length); + static int _on_headers_complete_cb(http_parser *parser); + static int _on_body_cb(http_parser *parser, const char *at, size_t length); + static int _on_message_complete_cb(http_parser *parser); + static int _on_chunk_header_cb(http_parser *parser); + static int _on_chunk_complete_cb(http_parser *parser); + + http_parser *parser; + http_parser_settings *settings; }; #endif diff --git a/modules/web/http_server_simple/http_server_simple.cpp b/modules/web/http_server_simple/http_server_simple.cpp index 2d479c4e8..bcd1dc269 100644 --- a/modules/web/http_server_simple/http_server_simple.cpp +++ b/modules/web/http_server_simple/http_server_simple.cpp @@ -194,7 +194,7 @@ void HTTPServerSimple::poll() { int buffer_start_index = 0; while (true) { char *rb = reinterpret_cast(&req_buf[buffer_start_index]); - buffer_start_index = _http_parser->read_from_buffer(rb, read); + buffer_start_index += _http_parser->read_from_buffer(rb, read); if (_http_parser->is_ready()) { Ref req; @@ -208,7 +208,7 @@ void HTTPServerSimple::poll() { _http_parser->reset(); } - if (buffer_start_index == read) { + if (buffer_start_index >= read) { return; } } diff --git a/modules/web/http_server_simple/simple_web_server_request.h b/modules/web/http_server_simple/simple_web_server_request.h index dcd984c49..75d5745c9 100644 --- a/modules/web/http_server_simple/simple_web_server_request.h +++ b/modules/web/http_server_simple/simple_web_server_request.h @@ -39,7 +39,7 @@ public: virtual String parser_get_path(); virtual String get_host() const; - virtual String get_path_full() const; + //virtual String get_path_full() const; SimpleWebServerRequest(); ~SimpleWebServerRequest(); diff --git a/modules/web/register_types.cpp b/modules/web/register_types.cpp index 3fe2e4562..e08511a41 100644 --- a/modules/web/register_types.cpp +++ b/modules/web/register_types.cpp @@ -61,6 +61,8 @@ void register_web_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + + ClassDB::register_class(); } void unregister_web_types() {