diff options
Diffstat (limited to 'modules/websocket')
23 files changed, 107 insertions, 92 deletions
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index d362bcc10f..40c0ad17ad 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -6,7 +6,7 @@ <description> This class implements a WebSocket client compatible with any RFC 6455-compliant WebSocket server. This client can be optionally used as a network peer for the [MultiplayerAPI]. - After starting the client ([method connect_to_url]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). + After starting the client ([method connect_to_url]), you will need to [method MultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). You will receive appropriate signals when connecting, disconnecting, or when new data is available. </description> <tutorials> @@ -17,11 +17,11 @@ </return> <argument index="0" name="url" type="String"> </argument> - <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray( )"> + <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()"> </argument> <argument index="2" name="gd_mp_api" type="bool" default="false"> </argument> - <argument index="3" name="custom_headers" type="PackedStringArray" default="PackedStringArray( )"> + <argument index="3" name="custom_headers" type="PackedStringArray" default="PackedStringArray()"> </argument> <description> Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested. diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml index 0679acf78a..ee1b60f739 100644 --- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml +++ b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketMultiplayerPeer" inherits="NetworkedMultiplayerPeer" version="4.0"> +<class name="WebSocketMultiplayerPeer" inherits="MultiplayerPeer" version="4.0"> <brief_description> Base class for WebSocket server and client. </brief_description> @@ -39,7 +39,7 @@ </methods> <members> <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" /> - <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="NetworkedMultiplayerPeer.TransferMode" default="2" /> + <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="MultiplayerPeer.TransferMode" default="2" /> </members> <signals> <signal name="peer_packet"> diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index f7805209e2..26e09fd8b3 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -5,7 +5,7 @@ </brief_description> <description> This class implements a WebSocket server that can also support the high-level multiplayer API. - After starting the server ([method listen]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). When clients connect, disconnect, or send data, you will receive the appropriate signal. + After starting the server ([method listen]), you will need to [method MultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). When clients connect, disconnect, or send data, you will receive the appropriate signal. [b]Note:[/b] Not available in HTML5 exports. </description> <tutorials> @@ -63,7 +63,7 @@ </return> <argument index="0" name="port" type="int"> </argument> - <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray( )"> + <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray()"> </argument> <argument index="2" name="gd_mp_api" type="bool" default="false"> </argument> @@ -89,6 +89,9 @@ <member name="ca_chain" type="X509Certificate" setter="set_ca_chain" getter="get_ca_chain"> When using SSL (see [member private_key] and [member ssl_certificate]), you can set this to a valid [X509Certificate] to be provided as additional CA chain information during the SSL handshake. </member> + <member name="handshake_timeout" type="float" setter="set_handshake_timeout" getter="get_handshake_timeout" default="3.0"> + The time in seconds before a pending client (i.e. a client that has not yet finished the HTTP handshake) is considered stale and forcefully disconnected. + </member> <member name="private_key" type="CryptoKey" setter="set_private_key" getter="get_private_key"> When set to a valid [CryptoKey] (along with [member ssl_certificate]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol). </member> diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp index b02d212c42..2e61cbfc08 100644 --- a/modules/websocket/editor_debugger_server_websocket.cpp +++ b/modules/websocket/editor_debugger_server_websocket.cpp @@ -50,9 +50,9 @@ void EditorDebuggerServerWebSocket::poll() { Error EditorDebuggerServerWebSocket::start() { int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); - Vector<String> protocols; - protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer. - return server->listen(remote_port, protocols); + Vector<String> compatible_protocols; + compatible_protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer. + return server->listen(remote_port, compatible_protocols); } void EditorDebuggerServerWebSocket::stop() { diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 25b6d6ef0e..744053b6e2 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -107,7 +107,7 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const { return _peer; } -NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const { +MultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const { if (_peer->is_connected_to_host()) { if (_is_connecting) return CONNECTION_CONNECTING; @@ -121,8 +121,8 @@ void EMWSClient::disconnect_from_host(int p_code, String p_reason) { _peer->close(p_code, p_reason); } -IP_Address EMWSClient::get_connected_host() const { - ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export."); +IPAddress EMWSClient::get_connected_host() const { + ERR_FAIL_V_MSG(IPAddress(), "Not supported in HTML5 export."); } uint16_t EMWSClient::get_connected_port() const { diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index 2ab7dc83d0..ca2d7ed986 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -56,7 +56,7 @@ public: Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocol = Vector<String>(), const Vector<String> p_custom_headers = Vector<String>()); Ref<WebSocketPeer> get_peer(int p_peer_id) const; void disconnect_from_host(int p_code = 1000, String p_reason = ""); - IP_Address get_connected_host() const; + IPAddress get_connected_host() const; uint16_t get_connected_port() const; virtual ConnectionStatus get_connection_status() const; int get_max_packet_size() const; diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 5e75e10d68..1ad3bdc825 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -93,8 +93,8 @@ void EMWSPeer::close(int p_code, String p_reason) { peer_sock = -1; }; -IP_Address EMWSPeer::get_connected_host() const { - ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export."); +IPAddress EMWSPeer::get_connected_host() const { + ERR_FAIL_V_MSG(IPAddress(), "Not supported in HTML5 export."); }; uint16_t EMWSPeer::get_connected_port() const { diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index abe5bf2bdb..73e701720b 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -73,7 +73,7 @@ public: virtual void close(int p_code = 1000, String p_reason = ""); virtual bool is_connected_to_host() const; - virtual IP_Address get_connected_host() const; + virtual IPAddress get_connected_host() const; virtual uint16_t get_connected_port() const; virtual WriteMode get_write_mode() const; diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp index a35d84f372..4a4f09a943 100644 --- a/modules/websocket/emws_server.cpp +++ b/modules/websocket/emws_server.cpp @@ -58,8 +58,8 @@ Vector<String> EMWSServer::get_protocols() const { return out; } -IP_Address EMWSServer::get_peer_address(int p_peer_id) const { - return IP_Address(); +IPAddress EMWSServer::get_peer_address(int p_peer_id) const { + return IPAddress(); } int EMWSServer::get_peer_port(int p_peer_id) const { diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index 4179b20ffe..d36e3a3557 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -33,7 +33,7 @@ #ifdef JAVASCRIPT_ENABLED -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "emws_peer.h" #include "websocket_server.h" @@ -47,7 +47,7 @@ public: bool is_listening() const; bool has_peer(int p_id) const; Ref<WebSocketPeer> get_peer(int p_id) const; - IP_Address get_peer_address(int p_peer_id) const; + IPAddress get_peer_address(int p_peer_id) const; int get_peer_port(int p_peer_id) const; void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = ""); int get_max_packet_size() const; diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index 425013f811..af1dc8ff54 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -42,35 +42,22 @@ Error WebSocketClient::connect_to_url(String p_url, const Vector<String> p_proto _is_multiplayer = gd_mp_api; String host = p_url; - String path = "/"; - int p_len = -1; - int port = 80; + String path; + String scheme; + int port = 0; + Error err = p_url.parse_url(scheme, host, port, path); + ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid URL: " + p_url); + bool ssl = false; - if (host.begins_with("wss://")) { - ssl = true; // we should implement this - host = host.substr(6, host.length() - 6); - port = 443; - } else { - ssl = false; - if (host.begins_with("ws://")) { - host = host.substr(5, host.length() - 5); - } + if (scheme == "wss://") { + ssl = true; } - - // Path - p_len = host.find("/"); - if (p_len != -1) { - path = host.substr(p_len, host.length() - p_len); - host = host.substr(0, p_len); + if (port == 0) { + port = ssl ? 443 : 80; } - - // Port - p_len = host.rfind(":"); - if (p_len != -1 && p_len == host.find(":")) { - port = host.substr(p_len, host.length() - p_len).to_int(); - host = host.substr(0, p_len); + if (path.is_empty()) { + path = "/"; } - return connect_to_host(host, path, port, ssl, p_protocols, p_custom_headers); } @@ -139,12 +126,12 @@ void WebSocketClient::_bind_methods() { ClassDB::bind_method(D_METHOD("set_verify_ssl_enabled", "enabled"), &WebSocketClient::set_verify_ssl_enabled); ClassDB::bind_method(D_METHOD("is_verify_ssl_enabled"), &WebSocketClient::is_verify_ssl_enabled); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", 0), "set_verify_ssl_enabled", "is_verify_ssl_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_verify_ssl_enabled", "is_verify_ssl_enabled"); ClassDB::bind_method(D_METHOD("get_trusted_ssl_certificate"), &WebSocketClient::get_trusted_ssl_certificate); ClassDB::bind_method(D_METHOD("set_trusted_ssl_certificate"), &WebSocketClient::set_trusted_ssl_certificate); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trusted_ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_trusted_ssl_certificate", "get_trusted_ssl_certificate"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trusted_ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_trusted_ssl_certificate", "get_trusted_ssl_certificate"); ADD_SIGNAL(MethodInfo("data_received")); ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol"))); diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 0225c9b3d3..c7f17f1ffb 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -57,7 +57,7 @@ public: virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocol = Vector<String>(), const Vector<String> p_custom_headers = Vector<String>()) = 0; virtual void disconnect_from_host(int p_code = 1000, String p_reason = "") = 0; - virtual IP_Address get_connected_host() const = 0; + virtual IPAddress get_connected_host() const = 0; virtual uint16_t get_connected_port() const = 0; virtual bool is_server() const override; diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index fa0ef7060f..1beeb67b91 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -123,13 +123,13 @@ Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer } // -// NetworkedMultiplayerPeer +// MultiplayerPeer // void WebSocketMultiplayerPeer::set_transfer_mode(TransferMode p_mode) { // Websocket uses TCP, reliable } -NetworkedMultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const { +MultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const { // Websocket uses TCP, reliable return TRANSFER_MODE_RELIABLE; } diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index 48a6607d89..e3ccd1a795 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -32,12 +32,12 @@ #define WEBSOCKET_MULTIPLAYER_PEER_H #include "core/error/error_list.h" -#include "core/io/networked_multiplayer_peer.h" +#include "core/io/multiplayer_peer.h" #include "core/templates/list.h" #include "websocket_peer.h" -class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer { - GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer); +class WebSocketMultiplayerPeer : public MultiplayerPeer { + GDCLASS(WebSocketMultiplayerPeer, MultiplayerPeer); private: Vector<uint8_t> _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size); @@ -78,7 +78,7 @@ protected: int _gen_unique_id() const; public: - /* NetworkedMultiplayerPeer */ + /* MultiplayerPeer */ void set_transfer_mode(TransferMode p_mode) override; TransferMode get_transfer_mode() const override; void set_target_peer(int p_target_peer) override; diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index 2ba83637f9..e9bb20f21f 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -55,7 +55,7 @@ public: virtual void close(int p_code = 1000, String p_reason = "") = 0; virtual bool is_connected_to_host() const = 0; - virtual IP_Address get_connected_host() const = 0; + virtual IPAddress get_connected_host() const = 0; virtual uint16_t get_connected_port() const = 0; virtual bool was_string_packet() const = 0; virtual void set_no_delay(bool p_enabled) = 0; diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index f57e8d959c..b996852f28 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -34,7 +34,7 @@ GDCINULL(WebSocketServer); WebSocketServer::WebSocketServer() { _peer_id = 1; - bind_ip = IP_Address("*"); + bind_ip = IPAddress("*"); } WebSocketServer::~WebSocketServer() { @@ -55,15 +55,19 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_private_key"), &WebSocketServer::get_private_key); ClassDB::bind_method(D_METHOD("set_private_key"), &WebSocketServer::set_private_key); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", 0), "set_private_key", "get_private_key"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", PROPERTY_USAGE_NONE), "set_private_key", "get_private_key"); ClassDB::bind_method(D_METHOD("get_ssl_certificate"), &WebSocketServer::get_ssl_certificate); ClassDB::bind_method(D_METHOD("set_ssl_certificate"), &WebSocketServer::set_ssl_certificate); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ssl_certificate", "get_ssl_certificate"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_ssl_certificate", "get_ssl_certificate"); ClassDB::bind_method(D_METHOD("get_ca_chain"), &WebSocketServer::get_ca_chain); ClassDB::bind_method(D_METHOD("set_ca_chain"), &WebSocketServer::set_ca_chain); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ca_chain", "get_ca_chain"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_ca_chain", "get_ca_chain"); + + ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout); + ClassDB::bind_method(D_METHOD("set_handshake_timeout", "timeout"), &WebSocketServer::set_handshake_timeout); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout"); ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason"))); ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close"))); @@ -71,11 +75,11 @@ void WebSocketServer::_bind_methods() { ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id"))); } -IP_Address WebSocketServer::get_bind_ip() const { +IPAddress WebSocketServer::get_bind_ip() const { return bind_ip; } -void WebSocketServer::set_bind_ip(const IP_Address &p_bind_ip) { +void WebSocketServer::set_bind_ip(const IPAddress &p_bind_ip) { ERR_FAIL_COND(is_listening()); ERR_FAIL_COND(!p_bind_ip.is_valid() && !p_bind_ip.is_wildcard()); bind_ip = p_bind_ip; @@ -108,7 +112,16 @@ void WebSocketServer::set_ca_chain(Ref<X509Certificate> p_ca_chain) { ca_chain = p_ca_chain; } -NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const { +float WebSocketServer::get_handshake_timeout() const { + return handshake_timeout / 1000.0; +} + +void WebSocketServer::set_handshake_timeout(float p_timeout) { + ERR_FAIL_COND(p_timeout <= 0.0); + handshake_timeout = p_timeout * 1000; +} + +MultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const { if (is_listening()) { return CONNECTION_CONNECTED; } diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 3fbd5e3b95..26864f3085 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -32,7 +32,7 @@ #define WEBSOCKET_H #include "core/crypto/crypto.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "websocket_multiplayer_peer.h" #include "websocket_peer.h" @@ -40,7 +40,7 @@ class WebSocketServer : public WebSocketMultiplayerPeer { GDCLASS(WebSocketServer, WebSocketMultiplayerPeer); GDCICLASS(WebSocketServer); - IP_Address bind_ip; + IPAddress bind_ip; protected: static void _bind_methods(); @@ -48,6 +48,7 @@ protected: Ref<CryptoKey> private_key; Ref<X509Certificate> ssl_cert; Ref<X509Certificate> ca_chain; + uint32_t handshake_timeout = 3000; public: virtual Error listen(int p_port, const Vector<String> p_protocols = Vector<String>(), bool gd_mp_api = false) = 0; @@ -57,7 +58,7 @@ public: virtual bool is_server() const override; ConnectionStatus get_connection_status() const override; - virtual IP_Address get_peer_address(int p_peer_id) const = 0; + virtual IPAddress get_peer_address(int p_peer_id) const = 0; virtual int get_peer_port(int p_peer_id) const = 0; virtual void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "") = 0; @@ -66,8 +67,8 @@ public: void _on_disconnect(int32_t p_peer_id, bool p_was_clean); void _on_close_request(int32_t p_peer_id, int p_code, String p_reason); - IP_Address get_bind_ip() const; - void set_bind_ip(const IP_Address &p_bind_ip); + IPAddress get_bind_ip() const; + void set_bind_ip(const IPAddress &p_bind_ip); Ref<CryptoKey> get_private_key() const; void set_private_key(Ref<CryptoKey> p_key); @@ -78,6 +79,9 @@ public: Ref<X509Certificate> get_ca_chain() const; void set_ca_chain(Ref<X509Certificate> p_ca_chain); + float get_handshake_timeout() const; + void set_handshake_timeout(float p_timeout); + WebSocketServer(); ~WebSocketServer(); }; diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index a075ae3982..49997b42d3 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -158,9 +158,10 @@ bool WSLClient::_verify_headers(String &r_protocol) { Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) { ERR_FAIL_COND_V(_connection.is_valid(), ERR_ALREADY_IN_USE); + ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER); _peer = Ref<WSLPeer>(memnew(WSLPeer)); - IP_Address addr; + IPAddress addr; if (!p_host.is_valid_ip_address()) { addr = IP::get_singleton()->resolve_hostname(p_host); @@ -287,7 +288,7 @@ Ref<WebSocketPeer> WSLClient::get_peer(int p_peer_id) const { return _peer; } -NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const { +MultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const { if (_peer->is_connected_to_host()) { return CONNECTION_CONNECTED; } @@ -316,8 +317,8 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) { _resp_pos = 0; } -IP_Address WSLClient::get_connected_host() const { - ERR_FAIL_COND_V(!_peer->is_connected_to_host(), IP_Address()); +IPAddress WSLClient::get_connected_host() const { + ERR_FAIL_COND_V(!_peer->is_connected_to_host(), IPAddress()); return _peer->get_connected_host(); } @@ -337,8 +338,8 @@ Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLClient::WSLClient() { - _peer.instance(); - _tcp.instance(); + _peer.instantiate(); + _tcp.instantiate(); disconnect_from_host(); } diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index e7c91ed333..849639ee8b 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -75,7 +75,7 @@ public: int get_max_packet_size() const; Ref<WebSocketPeer> get_peer(int p_peer_id) const; void disconnect_from_host(int p_code = 1000, String p_reason = ""); - IP_Address get_connected_host() const; + IPAddress get_connected_host() const; uint16_t get_connected_port() const; virtual ConnectionStatus get_connection_status() const; virtual void poll(); diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index dbbf86d0da..1dbadfed74 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -305,8 +305,8 @@ void WSLPeer::close(int p_code, String p_reason) { _packet_buffer.resize(0); } -IP_Address WSLPeer::get_connected_host() const { - ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), IP_Address()); +IPAddress WSLPeer::get_connected_host() const { + ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), IPAddress()); return _data->tcp->get_connected_host(); } diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index 5e6a7e8554..f1ea98d384 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -90,7 +90,7 @@ public: virtual void close_now(); virtual void close(int p_code = 1000, String p_reason = ""); virtual bool is_connected_to_host() const; - virtual IP_Address get_connected_host() const; + virtual IPAddress get_connected_host() const; virtual uint16_t get_connected_port() const; virtual WriteMode get_write_mode() const; diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 437eb2061b..c889562732 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -95,28 +95,33 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) { return true; } -Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) { - if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) { +Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uint64_t p_timeout) { + if (OS::get_singleton()->get_ticks_msec() - time > p_timeout) { + print_verbose(vformat("WebSocket handshake timed out after %.3f seconds.", p_timeout * 0.001)); return ERR_TIMEOUT; } + if (use_ssl) { Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL>>(connection); if (ssl.is_null()) { - return FAILED; + ERR_FAIL_V_MSG(ERR_BUG, "Couldn't get StreamPeerSSL for WebSocket handshake."); } ssl->poll(); if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) { return ERR_BUSY; } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) { + print_verbose(vformat("WebSocket SSL connection error during handshake (StreamPeerSSL status code %d).", ssl->get_status())); return FAILED; } } + if (!has_request) { int read = 0; while (true) { - ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "Response headers too big."); + ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "WebSocket response headers are too big."); Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); if (err != OK) { // Got an error + print_verbose(vformat("WebSocket error while getting partial data (StreamPeer error code %d).", err)); return FAILED; } else if (read != 1) { // Busy, wait next poll return ERR_BUSY; @@ -143,17 +148,21 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) { req_pos += 1; } } + if (has_request && response_sent < response.size() - 1) { int sent = 0; Error err = connection->put_partial_data((const uint8_t *)response.get_data() + response_sent, response.size() - response_sent - 1, sent); if (err != OK) { + print_verbose(vformat("WebSocket error while putting partial data (StreamPeer error code %d).", err)); return err; } response_sent += sent; } + if (response_sent < response.size() - 1) { return ERR_BUSY; } + return OK; } @@ -188,7 +197,7 @@ void WSLServer::poll() { List<Ref<PendingPeer>> remove_peers; for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) { Ref<PendingPeer> ppeer = E->get(); - Error err = ppeer->do_handshake(_protocols); + Error err = ppeer->do_handshake(_protocols, handshake_timeout); if (err == ERR_BUSY) { continue; } else if (err != OK) { @@ -272,8 +281,8 @@ Ref<WebSocketPeer> WSLServer::get_peer(int p_id) const { return _peer_map[p_id]; } -IP_Address WSLServer::get_peer_address(int p_peer_id) const { - ERR_FAIL_COND_V(!has_peer(p_peer_id), IP_Address()); +IPAddress WSLServer::get_peer_address(int p_peer_id) const { + ERR_FAIL_COND_V(!has_peer(p_peer_id), IPAddress()); return _peer_map[p_peer_id]->get_connected_host(); } @@ -301,7 +310,7 @@ Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLServer::WSLServer() { - _server.instance(); + _server.instantiate(); } WSLServer::~WSLServer() { diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 75669e12ee..a428c89f4f 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -40,13 +40,11 @@ #include "core/io/stream_peer_tcp.h" #include "core/io/tcp_server.h" -#define WSL_SERVER_TIMEOUT 1000 - class WSLServer : public WebSocketServer { GDCIIMPL(WSLServer, WebSocketServer); private: - class PendingPeer : public Reference { + class PendingPeer : public RefCounted { private: bool _parse_request(const Vector<String> p_protocols); @@ -64,7 +62,7 @@ private: CharString response; int response_sent = 0; - Error do_handshake(const Vector<String> p_protocols); + Error do_handshake(const Vector<String> p_protocols, uint64_t p_timeout); }; int _in_buf_size = DEF_BUF_SHIFT; @@ -73,7 +71,7 @@ private: int _out_pkt_size = DEF_PKT_SHIFT; List<Ref<PendingPeer>> _pending; - Ref<TCP_Server> _server; + Ref<TCPServer> _server; Vector<String> _protocols; public: @@ -84,7 +82,7 @@ public: int get_max_packet_size() const; bool has_peer(int p_id) const; Ref<WebSocketPeer> get_peer(int p_id) const; - IP_Address get_peer_address(int p_peer_id) const; + IPAddress get_peer_address(int p_peer_id) const; int get_peer_port(int p_peer_id) const; void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = ""); virtual void poll(); |