Expose the resource name the client used to the websocket server

This information is exposed to the websocket server through the
client_connected-signal.

example.com/chat?id=10 gives the resource name "/chat?id=10"
This commit is contained in:
Meriipu 2020-06-17 08:14:58 +02:00
parent de83ee57e5
commit 1475f617a3
6 changed files with 26 additions and 21 deletions

View file

@ -116,8 +116,11 @@
</argument>
<argument index="1" name="protocol" type="String">
</argument>
<argument index="2" name="resource_name" type="String">
</argument>
<description>
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.
</description>
</signal>
<signal name="client_disconnected">

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);

View file

@ -34,7 +34,7 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) {
bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols, String &r_resource_name) {
Vector<String> 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<String> 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<String, String> headers;
for (int i = 1; i < len; i++) {
Vector<String> header = psa[i].split(":", false, 1);
@ -95,7 +96,7 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) {
return true;
}
Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uint64_t p_timeout) {
Error WSLServer::PendingPeer::do_handshake(const Vector<String> 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<String> 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<Ref<PendingPeer>> remove_peers;
for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) {
String resource_name;
Ref<PendingPeer> 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<Ref<PendingPeer>>::Element *E = remove_peers.front(); E; E = E->next()) {
_pending.erase(E->get());

View file

@ -46,7 +46,7 @@ class WSLServer : public WebSocketServer {
private:
class PendingPeer : public RefCounted {
private:
bool _parse_request(const Vector<String> p_protocols);
bool _parse_request(const Vector<String> p_protocols, String &r_resource_name);
public:
Ref<StreamPeerTCP> tcp;
@ -62,7 +62,7 @@ private:
CharString response;
int response_sent = 0;
Error do_handshake(const Vector<String> p_protocols, uint64_t p_timeout);
Error do_handshake(const Vector<String> p_protocols, uint64_t p_timeout, String &r_resource_name);
};
int _in_buf_size = DEF_BUF_SHIFT;