summaryrefslogtreecommitdiff
path: root/modules/websocket
diff options
context:
space:
mode:
Diffstat (limited to 'modules/websocket')
-rw-r--r--modules/websocket/SCsub35
-rw-r--r--modules/websocket/lws_helper.cpp157
-rw-r--r--modules/websocket/lws_helper.h126
-rw-r--r--modules/websocket/lws_peer.cpp16
4 files changed, 185 insertions, 149 deletions
diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub
index c0985b3245..b67a836fe8 100644
--- a/modules/websocket/SCsub
+++ b/modules/websocket/SCsub
@@ -7,7 +7,7 @@ Import('env_modules')
env_lws = env_modules.Clone()
-if env['builtin_libwebsockets']:
+if env['builtin_libwebsockets'] and not env["platform"] == "javascript": # already builtin for javascript
thirdparty_dir = "#thirdparty/libwebsockets/"
helper_dir = "win32helpers/"
thirdparty_sources = [
@@ -61,34 +61,33 @@ if env['builtin_libwebsockets']:
"tls/mbedtls/mbedtls-server.c"
]
- if env_lws["platform"] == "android": # Builtin getifaddrs
+ if env["platform"] == "android": # Builtin getifaddrs
thirdparty_sources += ["misc/getifaddrs.c"]
- if env_lws["platform"] == "windows" or env_lws["platform"] == "uwp": # Winsock
+ if env["platform"] == "windows" or env["platform"] == "uwp": # Winsock
thirdparty_sources += ["plat/lws-plat-win.c", helper_dir + "getopt.c", helper_dir + "getopt_long.c", helper_dir + "gettimeofday.c"]
else: # Unix socket
thirdparty_sources += ["plat/lws-plat-unix.c"]
-
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
- if env_lws["platform"] == "javascript": # No need to add third party libraries at all
- pass
- else:
- env_lws.add_source_files(env.modules_sources, thirdparty_sources)
- env_lws.Append(CPPPATH=[thirdparty_dir])
+ env_lws.Append(CPPPATH=[thirdparty_dir])
+
+ if env['builtin_mbedtls']:
+ mbedtls_includes = "#thirdparty/mbedtls/include"
+ env_lws.Prepend(CPPPATH=[mbedtls_includes])
- wrapper_includes = ["#thirdparty/libwebsockets/tls/mbedtls/wrapper/include/" + inc for inc in ["internal", "openssl", "platform", ""]]
- env_lws.Prepend(CPPPATH=wrapper_includes)
+ wrapper_includes = ["#thirdparty/libwebsockets/tls/mbedtls/wrapper/include/" + inc for inc in ["internal", "openssl", "platform", ""]]
+ env_lws.Prepend(CPPPATH=wrapper_includes)
- if env['builtin_mbedtls']:
- mbedtls_includes = "#thirdparty/mbedtls/include"
- env_lws.Prepend(CPPPATH=[mbedtls_includes])
+ if env["platform"] == "windows" or env["platform"] == "uwp":
+ env_lws.Append(CPPPATH=[thirdparty_dir + helper_dir])
- if env_lws["platform"] == "windows" or env_lws["platform"] == "uwp":
- env_lws.Append(CPPPATH=[thirdparty_dir + helper_dir])
+ if env["platform"] == "uwp":
+ env_lws.Append(CCFLAGS=["/DLWS_MINGW_SUPPORT"])
- if env_lws["platform"] == "uwp":
- env_lws.Append(CCFLAGS=["/DLWS_MINGW_SUPPORT"])
+ env_thirdparty = env_lws.Clone()
+ env_thirdparty.disable_warnings()
+ env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
env_lws.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/websocket/lws_helper.cpp b/modules/websocket/lws_helper.cpp
new file mode 100644
index 0000000000..b5216615e9
--- /dev/null
+++ b/modules/websocket/lws_helper.cpp
@@ -0,0 +1,157 @@
+/*************************************************************************/
+/* lws_helper.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#if !defined(JAVASCRIPT_ENABLED)
+
+#include "lws_helper.h"
+
+_LWSRef *_lws_create_ref(void *obj) {
+
+ _LWSRef *out = (_LWSRef *)memalloc(sizeof(_LWSRef));
+ out->is_destroying = false;
+ out->free_context = false;
+ out->is_polling = false;
+ out->obj = obj;
+ out->is_valid = true;
+ out->lws_structs = NULL;
+ out->lws_names = NULL;
+ return out;
+}
+
+void _lws_free_ref(_LWSRef *ref) {
+ // Free strings and structs
+ memfree(ref->lws_structs);
+ memfree(ref->lws_names);
+ // Free ref
+ memfree(ref);
+}
+
+bool _lws_destroy(struct lws_context *context, _LWSRef *ref) {
+ if (context == NULL || ref->is_destroying)
+ return false;
+
+ if (ref->is_polling) {
+ ref->free_context = true;
+ return false;
+ }
+
+ ref->is_destroying = true;
+ lws_context_destroy(context);
+ _lws_free_ref(ref);
+ return true;
+}
+
+bool _lws_poll(struct lws_context *context, _LWSRef *ref) {
+
+ ERR_FAIL_COND_V(context == NULL, false);
+ ERR_FAIL_COND_V(ref == NULL, false);
+
+ ref->is_polling = true;
+ lws_service(context, 0);
+ ref->is_polling = false;
+
+ if (!ref->free_context)
+ return false; // Nothing to do
+
+ bool is_valid = ref->is_valid; // Might have been destroyed by poll
+
+ _lws_destroy(context, ref); // Will destroy context and ref
+
+ return is_valid; // If the object should NULL its context and ref
+}
+
+/*
+ * Prepare the protocol_structs to be fed to context.
+ * Also prepare the protocol string used by the client.
+ */
+void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) {
+ // The input strings might go away after this call, we need to copy them.
+ // We will clear them when destroying the context.
+ int i;
+ int len = p_names.size();
+ size_t data_size = sizeof(struct LWSPeer::PeerData);
+ PoolVector<String>::Read pnr = p_names.read();
+
+ // This is a reference connecting the object with lws keep track of status, mallocs, etc.
+ // Must survive as long the context.
+ // Must be freed manually when context creation fails.
+ _LWSRef *ref = _lws_create_ref(p_obj);
+
+ // LWS protocol structs.
+ ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2));
+ memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2));
+
+ CharString strings = p_names.join(",").ascii();
+ int str_len = strings.length();
+
+ // Joined string of protocols, double the size: comma separated first, NULL separated last
+ ref->lws_names = (char *)memalloc((str_len + 1) * 2); // Plus the terminator
+
+ char *names_ptr = ref->lws_names;
+ struct lws_protocols *structs_ptr = ref->lws_structs;
+
+ // Comma separated protocols string to be used in client Sec-WebSocket-Protocol header
+ if (str_len > 0)
+ copymem(names_ptr, strings.get_data(), str_len);
+ names_ptr[str_len] = '\0'; // NULL terminator
+
+ // NULL terminated protocol strings to be used in protocol structs
+ if (str_len > 0)
+ copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
+ names_ptr[(str_len * 2) + 1] = '\0'; // NULL terminator
+ int pos = str_len + 1;
+
+ // The first protocol is the default for any http request (before upgrade).
+ // It is also used as the websocket protocol when no subprotocol is specified.
+ structs_ptr[0].name = "default";
+ structs_ptr[0].callback = p_callback;
+ structs_ptr[0].per_session_data_size = data_size;
+ structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE;
+ structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE;
+ // Add user defined protocols
+ for (i = 0; i < len; i++) {
+ structs_ptr[i + 1].name = (const char *)&names_ptr[pos];
+ structs_ptr[i + 1].callback = p_callback;
+ structs_ptr[i + 1].per_session_data_size = data_size;
+ structs_ptr[i + 1].rx_buffer_size = LWS_BUF_SIZE;
+ structs_ptr[i + 1].tx_packet_size = LWS_PACKET_SIZE;
+ pos += pnr[i].ascii().length() + 1;
+ names_ptr[pos - 1] = '\0';
+ }
+ // Add protocols terminator
+ structs_ptr[len + 1].name = NULL;
+ structs_ptr[len + 1].callback = NULL;
+ structs_ptr[len + 1].per_session_data_size = 0;
+ structs_ptr[len + 1].rx_buffer_size = 0;
+
+ *r_lws_ref = ref;
+}
+
+#endif
diff --git a/modules/websocket/lws_helper.h b/modules/websocket/lws_helper.h
index 70256ccf16..fd8f85371b 100644
--- a/modules/websocket/lws_helper.h
+++ b/modules/websocket/lws_helper.h
@@ -49,127 +49,11 @@ struct _LWSRef {
char *lws_names;
};
-static _LWSRef *_lws_create_ref(void *obj) {
-
- _LWSRef *out = (_LWSRef *)memalloc(sizeof(_LWSRef));
- out->is_destroying = false;
- out->free_context = false;
- out->is_polling = false;
- out->obj = obj;
- out->is_valid = true;
- out->lws_structs = NULL;
- out->lws_names = NULL;
- return out;
-}
-
-static void _lws_free_ref(_LWSRef *ref) {
- // Free strings and structs
- memfree(ref->lws_structs);
- memfree(ref->lws_names);
- // Free ref
- memfree(ref);
-}
-
-static bool _lws_destroy(struct lws_context *context, _LWSRef *ref) {
- if (context == NULL || ref->is_destroying)
- return false;
-
- if (ref->is_polling) {
- ref->free_context = true;
- return false;
- }
-
- ref->is_destroying = true;
- lws_context_destroy(context);
- _lws_free_ref(ref);
- return true;
-}
-
-static bool _lws_poll(struct lws_context *context, _LWSRef *ref) {
-
- ERR_FAIL_COND_V(context == NULL, false);
- ERR_FAIL_COND_V(ref == NULL, false);
-
- ref->is_polling = true;
- lws_service(context, 0);
- ref->is_polling = false;
-
- if (!ref->free_context)
- return false; // Nothing to do
-
- bool is_valid = ref->is_valid; // Might have been destroyed by poll
-
- _lws_destroy(context, ref); // Will destroy context and ref
-
- return is_valid; // If the object should NULL its context and ref
-}
-
-/*
- * Prepare the protocol_structs to be fed to context.
- * Also prepare the protocol string used by the client.
- */
-static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) {
- // The input strings might go away after this call, we need to copy them.
- // We will clear them when destroying the context.
- int i;
- int len = p_names.size();
- size_t data_size = sizeof(struct LWSPeer::PeerData);
- PoolVector<String>::Read pnr = p_names.read();
-
- // This is a reference connecting the object with lws keep track of status, mallocs, etc.
- // Must survive as long the context.
- // Must be freed manually when context creation fails.
- _LWSRef *ref = _lws_create_ref(p_obj);
-
- // LWS protocol structs.
- ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2));
- memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2));
-
- CharString strings = p_names.join(",").ascii();
- int str_len = strings.length();
-
- // Joined string of protocols, double the size: comma separated first, NULL separated last
- ref->lws_names = (char *)memalloc((str_len + 1) * 2); // Plus the terminator
-
- char *names_ptr = ref->lws_names;
- struct lws_protocols *structs_ptr = ref->lws_structs;
-
- // Comma separated protocols string to be used in client Sec-WebSocket-Protocol header
- if (str_len > 0)
- copymem(names_ptr, strings.get_data(), str_len);
- names_ptr[str_len] = '\0'; // NULL terminator
-
- // NULL terminated protocol strings to be used in protocol structs
- if (str_len > 0)
- copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
- names_ptr[(str_len * 2) + 1] = '\0'; // NULL terminator
- int pos = str_len + 1;
-
- // The first protocol is the default for any http request (before upgrade).
- // It is also used as the websocket protocol when no subprotocol is specified.
- structs_ptr[0].name = "default";
- structs_ptr[0].callback = p_callback;
- structs_ptr[0].per_session_data_size = data_size;
- structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE;
- structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE;
- // Add user defined protocols
- for (i = 0; i < len; i++) {
- structs_ptr[i + 1].name = (const char *)&names_ptr[pos];
- structs_ptr[i + 1].callback = p_callback;
- structs_ptr[i + 1].per_session_data_size = data_size;
- structs_ptr[i + 1].rx_buffer_size = LWS_BUF_SIZE;
- structs_ptr[i + 1].tx_packet_size = LWS_PACKET_SIZE;
- pos += pnr[i].ascii().length() + 1;
- names_ptr[pos - 1] = '\0';
- }
- // Add protocols terminator
- structs_ptr[len + 1].name = NULL;
- structs_ptr[len + 1].callback = NULL;
- structs_ptr[len + 1].per_session_data_size = 0;
- structs_ptr[len + 1].rx_buffer_size = 0;
-
- *r_lws_ref = ref;
-}
+_LWSRef *_lws_create_ref(void *obj);
+void _lws_free_ref(_LWSRef *ref);
+bool _lws_destroy(struct lws_context *context, _LWSRef *ref);
+bool _lws_poll(struct lws_context *context, _LWSRef *ref);
+void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref);
/* clang-format off */
#define LWS_HELPER(CNAME) \
diff --git a/modules/websocket/lws_peer.cpp b/modules/websocket/lws_peer.cpp
index 245b28b608..b5c130b308 100644
--- a/modules/websocket/lws_peer.cpp
+++ b/modules/websocket/lws_peer.cpp
@@ -30,6 +30,7 @@
#ifndef JAVASCRIPT_ENABLED
#include "lws_peer.h"
+
#include "core/io/ip.h"
// Needed for socket_helpers on Android at least. UNIXes has it, just include if not windows
@@ -38,7 +39,7 @@
#include <sys/socket.h>
#endif
-#include "drivers/unix/socket_helpers.h"
+#include "drivers/unix/net_socket_posix.h"
void LWSPeer::set_wsi(struct lws *p_wsi) {
ERR_FAIL_COND(wsi != NULL);
@@ -60,7 +61,6 @@ Error LWSPeer::read_wsi(void *in, size_t len) {
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- PeerData *peer_data = (PeerData *)(lws_wsi_user(wsi));
uint32_t size = in_size;
uint8_t is_string = lws_frame_is_binary(wsi) ? 0 : 1;
@@ -88,7 +88,6 @@ Error LWSPeer::write_wsi() {
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- PeerData *peer_data = (PeerData *)(lws_wsi_user(wsi));
PoolVector<uint8_t> tmp;
int left = rbw.data_left();
uint32_t to_write = 0;
@@ -119,7 +118,6 @@ Error LWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- PeerData *peer_data = (PeerData *)lws_wsi_user(wsi);
rbw.write((uint8_t *)&p_buffer_size, 4);
rbw.write(p_buffer, MIN(p_buffer_size, rbw.space_left()));
out_count++;
@@ -132,8 +130,6 @@ Error LWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- PeerData *peer_data = (PeerData *)lws_wsi_user(wsi);
-
if (in_count == 0)
return ERR_UNAVAILABLE;
@@ -236,7 +232,7 @@ IP_Address LWSPeer::get_connected_host() const {
ERR_FAIL_COND_V(!is_connected_to_host(), IP_Address());
IP_Address ip;
- int port = 0;
+ uint16_t port = 0;
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
@@ -247,7 +243,7 @@ IP_Address LWSPeer::get_connected_host() const {
int ret = getpeername(fd, (struct sockaddr *)&addr, &len);
ERR_FAIL_COND_V(ret != 0, IP_Address());
- _set_ip_addr_port(ip, port, &addr);
+ NetSocketPosix::_set_ip_port(&addr, ip, port);
return ip;
};
@@ -257,7 +253,7 @@ uint16_t LWSPeer::get_connected_port() const {
ERR_FAIL_COND_V(!is_connected_to_host(), 0);
IP_Address ip;
- int port = 0;
+ uint16_t port = 0;
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
@@ -268,7 +264,7 @@ uint16_t LWSPeer::get_connected_port() const {
int ret = getpeername(fd, (struct sockaddr *)&addr, &len);
ERR_FAIL_COND_V(ret != 0, 0);
- _set_ip_addr_port(ip, port, &addr);
+ NetSocketPosix::_set_ip_port(&addr, ip, port);
return port;
};