diff options
Diffstat (limited to 'modules/websocket')
-rw-r--r-- | modules/websocket/doc_classes/WebSocketClient.xml | 2 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml | 2 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketPeer.xml | 2 | ||||
-rw-r--r-- | modules/websocket/doc_classes/WebSocketServer.xml | 2 | ||||
-rw-r--r-- | modules/websocket/emws_client.cpp | 10 | ||||
-rw-r--r-- | modules/websocket/emws_peer.cpp | 6 | ||||
-rw-r--r-- | modules/websocket/wsl_client.cpp | 72 | ||||
-rw-r--r-- | modules/websocket/wsl_client.h | 5 |
8 files changed, 71 insertions, 30 deletions
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index 5fcf51293d..ad2acf8a21 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketClient" inherits="WebSocketMultiplayerPeer" version="4.0"> +<class name="WebSocketClient" inherits="WebSocketMultiplayerPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> A WebSocket client implementation. </brief_description> diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml index 8d8ab220e2..4a617f4c82 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="MultiplayerPeer" version="4.0"> +<class name="WebSocketMultiplayerPeer" inherits="MultiplayerPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Base class for WebSocket server and client. </brief_description> diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml index 2f455c32fd..6466654517 100644 --- a/modules/websocket/doc_classes/WebSocketPeer.xml +++ b/modules/websocket/doc_classes/WebSocketPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketPeer" inherits="PacketPeer" version="4.0"> +<class name="WebSocketPeer" inherits="PacketPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> A class representing a specific WebSocket connection. </brief_description> diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index f901b089ea..ef3279aac4 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketServer" inherits="WebSocketMultiplayerPeer" version="4.0"> +<class name="WebSocketServer" inherits="WebSocketMultiplayerPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> A WebSocket server implementation. </brief_description> diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 2d029dfbbc..e051a3b564 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -31,6 +31,7 @@ #ifdef JAVASCRIPT_ENABLED #include "emws_client.h" + #include "core/config/project_settings.h" #include "core/io/ip.h" #include "emscripten.h" @@ -45,8 +46,9 @@ void EMWSClient::_esws_on_message(void *obj, const uint8_t *p_data, int p_data_s EMWSClient *client = static_cast<EMWSClient *>(obj); Error err = static_cast<EMWSPeer *>(*client->get_peer(1))->read_msg(p_data, p_data_size, p_is_string == 1); - if (err == OK) + if (err == OK) { client->_on_peer_packet(); + } } void EMWSClient::_esws_on_error(void *obj) { @@ -71,8 +73,9 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, String proto_string; for (int i = 0; i < p_protocols.size(); i++) { - if (i != 0) + if (i != 0) { proto_string += ","; + } proto_string += p_protocols[i]; } @@ -109,8 +112,9 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const { MultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const { if (_peer->is_connected_to_host()) { - if (_is_connecting) + if (_is_connecting) { return CONNECTION_CONNECTING; + } return CONNECTION_CONNECTED; } diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 77a96c8e4f..86169f88e9 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -31,6 +31,7 @@ #ifdef JAVASCRIPT_ENABLED #include "emws_peer.h" + #include "core/io/ip.h" void EMWSPeer::set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size) { @@ -66,8 +67,9 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { } Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - if (_in_buffer.packets_left() == 0) + if (_in_buffer.packets_left() == 0) { return ERR_UNAVAILABLE; + } int read = 0; Error err = _in_buffer.read_packet(_packet_buffer.ptrw(), _packet_buffer.size(), &_is_string, read); @@ -109,7 +111,7 @@ void EMWSPeer::close(int p_code, String p_reason) { IPAddress EMWSPeer::get_connected_host() const { ERR_FAIL_V_MSG(IPAddress(), "Not supported in HTML5 export."); -}; +} uint16_t EMWSPeer::get_connected_port() const { ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index be1c75c354..1ef571b6ee 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -163,22 +163,24 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, _peer = Ref<WSLPeer>(memnew(WSLPeer)); if (p_host.is_valid_ip_address()) { - ip_candidates.clear(); - ip_candidates.push_back(IPAddress(p_host)); + _ip_candidates.push_back(IPAddress(p_host)); } else { - ip_candidates = IP::get_singleton()->resolve_hostname_addresses(p_host); - } - - ERR_FAIL_COND_V(ip_candidates.is_empty(), ERR_INVALID_PARAMETER); - - String port = ""; - if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) { - port = ":" + itos(p_port); + // Queue hostname for resolution. + _resolver_id = IP::get_singleton()->resolve_hostname_queue_item(p_host); + ERR_FAIL_COND_V(_resolver_id == IP::RESOLVER_INVALID_ID, ERR_INVALID_PARAMETER); + // Check if it was found in cache. + IP::ResolverStatus ip_status = IP::get_singleton()->get_resolve_item_status(_resolver_id); + if (ip_status == IP::RESOLVER_STATUS_DONE) { + _ip_candidates = IP::get_singleton()->get_resolve_item_addresses(_resolver_id); + IP::get_singleton()->erase_resolve_item(_resolver_id); + _resolver_id = IP::RESOLVER_INVALID_ID; + } } - Error err = ERR_BUG; // Should be at least one entry. - while (ip_candidates.size() > 0) { - err = _tcp->connect_to_host(ip_candidates.pop_front(), p_port); + // We assume OK while hostname resolution is pending. + Error err = _resolver_id != IP::RESOLVER_INVALID_ID ? OK : FAILED; + while (_ip_candidates.size()) { + err = _tcp->connect_to_host(_ip_candidates.pop_front(), p_port); if (err == OK) { break; } @@ -200,8 +202,11 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, } _key = WSLPeer::generate_key(); - // TODO custom extra headers (allow overriding this too?) String request = "GET " + p_path + " HTTP/1.1\r\n"; + String port = ""; + if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) { + port = ":" + itos(p_port); + } request += "Host: " + p_host + port + "\r\n"; request += "Upgrade: websocket\r\n"; request += "Connection: Upgrade\r\n"; @@ -231,6 +236,30 @@ int WSLClient::get_max_packet_size() const { } void WSLClient::poll() { + if (_resolver_id != IP::RESOLVER_INVALID_ID) { + IP::ResolverStatus ip_status = IP::get_singleton()->get_resolve_item_status(_resolver_id); + if (ip_status == IP::RESOLVER_STATUS_WAITING) { + return; + } + // Anything else is either a candidate or a failure. + Error err = FAILED; + if (ip_status == IP::RESOLVER_STATUS_DONE) { + _ip_candidates = IP::get_singleton()->get_resolve_item_addresses(_resolver_id); + while (_ip_candidates.size()) { + err = _tcp->connect_to_host(_ip_candidates.pop_front(), _port); + if (err == OK) { + break; + } + } + } + IP::get_singleton()->erase_resolve_item(_resolver_id); + _resolver_id = IP::RESOLVER_INVALID_ID; + if (err != OK) { + disconnect_from_host(); + _on_error(); + return; + } + } if (_peer->is_connected_to_host()) { _peer->poll(); if (!_peer->is_connected_to_host()) { @@ -251,7 +280,7 @@ void WSLClient::poll() { _on_error(); break; case StreamPeerTCP::STATUS_CONNECTED: { - ip_candidates.clear(); + _ip_candidates.clear(); Ref<StreamPeerSSL> ssl; if (_use_ssl) { if (_connection == _tcp) { @@ -282,9 +311,9 @@ void WSLClient::poll() { _do_handshake(); } break; case StreamPeerTCP::STATUS_ERROR: - while (ip_candidates.size() > 0) { + while (_ip_candidates.size() > 0) { _tcp->disconnect_from_host(); - if (_tcp->connect_to_host(ip_candidates.pop_front(), _port) == OK) { + if (_tcp->connect_to_host(_ip_candidates.pop_front(), _port) == OK) { return; } } @@ -307,7 +336,7 @@ MultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const { return CONNECTION_CONNECTED; } - if (_tcp->is_connected_to_host()) { + if (_tcp->is_connected_to_host() || _resolver_id != IP::RESOLVER_INVALID_ID) { return CONNECTION_CONNECTING; } @@ -330,7 +359,12 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) { memset(_resp_buf, 0, sizeof(_resp_buf)); _resp_pos = 0; - ip_candidates.clear(); + if (_resolver_id != IP::RESOLVER_INVALID_ID) { + IP::get_singleton()->erase_resolve_item(_resolver_id); + _resolver_id = IP::RESOLVER_INVALID_ID; + } + + _ip_candidates.clear(); } IPAddress WSLClient::get_connected_host() const { diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 4839d7ab9b..d846e6be00 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -63,10 +63,11 @@ private: String _key; String _host; - int _port; - Array ip_candidates; + uint16_t _port; + Array _ip_candidates; Vector<String> _protocols; bool _use_ssl = false; + IP::ResolverID _resolver_id = IP::RESOLVER_INVALID_ID; void _do_handshake(); bool _verify_headers(String &r_protocol); |