From 069c955af7d75bfb71df7aca01e82807551e9c7a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 21 Apr 2022 00:05:52 +0200 Subject: [PATCH] Use a floating-point number for the `timeout` property in HTTPRequest This allows for greater precision when specifying a timeout in HTTPRequest in `3.x`, similar to what is already possible in `master`. --- doc/classes/HTTPRequest.xml | 10 ++++++---- scene/main/http_request.cpp | 18 +++++++++++------- scene/main/http_request.h | 6 +++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index b7ebdccf747..2c7f20ef955 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -142,19 +142,21 @@ - Maximum allowed size for response bodies. + Maximum allowed size for response bodies ([code]-1[/code] means no limit). When only small files are expected, this can be used to prevent disallow receiving files that are too large, preventing potential denial of service attacks. The size of the buffer used and maximum bytes to read per iteration. See [member HTTPClient.read_chunk_size]. Set this to a lower value (e.g. 4096 for 4 KiB) when downloading small files to decrease memory usage at the cost of download speeds. - The file to download into. Will output any received file into it. + The file to download into. If set to a non-empty string, the request output will be written to the file located at the path. If a file already exists at the specified location, it will be overwritten as soon as body data begins to be received. + [b]Note:[/b] Folders are not automatically created when the file is created. If [member download_file] points to a subfolder, it's recommended to create the necessary folders beforehand using [method Directory.make_dir_recursive] to ensure the file can be written. - Maximum number of allowed redirects. + Maximum number of allowed redirects. This is used to prevent endless redirect loops. - + + If set to a value greater than [code]0.0[/code], the HTTP request will time out after [code]timeout[/code] seconds have passed and the request is not [i]completed[/i] yet. For small HTTP requests such as REST API usage, set [member timeout] to a value greater than [code]0.0[/code] to prevent the application from getting stuck if the request fails to get a response in a timely manner. For file downloads, leave this to [code]0.0[/code] to prevent the download from failing if it takes too much time. If [code]true[/code], multithreading is used to improve performance. diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 6384bf8c92a..0a924358675 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -81,7 +81,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector &p_cust ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one."); - if (timeout > 0) { + if (timeout > 0.0) { timer->stop(); timer->start(timeout); } @@ -471,12 +471,16 @@ void HTTPRequest::set_https_proxy(const String &p_host, int p_port) { client->set_https_proxy(p_host, p_port); } -void HTTPRequest::set_timeout(int p_timeout) { - ERR_FAIL_COND(p_timeout < 0); - timeout = p_timeout; +void HTTPRequest::set_timeout(double p_timeout) { + if (Math::is_zero_approx(p_timeout)) { + timeout = 0.0; + } else { + ERR_FAIL_COND(p_timeout < 0.0); + timeout = p_timeout; + } } -int HTTPRequest::get_timeout() { +double HTTPRequest::get_timeout() { return timeout; } @@ -526,7 +530,7 @@ void HTTPRequest::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "timeout", PROPERTY_HINT_RANGE, "0,86400"), "set_timeout", "get_timeout"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "timeout", PROPERTY_HINT_RANGE, "0,3600,0.1,or_greater"), "set_timeout", "get_timeout"); ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::POOL_STRING_ARRAY, "headers"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "body"))); @@ -565,7 +569,7 @@ HTTPRequest::HTTPRequest() { timer->set_one_shot(true); timer->connect("timeout", this, "_timeout"); add_child(timer); - timeout = 0; + timeout = 0.0; } HTTPRequest::~HTTPRequest() { diff --git a/scene/main/http_request.h b/scene/main/http_request.h index e8afa7a45bb..9aa293a251a 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -94,7 +94,7 @@ private: int max_redirects; - int timeout; + double timeout; void _redirect_request(const String &p_new_url); @@ -138,8 +138,8 @@ public: Timer *timer; - void set_timeout(int p_timeout); - int get_timeout(); + void set_timeout(double p_timeout); + double get_timeout(); void _timeout();