mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-02-21 23:18:00 +01:00
Implement max request size limit for HTTPServerSimple.
This commit is contained in:
parent
e607aba732
commit
a155e44491
@ -51,10 +51,23 @@ int HTTPParser::read_from_buffer(const char *p_buffer, const int p_data_length)
|
|||||||
|
|
||||||
parsed_bytes = static_cast<int>(http_parser_execute(parser, settings, p_buffer, p_data_length));
|
parsed_bytes = static_cast<int>(http_parser_execute(parser, settings, p_buffer, p_data_length));
|
||||||
|
|
||||||
|
_current_request_size += parsed_bytes;
|
||||||
|
|
||||||
|
if (_current_request_size >= max_request_size) {
|
||||||
|
_error = true;
|
||||||
|
#if PROTOCOL_ERROR_LOGGING_ENABLED
|
||||||
|
PLOG_ERR("_current_request_size >= max_request_size");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return parsed_bytes;
|
return parsed_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPParser::HTTPParser() {
|
HTTPParser::HTTPParser() {
|
||||||
|
// Should always get set from the outside, if it remains 0 it's a bug.
|
||||||
|
max_request_size = 0;
|
||||||
|
_current_request_size = 0;
|
||||||
|
|
||||||
_is_ready = false;
|
_is_ready = false;
|
||||||
_content_type = REQUEST_CONTENT_URLENCODED;
|
_content_type = REQUEST_CONTENT_URLENCODED;
|
||||||
_multipart_form_is_file = false;
|
_multipart_form_is_file = false;
|
||||||
@ -206,6 +219,8 @@ int HTTPParser::on_message_begin() {
|
|||||||
ERR_PRINT("Request was valid!");
|
ERR_PRINT("Request was valid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_current_request_size = 0;
|
||||||
|
|
||||||
_in_header = true;
|
_in_header = true;
|
||||||
_content_type = REQUEST_CONTENT_URLENCODED;
|
_content_type = REQUEST_CONTENT_URLENCODED;
|
||||||
_multipart_form_is_file = false;
|
_multipart_form_is_file = false;
|
||||||
|
@ -22,6 +22,8 @@ public:
|
|||||||
REQUEST_CONTENT_TEXT_PLAIN,
|
REQUEST_CONTENT_TEXT_PLAIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint64_t max_request_size;
|
||||||
|
|
||||||
Ref<SimpleWebServerRequest> get_next_request();
|
Ref<SimpleWebServerRequest> get_next_request();
|
||||||
int get_request_count() const;
|
int get_request_count() const;
|
||||||
|
|
||||||
@ -42,6 +44,8 @@ protected:
|
|||||||
|
|
||||||
String _partial_data;
|
String _partial_data;
|
||||||
|
|
||||||
|
uint64_t _current_request_size;
|
||||||
|
|
||||||
Ref<SimpleWebServerRequest> _request;
|
Ref<SimpleWebServerRequest> _request;
|
||||||
Vector<Ref<SimpleWebServerRequest>> _requests;
|
Vector<Ref<SimpleWebServerRequest>> _requests;
|
||||||
|
|
||||||
|
@ -340,6 +340,7 @@ HTTPServerConnection::HTTPServerConnection() {
|
|||||||
_http_server = nullptr;
|
_http_server = nullptr;
|
||||||
|
|
||||||
_http_parser.instance();
|
_http_parser.instance();
|
||||||
|
_http_parser->max_request_size = max_request_size;
|
||||||
time = 0;
|
time = 0;
|
||||||
|
|
||||||
memset(req_buf, 0, sizeof(req_buf));
|
memset(req_buf, 0, sizeof(req_buf));
|
||||||
@ -428,6 +429,9 @@ void HTTPServerSimple::poll() {
|
|||||||
connection->_web_server = _web_server;
|
connection->_web_server = _web_server;
|
||||||
connection->_http_server = this;
|
connection->_http_server = this;
|
||||||
|
|
||||||
|
connection->max_request_size = max_request_size;
|
||||||
|
connection->_http_parser->max_request_size = max_request_size;
|
||||||
|
|
||||||
connection->use_ssl = use_ssl;
|
connection->use_ssl = use_ssl;
|
||||||
connection->key = key;
|
connection->key = key;
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ public:
|
|||||||
WebServerSimple *_web_server;
|
WebServerSimple *_web_server;
|
||||||
HTTPServerSimple *_http_server;
|
HTTPServerSimple *_http_server;
|
||||||
|
|
||||||
|
uint64_t max_request_size;
|
||||||
|
|
||||||
bool use_ssl = false;
|
bool use_ssl = false;
|
||||||
Ref<CryptoKey> key;
|
Ref<CryptoKey> key;
|
||||||
|
|
||||||
@ -98,6 +100,8 @@ public:
|
|||||||
|
|
||||||
WebServerSimple *_web_server;
|
WebServerSimple *_web_server;
|
||||||
|
|
||||||
|
uint64_t max_request_size;
|
||||||
|
|
||||||
RBMap<String, String> mimes;
|
RBMap<String, String> mimes;
|
||||||
|
|
||||||
Ref<X509Certificate> cert;
|
Ref<X509Certificate> cert;
|
||||||
|
@ -105,6 +105,22 @@ void WebServerSimple::set_worker_thread_count(const int val) {
|
|||||||
_worker_thread_count = val;
|
_worker_thread_count = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebServerSimple::MaxRequestSizeTypes WebServerSimple::get_max_request_size_type() {
|
||||||
|
return _max_request_size_type;
|
||||||
|
}
|
||||||
|
void WebServerSimple::set_max_request_size_type(const MaxRequestSizeTypes val) {
|
||||||
|
_max_request_size_type = val;
|
||||||
|
_apply_max_request_size_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebServerSimple::get_max_request_size() {
|
||||||
|
return _max_request_size;
|
||||||
|
}
|
||||||
|
void WebServerSimple::set_max_request_size(const int val) {
|
||||||
|
_max_request_size = val;
|
||||||
|
_apply_max_request_size_type();
|
||||||
|
}
|
||||||
|
|
||||||
void WebServerSimple::add_mime_type(const String &file_extension, const String &mime_type) {
|
void WebServerSimple::add_mime_type(const String &file_extension, const String &mime_type) {
|
||||||
_server->mimes[file_extension] = mime_type;
|
_server->mimes[file_extension] = mime_type;
|
||||||
}
|
}
|
||||||
@ -200,6 +216,9 @@ void WebServerSimple::_stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WebServerSimple::WebServerSimple() {
|
WebServerSimple::WebServerSimple() {
|
||||||
|
_max_request_size_type = MAX_REQUEST_SIZE_TYPE_MEGA_BYTE;
|
||||||
|
_max_request_size = 3;
|
||||||
|
|
||||||
_bind_port = 8080;
|
_bind_port = 8080;
|
||||||
_bind_host = "127.0.0.1";
|
_bind_host = "127.0.0.1";
|
||||||
|
|
||||||
@ -216,6 +235,8 @@ WebServerSimple::WebServerSimple() {
|
|||||||
|
|
||||||
_server.instance();
|
_server.instance();
|
||||||
_server->_web_server = this;
|
_server->_web_server = this;
|
||||||
|
|
||||||
|
_apply_max_request_size_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
WebServerSimple::~WebServerSimple() {
|
WebServerSimple::~WebServerSimple() {
|
||||||
@ -228,6 +249,10 @@ WebServerSimple::~WebServerSimple() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebServerSimple::_apply_max_request_size_type() {
|
||||||
|
_server->max_request_size = (static_cast<uint64_t>(1) << (10 * static_cast<uint64_t>(_max_request_size_type))) * static_cast<uint64_t>(_max_request_size);
|
||||||
|
}
|
||||||
|
|
||||||
void WebServerSimple::_notification(int p_what) {
|
void WebServerSimple::_notification(int p_what) {
|
||||||
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
|
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
|
||||||
if (_single_threaded_poll) {
|
if (_single_threaded_poll) {
|
||||||
@ -271,10 +296,23 @@ void WebServerSimple::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_worker_thread_count", "val"), &WebServerSimple::set_worker_thread_count);
|
ClassDB::bind_method(D_METHOD("set_worker_thread_count", "val"), &WebServerSimple::set_worker_thread_count);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "worker_thread_count"), "set_worker_thread_count", "get_worker_thread_count");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "worker_thread_count"), "set_worker_thread_count", "get_worker_thread_count");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_max_request_size_type"), &WebServerSimple::get_max_request_size_type);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_max_request_size_type", "val"), &WebServerSimple::set_max_request_size_type);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_request_size_type", PROPERTY_HINT_ENUM, "B,KB,MB,GB"), "set_max_request_size_type", "get_max_request_size_type");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_max_request_size"), &WebServerSimple::get_max_request_size);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_max_request_size", "val"), &WebServerSimple::set_max_request_size);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_request_size"), "set_max_request_size", "get_max_request_size");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_mime_type", "file_extension", "mime_type"), &WebServerSimple::add_mime_type);
|
ClassDB::bind_method(D_METHOD("add_mime_type", "file_extension", "mime_type"), &WebServerSimple::add_mime_type);
|
||||||
ClassDB::bind_method(D_METHOD("remove_mime_type", "file_extension"), &WebServerSimple::remove_mime_type);
|
ClassDB::bind_method(D_METHOD("remove_mime_type", "file_extension"), &WebServerSimple::remove_mime_type);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_running"), &WebServerSimple::is_running);
|
ClassDB::bind_method(D_METHOD("is_running"), &WebServerSimple::is_running);
|
||||||
|
|
||||||
|
BIND_ENUM_CONSTANT(MAX_REQUEST_SIZE_TYPE_BYTE);
|
||||||
|
BIND_ENUM_CONSTANT(MAX_REQUEST_SIZE_TYPE_KILO_BYTE);
|
||||||
|
BIND_ENUM_CONSTANT(MAX_REQUEST_SIZE_TYPE_MEGA_BYTE);
|
||||||
|
BIND_ENUM_CONSTANT(MAX_REQUEST_SIZE_TYPE_GIGA_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebServerSimple::_server_thread_poll(void *data) {
|
void WebServerSimple::_server_thread_poll(void *data) {
|
||||||
|
@ -47,6 +47,13 @@ class WebServerSimple : public WebServer {
|
|||||||
GDCLASS(WebServerSimple, WebServer);
|
GDCLASS(WebServerSimple, WebServer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum MaxRequestSizeTypes {
|
||||||
|
MAX_REQUEST_SIZE_TYPE_BYTE = 0,
|
||||||
|
MAX_REQUEST_SIZE_TYPE_KILO_BYTE = 1,
|
||||||
|
MAX_REQUEST_SIZE_TYPE_MEGA_BYTE = 2,
|
||||||
|
MAX_REQUEST_SIZE_TYPE_GIGA_BYTE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
int get_bind_port();
|
int get_bind_port();
|
||||||
void set_bind_port(const int val);
|
void set_bind_port(const int val);
|
||||||
|
|
||||||
@ -71,6 +78,18 @@ public:
|
|||||||
int get_worker_thread_count();
|
int get_worker_thread_count();
|
||||||
void set_worker_thread_count(const int val);
|
void set_worker_thread_count(const int val);
|
||||||
|
|
||||||
|
MaxRequestSizeTypes get_max_request_size_type();
|
||||||
|
void set_max_request_size_type(const MaxRequestSizeTypes val);
|
||||||
|
|
||||||
|
// Note, that the implementation is extremely simple for now.
|
||||||
|
// This includes the entire request header, including file uploads,
|
||||||
|
// as right now uploaded files are stored in memory,
|
||||||
|
// so this will not change until temp files are implemented.
|
||||||
|
// (A big file upload / request can eat all the ram in a server!)
|
||||||
|
// Also 0 means 0, not unlimited -> This should NOT change (Reason: line above).
|
||||||
|
int get_max_request_size();
|
||||||
|
void set_max_request_size(const int val);
|
||||||
|
|
||||||
void add_mime_type(const String &file_extension, const String &mime_type);
|
void add_mime_type(const String &file_extension, const String &mime_type);
|
||||||
void remove_mime_type(const String &file_extension);
|
void remove_mime_type(const String &file_extension);
|
||||||
|
|
||||||
@ -83,6 +102,8 @@ public:
|
|||||||
~WebServerSimple();
|
~WebServerSimple();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _apply_max_request_size_type();
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -101,6 +122,9 @@ protected:
|
|||||||
|
|
||||||
bool _single_threaded_poll;
|
bool _single_threaded_poll;
|
||||||
|
|
||||||
|
MaxRequestSizeTypes _max_request_size_type;
|
||||||
|
int _max_request_size;
|
||||||
|
|
||||||
Ref<HTTPServerSimple> _server;
|
Ref<HTTPServerSimple> _server;
|
||||||
bool _server_quit;
|
bool _server_quit;
|
||||||
Mutex _server_lock;
|
Mutex _server_lock;
|
||||||
@ -110,4 +134,6 @@ protected:
|
|||||||
static void _server_thread_poll(void *data);
|
static void _server_thread_poll(void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VARIANT_ENUM_CAST(WebServerSimple::MaxRequestSizeTypes);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user