diff options
-rw-r--r-- | core/io/http_client.cpp | 85 | ||||
-rw-r--r-- | core/io/http_client.h | 1 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 8 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_class.cpp | 10 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_class.h | 3 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.cpp | 5 |
6 files changed, 69 insertions, 43 deletions
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index b25b1934ff..e5c6d2a4f2 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -278,6 +278,7 @@ void HTTPClient::close() { body_size = -1; body_left = 0; chunk_left = 0; + chunk_trailer_part = 0; read_until_eof = false; response_num = 0; handshaking = false; @@ -421,6 +422,7 @@ Error HTTPClient::poll() { chunked = false; body_left = 0; chunk_left = 0; + chunk_trailer_part = false; read_until_eof = false; response_str.clear(); response_headers.clear(); @@ -504,13 +506,37 @@ PoolByteArray HTTPClient::read_response_body_chunk() { ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray()); + PoolByteArray ret; Error err = OK; if (chunked) { while (true) { - if (chunk_left == 0) { + if (chunk_trailer_part) { + // We need to consume the trailer part too or keep-alive will break + uint8_t b; + int rec = 0; + err = _get_http_data(&b, 1, rec); + + if (rec == 0) + break; + + chunk.push_back(b); + int cs = chunk.size(); + if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) { + if (cs == 2) { + // Finally over + chunk_trailer_part = false; + status = STATUS_CONNECTED; + chunk.clear(); + break; + } else { + // We do not process nor return the trailer data + chunk.clear(); + } + } + } else if (chunk_left == 0) { // Reading length uint8_t b; int rec = 0; @@ -524,7 +550,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { if (chunk.size() > 32) { ERR_PRINT("HTTP Invalid chunk hex len"); status = STATUS_CONNECTION_ERROR; - return PoolByteArray(); + break; } if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') { @@ -542,22 +568,22 @@ PoolByteArray HTTPClient::read_response_body_chunk() { else { ERR_PRINT("HTTP Chunk len not in hex!!"); status = STATUS_CONNECTION_ERROR; - return PoolByteArray(); + break; } len <<= 4; len |= v; if (len > (1 << 24)) { ERR_PRINT("HTTP Chunk too big!! >16mb"); status = STATUS_CONNECTION_ERROR; - return PoolByteArray(); + break; } } if (len == 0) { // End reached! - status = STATUS_CONNECTED; + chunk_trailer_part = true; chunk.clear(); - return PoolByteArray(); + break; } chunk_left = len + 2; @@ -577,18 +603,13 @@ PoolByteArray HTTPClient::read_response_body_chunk() { if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') { ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)"); status = STATUS_CONNECTION_ERROR; - return PoolByteArray(); + break; } - PoolByteArray ret; ret.resize(chunk.size() - 2); - { - PoolByteArray::Write w = ret.write(); - copymem(w.ptr(), chunk.ptr(), chunk.size() - 2); - } + PoolByteArray::Write w = ret.write(); + copymem(w.ptr(), chunk.ptr(), chunk.size() - 2); chunk.clear(); - - return ret; } break; @@ -598,45 +619,26 @@ PoolByteArray HTTPClient::read_response_body_chunk() { } else { int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size; - PoolByteArray ret; ret.resize(to_read); int _offset = 0; - while (read_until_eof || to_read > 0) { + while (to_read > 0) { int rec = 0; { PoolByteArray::Write w = ret.write(); err = _get_http_data(w.ptr() + _offset, to_read, rec); } - if (rec < 0) { - if (to_read > 0) // Ended up reading less - ret.resize(_offset); + if (rec <= 0) { // Ended up reading less + ret.resize(_offset); break; } else { _offset += rec; + to_read -= rec; if (!read_until_eof) { body_left -= rec; - to_read -= rec; - } else { - if (rec < to_read) { - ret.resize(_offset); - err = ERR_FILE_EOF; - break; - } - ret.resize(_offset + to_read); } } - } - if (!read_until_eof) { - if (body_left == 0) { - status = STATUS_CONNECTED; - } - return ret; - } else { - if (err == ERR_FILE_EOF) { - err = OK; // EOF is expected here - close(); - return ret; - } + if (err != OK) + break; } } @@ -651,12 +653,12 @@ PoolByteArray HTTPClient::read_response_body_chunk() { status = STATUS_CONNECTION_ERROR; } - } else if (body_left == 0 && !chunked) { + } else if (body_left == 0 && !chunked && !read_until_eof) { status = STATUS_CONNECTED; } - return PoolByteArray(); + return ret; } HTTPClient::Status HTTPClient::get_status() const { @@ -718,6 +720,7 @@ HTTPClient::HTTPClient() { body_left = 0; read_until_eof = false; chunk_left = 0; + chunk_trailer_part = false; response_num = 0; ssl = false; blocking = false; diff --git a/core/io/http_client.h b/core/io/http_client.h index 1ad44d5f01..85ee1959a2 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -172,6 +172,7 @@ private: bool chunked; Vector<uint8_t> chunk; int chunk_left; + bool chunk_trailer_part; int body_size; int body_left; bool read_until_eof; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 77e9b1f1f4..2161b15591 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -97,7 +97,7 @@ #define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type #define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array" -#define BINDINGS_GENERATOR_VERSION UINT32_C(6) +#define BINDINGS_GENERATOR_VERSION UINT32_C(7) const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n"; @@ -854,6 +854,12 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str if (itype.is_singleton) { // Add the type name and the singleton pointer as static fields + output.push_back(MEMBER_BEGIN "private static Godot.Object singleton;\n"); + output.push_back(MEMBER_BEGIN "public static Godot.Object Singleton\n" INDENT2 "{\n" INDENT3 + "get\n" INDENT3 "{\n" INDENT4 "if (singleton == null)\n" INDENT5 + "singleton = Engine.GetSingleton(" BINDINGS_NATIVE_NAME_FIELD ");\n" INDENT4 + "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n"); + output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \""); output.push_back(itype.name); output.push_back("\";\n"); diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index bf2a84c708..92324d73f9 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -59,8 +59,16 @@ MonoType *GDMonoClass::get_mono_type() { return get_mono_type(mono_class); } -bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const { +uint32_t GDMonoClass::get_flags() const { + return mono_class_get_flags(mono_class); +} +bool GDMonoClass::is_static() const { + uint32_t static_class_flags = MONO_TYPE_ATTR_ABSTRACT | MONO_TYPE_ATTR_SEALED; + return (get_flags() & static_class_flags) == static_class_flags; +} + +bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const { return mono_class_is_assignable_from(mono_class, p_from->mono_class); } diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 08718ec1a4..4af909450e 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -109,6 +109,9 @@ public: String get_full_name() const; MonoType *get_mono_type(); + uint32_t get_flags() const; + bool is_static() const; + bool is_assignable_from(GDMonoClass *p_from) const; _FORCE_INLINE_ StringName get_namespace() const { return namespace_name; } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 3b97339fea..6cc1c8afc2 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -374,6 +374,11 @@ GDMonoClass *type_get_proxy_class(const StringName &p_type) { GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); + if (klass && klass->is_static()) { + // A static class means this is a Godot singleton class. If an instance is needed we use Godot.Object. + return mono_cache.class_GodotObject; + } + #ifdef TOOLS_ENABLED if (!klass) { return GDMono::get_singleton()->get_editor_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); |