diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index 26e09fd8b3..5491f7de15 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -116,8 +116,11 @@ + + - Emitted when a new client connects. "protocol" will be the sub-protocol agreed with the client. + Emitted when a new client connects. "protocol" will be the sub-protocol agreed with the client, and "resource_name" will be the resource name of the URI the peer used. + "resource_name" is a path (at the very least a single forward slash) and potentially a query string. diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 1ad3bdc825..05f9e12ae1 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -56,7 +56,7 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0; godot_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin); return OK; -}; +} Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { if (_in_buffer.packets_left() == 0) @@ -70,19 +70,19 @@ Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { r_buffer_size = read; return OK; -}; +} int EMWSPeer::get_available_packet_count() const { return _in_buffer.packets_left(); -}; +} bool EMWSPeer::was_string_packet() const { return _is_string; -}; +} bool EMWSPeer::is_connected_to_host() const { return peer_sock != -1; -}; +} void EMWSPeer::close(int p_code, String p_reason) { if (peer_sock != -1) { @@ -91,7 +91,7 @@ void EMWSPeer::close(int p_code, String p_reason) { _is_string = 0; _in_buffer.clear(); peer_sock = -1; -}; +} IPAddress EMWSPeer::get_connected_host() const { ERR_FAIL_V_MSG(IPAddress(), "Not supported in HTML5 export."); @@ -99,7 +99,7 @@ IPAddress EMWSPeer::get_connected_host() const { uint16_t EMWSPeer::get_connected_port() const { ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); -}; +} void EMWSPeer::set_no_delay(bool p_enabled) { ERR_FAIL_MSG("'set_no_delay' is not supported in HTML5 export."); @@ -107,10 +107,10 @@ void EMWSPeer::set_no_delay(bool p_enabled) { EMWSPeer::EMWSPeer() { close(); -}; +} EMWSPeer::~EMWSPeer() { close(); -}; +} #endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index b996852f28..79ca9e4667 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -71,7 +71,7 @@ void WebSocketServer::_bind_methods() { 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"))); - ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"))); + ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"), PropertyInfo(Variant::STRING, "resource_name"))); ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id"))); } @@ -141,13 +141,13 @@ void WebSocketServer::_on_peer_packet(int32_t p_peer_id) { } } -void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol) { +void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol, String p_resource_name) { if (_is_multiplayer) { // Send add to clients _send_add(p_peer_id); emit_signal("peer_connected", p_peer_id); } else { - emit_signal("client_connected", p_peer_id, p_protocol); + emit_signal("client_connected", p_peer_id, p_protocol, p_resource_name); } } diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 26864f3085..c4d651471f 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -63,7 +63,7 @@ public: virtual void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "") = 0; void _on_peer_packet(int32_t p_peer_id); - void _on_connect(int32_t p_peer_id, String p_protocol); + void _on_connect(int32_t p_peer_id, String p_protocol, String p_resource_name); 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); diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index c889562732..5f794415af 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -34,7 +34,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" -bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols) { +bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols, String &r_resource_name) { Vector psa = String((char *)req_buf).split("\r\n"); int len = psa.size(); ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4."); @@ -45,6 +45,7 @@ bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols) { // Wrong protocol ERR_FAIL_COND_V_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", false, "Invalid method or HTTP version."); + r_resource_name = req[1]; Map headers; for (int i = 1; i < len; i++) { Vector header = psa[i].split(":", false, 1); @@ -95,7 +96,7 @@ bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols) { return true; } -Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols, uint64_t p_timeout) { +Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols, uint64_t p_timeout, String &r_resource_name) { 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; @@ -130,7 +131,7 @@ Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols, uin int l = req_pos; if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { r[l - 3] = '\0'; - if (!_parse_request(p_protocols)) { + if (!_parse_request(p_protocols, r_resource_name)) { return FAILED; } String s = "HTTP/1.1 101 Switching Protocols\r\n"; @@ -196,8 +197,9 @@ void WSLServer::poll() { List> remove_peers; for (List>::Element *E = _pending.front(); E; E = E->next()) { + String resource_name; Ref ppeer = E->get(); - Error err = ppeer->do_handshake(_protocols, handshake_timeout); + Error err = ppeer->do_handshake(_protocols, handshake_timeout, resource_name); if (err == ERR_BUSY) { continue; } else if (err != OK) { @@ -220,7 +222,7 @@ void WSLServer::poll() { _peer_map[id] = ws_peer; remove_peers.push_back(ppeer); - _on_connect(id, ppeer->protocol); + _on_connect(id, ppeer->protocol, resource_name); } for (List>::Element *E = remove_peers.front(); E; E = E->next()) { _pending.erase(E->get()); diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index a428c89f4f..93c8bd9604 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -46,7 +46,7 @@ class WSLServer : public WebSocketServer { private: class PendingPeer : public RefCounted { private: - bool _parse_request(const Vector p_protocols); + bool _parse_request(const Vector p_protocols, String &r_resource_name); public: Ref tcp; @@ -62,7 +62,7 @@ private: CharString response; int response_sent = 0; - Error do_handshake(const Vector p_protocols, uint64_t p_timeout); + Error do_handshake(const Vector p_protocols, uint64_t p_timeout, String &r_resource_name); }; int _in_buf_size = DEF_BUF_SHIFT;