diff --git a/modules/http_server_simple/http_parser.cpp b/modules/http_server_simple/http_parser.cpp index c524fbd54..333f738c7 100644 --- a/modules/http_server_simple/http_parser.cpp +++ b/modules/http_server_simple/http_parser.cpp @@ -179,7 +179,7 @@ void HTTPParser::process_urlenc_data() { String key = p.get_slicec('=', 0).replace("+", " ").percent_decode(); String value = p.get_slicec('=', 1).replace("+", " ").percent_decode(); - _request->add_parameter(key, value); + _request->add_post_parameter(key, value); } } @@ -280,7 +280,7 @@ int HTTPParser::on_header_value(const char *at, size_t length) { ERR_PRINT("header_val " + s); #endif - _request->add_parameter(_queued_header_field, s); + _request->add_post_parameter(_queued_header_field, s); if (_queued_header_field == "Host") { _request->set_host(s); @@ -566,7 +566,7 @@ int HTTPParser::on_multipart_part_data_end_cb() { } } else { String s = _multipart_form_data.ptr(); - _request->add_parameter(_multipart_form_name, s); + _request->add_post_parameter(_multipart_form_name, s); } _multipart_form_is_file = false; diff --git a/modules/http_server_simple/simple_web_server_request.cpp b/modules/http_server_simple/simple_web_server_request.cpp index 61f05aaa5..e7ce64fd6 100644 --- a/modules/http_server_simple/simple_web_server_request.cpp +++ b/modules/http_server_simple/simple_web_server_request.cpp @@ -65,11 +65,25 @@ String SimpleWebServerRequest::get_file_data_str(const int index) const { } String SimpleWebServerRequest::get_parameter(const String &key) const { - if (!_parameters.has(key)) { + if (!_post_parameters.has(key)) { + return get_get_parameter(key); + } + + return get_post_parameter(key); +} +String SimpleWebServerRequest::get_post_parameter(const String &key) const { + if (!_post_parameters.has(key)) { return ""; } - return _parameters[key]; + return _post_parameters[key]; +} +String SimpleWebServerRequest::get_get_parameter(const String &key) const { + if (!_get_parameters.has(key)) { + return ""; + } + + return _get_parameters[key]; } void SimpleWebServerRequest::send_redirect(const String &location, const HTTPServerEnums::HTTPStatusCode status_code) { @@ -107,12 +121,62 @@ String SimpleWebServerRequest::get_host() const { return _host; } -void SimpleWebServerRequest::add_parameter(const String &key, const String &value) { - _parameters[key] = value; +void SimpleWebServerRequest::add_post_parameter(const String &key, const String &value) { + _post_parameters[key] = value; +} + +void SimpleWebServerRequest::add_get_parameter(const String &key, const String &value) { + _get_parameters[key] = value; } void SimpleWebServerRequest::set_parser_path(const String &value) { - _parser_path = value; + //https://www.rfc-editor.org/rfc/rfc3986.txt + //3.4. Query + //The query component is indicated by the first question mark ("?") ... + int qpos = value.find_char('?'); + + if (qpos == -1) { + _parser_path = value; + return; + } + + _parser_path = value.substr_index(0, qpos); + + //... and terminated by a number sign ("#") character or by the end of the URI. + int get_query_end = value.find_char('#', qpos); + + // ...The characters slash ("/") and question mark ("?") may represent data within the query component. + // "key=value" pairs and one frequently used value is a reference to another URI, it is sometimes + // better for usability to avoid percent-encoding those characters. + + if (get_query_end == -1) { + get_query_end = value.size() - 1; + } + + String get_req_str = value.substr_index(qpos + 1, get_query_end); + + Vector get_req_params = get_req_str.split("&"); + + for (int i = 0; i < get_req_params.size(); ++i) { + String cp = get_req_params[i]; + + int eq = cp.find_char('='); + + if (eq == -1) { + // skip if ¶m& + continue; + } + + String key = cp.substr_index(0, eq); + String val = cp.substr_index(eq + 1, cp.size()); + + if (key.empty() || val.empty()) { + // &=v& or &p=& + continue; + } + + add_get_parameter(key.percent_decode(), val.percent_decode()); + } } void SimpleWebServerRequest::set_host(const String &value) { diff --git a/modules/http_server_simple/simple_web_server_request.h b/modules/http_server_simple/simple_web_server_request.h index 1ff1cfae9..57a639f0a 100644 --- a/modules/http_server_simple/simple_web_server_request.h +++ b/modules/http_server_simple/simple_web_server_request.h @@ -1,10 +1,10 @@ #ifndef SIMPLE_WEB_SERVER_REQUEST_H #define SIMPLE_WEB_SERVER_REQUEST_H -#include "core/variant/dictionary.h" #include "core/containers/hash_map.h" -#include "core/string/ustring.h" #include "core/containers/vector.h" +#include "core/string/ustring.h" +#include "core/variant/dictionary.h" #include "modules/web/http/web_server_request.h" @@ -35,6 +35,8 @@ public: virtual String get_file_data_str(const int index) const; virtual String get_parameter(const String &key) const; + virtual String get_post_parameter(const String &key) const; + virtual String get_get_parameter(const String &key) const; virtual void send_redirect(const String &location, const HTTPServerEnums::HTTPStatusCode status_code = HTTPServerEnums::HTTP_STATUS_CODE_302_FOUND); virtual void send(); @@ -42,7 +44,8 @@ public: virtual String parser_get_path(); virtual String get_host() const; - void add_parameter(const String &key, const String &value); + void add_post_parameter(const String &key, const String &value); + void add_get_parameter(const String &key, const String &value); void set_parser_path(const String &value); void set_host(const String &value); @@ -63,7 +66,8 @@ public: protected: static void _bind_methods(); - HashMap _parameters; + HashMap _post_parameters; + HashMap _get_parameters; String _parser_path; String _host; diff --git a/modules/web/http/web_server_request.cpp b/modules/web/http/web_server_request.cpp index a07307676..d0c9f5985 100644 --- a/modules/web/http/web_server_request.cpp +++ b/modules/web/http/web_server_request.cpp @@ -205,6 +205,14 @@ String WebServerRequest::get_parameter(const String &key) const { return ""; } +String WebServerRequest::get_post_parameter(const String &key) const { + return ""; +} + +String WebServerRequest::get_get_parameter(const String &key) const { + return ""; +} + HTTPServerEnums::HTTPStatusCode WebServerRequest::get_status_code() const { return _status_code; } @@ -541,6 +549,8 @@ void WebServerRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("get_file_data_str", "index"), &WebServerRequest::get_file_data_str); ClassDB::bind_method(D_METHOD("get_parameter", "key"), &WebServerRequest::get_parameter); + ClassDB::bind_method(D_METHOD("get_post_parameter", "key"), &WebServerRequest::get_post_parameter); + ClassDB::bind_method(D_METHOD("get_get_parameter", "key"), &WebServerRequest::get_get_parameter); ClassDB::bind_method(D_METHOD("get_status_code"), &WebServerRequest::get_status_code); ClassDB::bind_method(D_METHOD("set_status_code", "val"), &WebServerRequest::set_status_code); diff --git a/modules/web/http/web_server_request.h b/modules/web/http/web_server_request.h index e1217303d..530db698a 100644 --- a/modules/web/http/web_server_request.h +++ b/modules/web/http/web_server_request.h @@ -78,6 +78,8 @@ public: virtual String get_file_data_str(const int index) const; virtual String get_parameter(const String &key) const; + virtual String get_post_parameter(const String &key) const; + virtual String get_get_parameter(const String &key) const; HTTPServerEnums::HTTPStatusCode get_status_code() const; void set_status_code(const HTTPServerEnums::HTTPStatusCode status_code);