feat: updated engine

This commit is contained in:
Sara Gerretsen 2026-07-10 17:04:34 +02:00
parent cbe99774ff
commit f4cf6b3999
6607 changed files with 910135 additions and 430025 deletions

View file

@ -30,7 +30,13 @@
#include "http_request.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/stream_peer_gzip.h"
#include "core/object/callable_mp.h"
#include "core/object/class_db.h"
#include "core/os/os.h"
#include "core/os/thread.h"
#include "scene/main/timer.h"
Error HTTPRequest::_request() {
@ -199,13 +205,21 @@ void HTTPRequest::cancel_request() {
}
}
file.unref();
if (file.is_valid()) {
file.unref();
if (!download_complete && !keep_partial_download) {
DirAccess::remove_absolute(download_to_file);
}
}
decompressor.unref();
client->close();
body.clear();
got_response = false;
response_code = -1;
request_sent = false;
download_complete = false;
append_to_download_file = false;
requesting = false;
}
@ -229,6 +243,22 @@ Error HTTPRequest::_get_redirect_headers(Vector<String> *r_headers) {
return OK;
}
bool HTTPRequest::_is_automatic_redirect() const {
if (unlikely(method == HTTPClient::METHOD_CONNECT)) {
// Never automatically redirect CONNECT requests.
return false;
} else if (response_code == 301 || response_code == 302 || response_code == 303 || response_code == 305) {
// We change unsafe methods to GET for 301, 302, and 303, so these are always redirected.
// 305 is deprecated and treated as equivalent to 302.
return true;
} else if ((response_code == 307 || response_code == 308) && _is_method_safe()) {
// We only automatically redirect for safe methods on method-preserving status codes.
return true;
} else {
return false;
}
}
bool HTTPRequest::_handle_response(bool *ret_value) {
if (!client->has_response()) {
_defer_done(RESULT_NO_RESPONSE, 0, PackedStringArray(), PackedByteArray());
@ -249,8 +279,8 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
response_headers.push_back(E);
}
if (response_code == 301 || response_code == 302) {
// Handle redirect.
if (_is_automatic_redirect()) {
// Follow redirect.
if (max_redirects >= 0 && redirections >= max_redirects) {
_defer_done(RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray());
@ -361,6 +391,7 @@ bool HTTPRequest::_update_connection() {
}
if (body_len < 0) {
// Chunked transfer is done.
download_complete = true;
_defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
@ -411,7 +442,14 @@ bool HTTPRequest::_update_connection() {
}
if (!download_to_file.is_empty()) {
file = FileAccess::open(download_to_file, FileAccess::WRITE);
if (append_to_download_file && response_code == HTTPClient::RESPONSE_PARTIAL_CONTENT) {
file = FileAccess::open(download_to_file, FileAccess::READ_WRITE);
if (file.is_valid()) {
file->seek_end();
}
} else {
file = FileAccess::open(download_to_file, FileAccess::WRITE);
}
if (file.is_null()) {
_defer_done(RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray());
return true;
@ -480,11 +518,13 @@ bool HTTPRequest::_update_connection() {
if (body_len >= 0) {
if (downloaded.get() == body_len) {
download_complete = true;
_defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
} else if (client->get_status() == HTTPClient::STATUS_DISCONNECTED) {
// We read till EOF, with no errors. Request is done.
download_complete = true;
_defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
@ -574,6 +614,22 @@ String HTTPRequest::get_download_file() const {
return download_to_file;
}
void HTTPRequest::set_keep_partial_download(bool p_keep) {
keep_partial_download = p_keep;
}
bool HTTPRequest::is_keeping_partial_download() const {
return keep_partial_download;
}
void HTTPRequest::set_append_to_download_file(bool p_append) {
append_to_download_file = p_append;
}
bool HTTPRequest::is_appending_to_download_file() const {
return append_to_download_file;
}
void HTTPRequest::set_download_chunk_size(int p_chunk_size) {
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
@ -654,6 +710,12 @@ void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_download_file", "path"), &HTTPRequest::set_download_file);
ClassDB::bind_method(D_METHOD("get_download_file"), &HTTPRequest::get_download_file);
ClassDB::bind_method(D_METHOD("set_keep_partial_download", "enabled"), &HTTPRequest::set_keep_partial_download);
ClassDB::bind_method(D_METHOD("is_keeping_partial_download"), &HTTPRequest::is_keeping_partial_download);
ClassDB::bind_method(D_METHOD("set_append_to_download_file", "enabled"), &HTTPRequest::set_append_to_download_file);
ClassDB::bind_method(D_METHOD("is_appending_to_download_file"), &HTTPRequest::is_appending_to_download_file);
ClassDB::bind_method(D_METHOD("get_downloaded_bytes"), &HTTPRequest::get_downloaded_bytes);
ClassDB::bind_method(D_METHOD("get_body_size"), &HTTPRequest::get_body_size);
@ -668,6 +730,8 @@ void HTTPRequest::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE_PATH), "set_download_file", "get_download_file");
ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216,suffix:B"), "set_download_chunk_size", "get_download_chunk_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_partial_download"), "set_keep_partial_download", "is_keeping_partial_download");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "append_to_download_file"), "set_append_to_download_file", "is_appending_to_download_file");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accept_gzip"), "set_accept_gzip", "is_accepting_gzip");
ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000,suffix:B"), "set_body_size_limit", "get_body_size_limit");