├── .gitignore ├── LICENSE.txt ├── README.md ├── modules └── websocket │ ├── SCsub │ ├── config.py │ ├── emws_client.cpp │ ├── emws_client.h │ ├── emws_peer.cpp │ ├── emws_peer.h │ ├── emws_server.cpp │ ├── emws_server.h │ ├── lws_client.cpp │ ├── lws_client.h │ ├── lws_helper.h │ ├── lws_peer.cpp │ ├── lws_peer.h │ ├── lws_server.cpp │ ├── lws_server.h │ ├── register_types.cpp │ ├── register_types.h │ ├── websocket_client.cpp │ ├── websocket_client.h │ ├── websocket_macros.h │ ├── websocket_multiplayer.cpp │ ├── websocket_multiplayer.h │ ├── websocket_peer.cpp │ ├── websocket_peer.h │ ├── websocket_server.cpp │ └── websocket_server.h ├── multiplayer_demo ├── .gitignore ├── default_env.tres ├── icon.png ├── img │ └── crown.png ├── project.godot ├── scene │ ├── game.tscn │ └── main.tscn └── script │ ├── game.gd │ └── main.gd ├── screenshot.png ├── thirdparty └── lws │ ├── LICENSE.txt │ ├── alloc.c │ ├── client │ ├── client-handshake.c │ ├── client-parser.c │ ├── client.c │ └── ssl-client.c │ ├── context.c │ ├── event-libs │ ├── libev.c │ ├── libevent.c │ └── libuv.c │ ├── ext │ ├── extension-permessage-deflate.c │ ├── extension-permessage-deflate.h │ └── extension.c │ ├── handshake.c │ ├── header.c │ ├── http2 │ ├── hpack.c │ ├── http2.c │ ├── huftable.h │ ├── minihuf.c │ └── ssl-http2.c │ ├── lextable-strings.h │ ├── lextable.h │ ├── libwebsockets.c │ ├── libwebsockets.h │ ├── lws_config.h │ ├── lws_config_private.h │ ├── mbedtls_wrapper │ ├── include │ │ ├── internal │ │ │ ├── ssl3.h │ │ │ ├── ssl_cert.h │ │ │ ├── ssl_code.h │ │ │ ├── ssl_dbg.h │ │ │ ├── ssl_lib.h │ │ │ ├── ssl_methods.h │ │ │ ├── ssl_pkey.h │ │ │ ├── ssl_stack.h │ │ │ ├── ssl_types.h │ │ │ ├── ssl_x509.h │ │ │ ├── tls1.h │ │ │ └── x509_vfy.h │ │ ├── openssl │ │ │ └── ssl.h │ │ └── platform │ │ │ ├── ssl_pm.h │ │ │ └── ssl_port.h │ ├── library │ │ ├── ssl_cert.c │ │ ├── ssl_lib.c │ │ ├── ssl_methods.c │ │ ├── ssl_pkey.c │ │ ├── ssl_stack.c │ │ └── ssl_x509.c │ └── platform │ │ ├── ssl_pm.c │ │ └── ssl_port.c │ ├── minilex.c │ ├── misc │ ├── base64-decode.c │ ├── getifaddrs.c │ ├── getifaddrs.h │ ├── lejp.c │ ├── lejp.h │ ├── lws-genhash.c │ ├── lws-ring.c │ ├── romfs.c │ ├── romfs.h │ ├── sha-1.c │ └── smtp.c │ ├── output.c │ ├── plat │ ├── lws-plat-esp32.c │ ├── lws-plat-esp8266.c │ ├── lws-plat-optee.c │ ├── lws-plat-unix.c │ └── lws-plat-win.c │ ├── pollfd.c │ ├── private-libwebsockets.h │ ├── server │ ├── access-log.c │ ├── cgi.c │ ├── daemonize.c │ ├── fops-zip.c │ ├── lejp-conf.c │ ├── lws-spa.c │ ├── parsers.c │ ├── peer-limits.c │ ├── ranges.c │ ├── rewrite.c │ ├── server-handshake.c │ ├── server.c │ └── ssl-server.c │ ├── service.c │ ├── ssl.c │ └── win32helpers │ ├── getopt.c │ ├── getopt.h │ ├── getopt_long.c │ ├── gettimeofday.c │ └── gettimeofday.h └── websocket_chat_demo ├── .gitignore ├── client ├── client.gd ├── client.tscn └── client_ui.gd ├── combo └── combo.tscn ├── default_env.tres ├── icon.png ├── project.godot ├── server ├── server.gd ├── server.tscn └── server_ui.gd └── utils.gd /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot auto generated files 2 | *.gen.* 3 | 4 | # Documentation generated by doxygen or from classes.xml 5 | doc/_build/ 6 | 7 | # Javascript specific 8 | *.bc 9 | 10 | # Android specific 11 | platform/android/java/build.gradle 12 | platform/android/java/.gradle 13 | platform/android/java/.gradletasknamecache 14 | platform/android/java/local.properties 15 | platform/android/java/project.properties 16 | platform/android/java/build.gradle 17 | platform/android/java/AndroidManifest.xml 18 | platform/android/java/libs/* 19 | platform/android/java/assets 20 | 21 | # General c++ generated files 22 | *.lib 23 | *.o 24 | *.ox 25 | *.a 26 | *.ax 27 | *.d 28 | *.so 29 | *.os 30 | *.Plo 31 | *.lo 32 | 33 | # Libs generated files 34 | .deps/* 35 | .dirstamp 36 | 37 | # Gprof output 38 | gmon.out 39 | 40 | # Vim temp files 41 | *.swo 42 | *.swp 43 | 44 | # QT project files 45 | *.config 46 | *.creator 47 | *.files 48 | *.includes 49 | 50 | # Eclipse CDT files 51 | .cproject 52 | .settings/ 53 | 54 | # Misc 55 | .DS_Store 56 | logs/ 57 | 58 | # for projects that use SCons for building: http://http://www.scons.org/ 59 | .sconf_temp 60 | .sconsign.dblite 61 | *.pyc 62 | 63 | 64 | # https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 65 | ## Ignore Visual Studio temporary files, build results, and 66 | ## files generated by popular Visual Studio add-ons. 67 | 68 | # User-specific files 69 | *.suo 70 | *.user 71 | *.sln.docstates 72 | *.sln 73 | *.vcxproj* 74 | 75 | # Build results 76 | [Dd]ebug/ 77 | [Dd]ebugPublic/ 78 | [Rr]elease/ 79 | x64/ 80 | build/ 81 | bld/ 82 | [Bb]in/ 83 | [Oo]bj/ 84 | *.debug 85 | *.dSYM 86 | 87 | # MSTest test Results 88 | [Tt]est[Rr]esult*/ 89 | [Bb]uild[Ll]og.* 90 | 91 | #NUNIT 92 | *.VisualState.xml 93 | TestResult.xml 94 | 95 | *.o 96 | *.a 97 | *_i.c 98 | *_p.c 99 | *_i.h 100 | *.ilk 101 | *.meta 102 | *.obj 103 | *.pch 104 | *.pdb 105 | *.pgc 106 | *.pgd 107 | *.rsp 108 | *.sbr 109 | *.tlb 110 | *.tli 111 | *.tlh 112 | *.tmp 113 | *.tmp_proj 114 | *.log 115 | *.vspscc 116 | *.vssscc 117 | .builds 118 | *.pidb 119 | *.svclog 120 | *.scc 121 | 122 | # Chutzpah Test files 123 | _Chutzpah* 124 | 125 | # Visual C++ cache files 126 | ipch/ 127 | *.aps 128 | *.ncb 129 | *.opensdf 130 | *.sdf 131 | *.cachefile 132 | *.VC.db 133 | *.VC.opendb 134 | *.VC.VC.opendb 135 | enc_temp_folder/ 136 | 137 | # Visual Studio profiler 138 | *.psess 139 | *.vsp 140 | *.vspx 141 | 142 | # CodeLite project files 143 | *.project 144 | *.workspace 145 | .codelite/ 146 | 147 | # TFS 2012 Local Workspace 148 | $tf/ 149 | 150 | # Guidance Automation Toolkit 151 | *.gpState 152 | 153 | # ReSharper is a .NET coding add-in 154 | _ReSharper*/ 155 | *.[Rr]e[Ss]harper 156 | *.DotSettings.user 157 | 158 | # JustCode is a .NET coding addin-in 159 | .JustCode 160 | 161 | # TeamCity is a build add-in 162 | _TeamCity* 163 | 164 | # DotCover is a Code Coverage Tool 165 | *.dotCover 166 | 167 | # NCrunch 168 | *.ncrunch* 169 | _NCrunch_* 170 | .*crunch*.local.xml 171 | 172 | # MightyMoose 173 | *.mm.* 174 | AutoTest.Net/ 175 | 176 | # Web workbench (sass) 177 | .sass-cache/ 178 | 179 | # Installshield output folder 180 | [Ee]xpress/ 181 | 182 | # DocProject is a documentation generator add-in 183 | DocProject/buildhelp/ 184 | DocProject/Help/*.HxT 185 | DocProject/Help/*.HxC 186 | DocProject/Help/*.hhc 187 | DocProject/Help/*.hhk 188 | DocProject/Help/*.hhp 189 | DocProject/Help/Html2 190 | DocProject/Help/html 191 | 192 | # Click-Once directory 193 | publish/ 194 | 195 | # Publish Web Output 196 | *.[Pp]ublish.xml 197 | *.azurePubxml 198 | 199 | # NuGet Packages Directory 200 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 201 | #packages/* 202 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line 203 | #!packages/repositories.config 204 | 205 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 206 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 207 | !packages/build/ 208 | 209 | # Windows Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Windows Store app package directory 214 | AppPackages/ 215 | 216 | # Others 217 | sql/ 218 | *.Cache 219 | ClientBin/ 220 | [Ss]tyle[Cc]op.* 221 | ~$* 222 | *~ 223 | *.dbmdl 224 | *.dbproj.schemaview 225 | *.pfx 226 | *.publishsettings 227 | node_modules/ 228 | 229 | # KDE 230 | .directory 231 | 232 | #Kdevelop project files 233 | *.kdev4 234 | 235 | # xCode 236 | xcuserdata 237 | 238 | # RIA/Silverlight projects 239 | Generated_Code/ 240 | 241 | # Backup & report files from converting an old project file to a newer 242 | # Visual Studio version. Backup files are not needed, because we have git ;-) 243 | _UpgradeReport_Files/ 244 | Backup*/ 245 | UpgradeLog*.XML 246 | UpgradeLog*.htm 247 | 248 | # SQL Server files 249 | App_Data/*.mdf 250 | App_Data/*.ldf 251 | 252 | # Business Intelligence projects 253 | *.rdl.data 254 | *.bim.layout 255 | *.bim_*.settings 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # ========================= 261 | # Windows detritus 262 | # ========================= 263 | 264 | # Windows image file caches 265 | Thumbs.db 266 | ehthumbs.db 267 | 268 | # Folder config file 269 | Desktop.ini 270 | 271 | # Recycle Bin used on file shares 272 | $RECYCLE.BIN/ 273 | logo.h 274 | *.autosave 275 | 276 | # https://github.com/github/gitignore/blob/master/Global/Tags.gitignore 277 | # Ignore tags created by etags, ctags, gtags (GNU global) and cscope 278 | TAGS 279 | !TAGS/ 280 | tags 281 | !tags/ 282 | gtags.files 283 | GTAGS 284 | GRTAGS 285 | GPATH 286 | cscope.files 287 | cscope.out 288 | cscope.in.out 289 | cscope.po.out 290 | godot.creator.* 291 | 292 | projects/ 293 | platform/windows/godot_res.res 294 | 295 | # Visual Studio 2017 and Visual Studio Code workspace folder 296 | /.vs 297 | /.vscode 298 | 299 | # Scons progress indicator 300 | .scons_node_count 301 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2017 Ludi Dorici di Alessandrelli Fabio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NOTE: This module was merged in Godot Engine master branch via pull request https://github.com/godotengine/godot/pull/14888 and will be available on official Godot Engine releases starting from version 3.1. This repository is no longer mantained and only left for historical purpose. All further development will be done inside the Godot Engine repository ( https://github.com/godotengine/godot ). Thank you for your support. 2 | # Demos are available for newer versions of Godot in the official [demo repository](https://github.com/godotengine/godot-demo-projects/tree/master/networking). 3 | 4 | # If you like this, and want to support us, [check out our videogame](http://store.steampowered.com/app/679100/Aequitas_Orbis) and follow us on [twitter](https://twitter.com/aequitasorbis) 5 | 6 | 7 | 8 | ----------- 9 | 10 | # WebSocket module for Godot Engine 3.0 11 | 12 | This module allows for easy creation of **WebSocket Client and Server** using [libwebsockets](https://libwebsockets.org/) as a thirdparty library. Libwebsockets is released as LGPLv2.1 + static linkning exception. You can find that license in `thirdparty/LICENSE.txt` 13 | 14 | The client API is also available in project exported to HTML5 using native Javascript code. 15 | 16 | A small demo project is available in `websocket_chat_demo` to show how to use the module. 17 | 18 | This module is still a work in progress. 19 | 20 | Tested on: 21 | 22 | * Linux 23 | * Windows (mingw build) 24 | * Javascript/HTML5 25 | 26 | Compiles on (untested but should work): 27 | 28 | * Android 29 | * iOS 30 | * OSX 31 | 32 | The module supports writing data in both TEXT and BINARY mode. 33 | 34 | ### NOTE 35 | 36 | You can run the demo server from a godot instance and connect to it with the demo client exported to Javascipt/HTML5, checkout the screenshot: 37 | 38 | ![LWS Module Screenshot](https://github.com/LudiDorici/godot-lws/raw/master/screenshot.png) 39 | 40 | ### Build instruction 41 | 42 | Simply copy (or link) `modules/lws` inside Godot `modules` directory. Also copy `thirdparty/lws` inside Godot `thirdparty` directory. 43 | 44 | Compile Godot Engine as you would normally do. 45 | 46 | #### Support us 47 | 48 | If you like this, and want to support us, [check out our videogame](http://store.steampowered.com/app/679100/Aequitas_Orbis) and follow us on [twitter](https://twitter.com/aequitasorbis) 49 | -------------------------------------------------------------------------------- /modules/websocket/SCsub: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | Import('env') 4 | Import('env_modules') 5 | 6 | # Thirdparty source files 7 | 8 | env_lws = env_modules.Clone() 9 | 10 | thirdparty_dir = "#thirdparty/lws/" 11 | helper_dir = "win32helpers/" 12 | openssl_dir = "#thirdparty/openssl/" 13 | thirdparty_sources = [ 14 | "client/client.c", 15 | "client/client-handshake.c", 16 | "client/client-parser.c", 17 | "client/ssl-client.c", 18 | 19 | "ext/extension.c", 20 | "ext/extension-permessage-deflate.c", 21 | 22 | "server/fops-zip.c", 23 | "server/lejp-conf.c", 24 | "server/parsers.c", 25 | "server/ranges.c", 26 | "server/server.c", 27 | "server/server-handshake.c", 28 | "server/ssl-server.c", 29 | 30 | "misc/base64-decode.c", 31 | "misc/lejp.c", 32 | "misc/sha-1.c", 33 | 34 | "alloc.c", 35 | "context.c", 36 | "handshake.c", 37 | "header.c", 38 | "libwebsockets.c", 39 | "minilex.c", 40 | "output.c", 41 | "pollfd.c", 42 | "service.c", 43 | "ssl.c", 44 | 45 | ] 46 | 47 | if env_lws["platform"] == "android": # Builtin getifaddrs 48 | thirdparty_sources += ["misc/getifaddrs.c"] 49 | 50 | if env_lws["platform"] == "windows": # Winsock 51 | thirdparty_sources += ["plat/lws-plat-win.c", helper_dir + "getopt.c", helper_dir + "getopt_long.c", helper_dir + "gettimeofday.c"] 52 | else: # Unix socket 53 | thirdparty_sources += ["plat/lws-plat-unix.c"] 54 | 55 | 56 | thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] 57 | 58 | if env_lws["platform"] == "javascript": # No need to add third party libraries at all 59 | pass 60 | else: 61 | env_lws.add_source_files(env.modules_sources, thirdparty_sources) 62 | env_lws.Append(CPPPATH=[thirdparty_dir]) 63 | 64 | if env['builtin_openssl']: 65 | env_lws.Append(CPPPATH=[openssl_dir]) 66 | 67 | if env_lws["platform"] == "windows": 68 | env_lws.Append(CPPPATH=[thirdparty_dir + helper_dir]) 69 | 70 | env_lws.add_source_files(env.modules_sources, "*.cpp") 71 | -------------------------------------------------------------------------------- /modules/websocket/config.py: -------------------------------------------------------------------------------- 1 | 2 | def can_build(platform): 3 | return True 4 | 5 | 6 | def configure(env): 7 | pass 8 | -------------------------------------------------------------------------------- /modules/websocket/emws_client.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* emws_client.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef EMWSCLIENT_H 30 | #define EMWSCLIENT_H 31 | 32 | #ifdef JAVASCRIPT_ENABLED 33 | 34 | #include "core/error_list.h" 35 | #include "emws_peer.h" 36 | #include "websocket_client.h" 37 | 38 | class EMWSClient : public WebSocketClient { 39 | 40 | GDCIIMPL(EMWSClient, WebSocketClient); 41 | 42 | private: 43 | int _js_id; 44 | 45 | public: 46 | bool _is_connecting; 47 | 48 | Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector p_protocol = PoolVector()); 49 | Ref get_peer(int p_peer_id) const; 50 | void disconnect_from_host(); 51 | IP_Address get_connected_host() const; 52 | uint16_t get_connected_port() const; 53 | virtual ConnectionStatus get_connection_status() const; 54 | virtual void poll(); 55 | EMWSClient(); 56 | ~EMWSClient(); 57 | }; 58 | 59 | #endif // JAVASCRIPT_ENABLED 60 | 61 | #endif // EMWSCLIENT_H 62 | -------------------------------------------------------------------------------- /modules/websocket/emws_peer.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* emws_peer.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifdef JAVASCRIPT_ENABLED 30 | 31 | #include "emws_peer.h" 32 | #include "core/io/ip.h" 33 | 34 | void EMWSPeer::set_sock(int p_sock) { 35 | 36 | peer_sock = p_sock; 37 | in_buffer.clear(); 38 | queue_count = 0; 39 | } 40 | 41 | void EMWSPeer::set_write_mode(WriteMode p_mode) { 42 | write_mode = p_mode; 43 | } 44 | 45 | EMWSPeer::WriteMode EMWSPeer::get_write_mode() const { 46 | return write_mode; 47 | } 48 | 49 | void EMWSPeer::read_msg(uint8_t *p_data, uint32_t p_size, bool p_is_string) { 50 | 51 | if (in_buffer.space_left() < p_size + 5) { 52 | ERR_EXPLAIN("Buffer full! Dropping data"); 53 | ERR_FAIL(); 54 | } 55 | 56 | uint8_t is_string = p_is_string ? 1 : 0; 57 | in_buffer.write((uint8_t *)&p_size, 4); 58 | in_buffer.write((uint8_t *)&is_string, 1); 59 | in_buffer.write(p_data, p_size); 60 | queue_count++; 61 | } 62 | 63 | Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { 64 | 65 | int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0; 66 | 67 | /* clang-format off */ 68 | EM_ASM({ 69 | var sock = Module.IDHandler.get($0); 70 | var bytes_array = new Uint8Array($2); 71 | var i = 0; 72 | 73 | for(i=0; i<$2; i++) { 74 | bytes_array[i] = Module.getValue($1+i, 'i8'); 75 | } 76 | 77 | if ($3) { 78 | sock.send(bytes_array.buffer); 79 | } else { 80 | var string = new TextDecoder("utf-8").decode(bytes_array); 81 | sock.send(string); 82 | } 83 | }, peer_sock, p_buffer, p_buffer_size, is_bin); 84 | /* clang-format on */ 85 | 86 | return OK; 87 | }; 88 | 89 | Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { 90 | 91 | if (queue_count == 0) 92 | return ERR_UNAVAILABLE; 93 | 94 | uint32_t to_read = 0; 95 | uint32_t left = 0; 96 | uint8_t is_string = 0; 97 | r_buffer_size = 0; 98 | 99 | in_buffer.read((uint8_t *)&to_read, 4); 100 | --queue_count; 101 | left = in_buffer.data_left(); 102 | 103 | if (left < to_read + 1) { 104 | in_buffer.advance_read(left); 105 | return FAILED; 106 | } 107 | 108 | in_buffer.read(&is_string, 1); 109 | _was_string = is_string == 1; 110 | in_buffer.read(packet_buffer, to_read); 111 | *r_buffer = packet_buffer; 112 | r_buffer_size = to_read; 113 | 114 | return OK; 115 | }; 116 | 117 | int EMWSPeer::get_available_packet_count() const { 118 | 119 | return queue_count; 120 | }; 121 | 122 | bool EMWSPeer::was_string_packet() const { 123 | 124 | return _was_string; 125 | }; 126 | 127 | bool EMWSPeer::is_connected_to_host() const { 128 | 129 | return peer_sock != -1; 130 | }; 131 | 132 | void EMWSPeer::close() { 133 | 134 | if (peer_sock != -1) { 135 | /* clang-format off */ 136 | EM_ASM({ 137 | var sock = Module.IDHandler.get($0); 138 | sock.close(); 139 | Module.IDHandler.remove($0); 140 | }, peer_sock); 141 | /* clang-format on */ 142 | } 143 | peer_sock = -1; 144 | queue_count = 0; 145 | in_buffer.clear(); 146 | }; 147 | 148 | IP_Address EMWSPeer::get_connected_host() const { 149 | 150 | return IP_Address(); 151 | }; 152 | 153 | uint16_t EMWSPeer::get_connected_port() const { 154 | 155 | return 1025; 156 | }; 157 | 158 | EMWSPeer::EMWSPeer() { 159 | peer_sock = -1; 160 | queue_count = 0; 161 | _was_string = false; 162 | in_buffer.resize(16); 163 | write_mode = WRITE_MODE_BINARY; 164 | }; 165 | 166 | EMWSPeer::~EMWSPeer() { 167 | 168 | in_buffer.resize(0); 169 | close(); 170 | }; 171 | 172 | #endif // JAVASCRIPT_ENABLED 173 | -------------------------------------------------------------------------------- /modules/websocket/emws_peer.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* emws_peer.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef EMWSPEER_H 30 | #define EMWSPEER_H 31 | 32 | #ifdef JAVASCRIPT_ENABLED 33 | 34 | #include "core/error_list.h" 35 | #include "core/io/packet_peer.h" 36 | #include "core/ring_buffer.h" 37 | #include "emscripten.h" 38 | #include "websocket_peer.h" 39 | 40 | class EMWSPeer : public WebSocketPeer { 41 | 42 | GDCIIMPL(EMWSPeer, WebSocketPeer); 43 | 44 | private: 45 | enum { 46 | PACKET_BUFFER_SIZE = 65536 - 5 // 4 bytes for the size, 1 for for type 47 | }; 48 | 49 | int peer_sock; 50 | WriteMode write_mode; 51 | 52 | uint8_t packet_buffer[PACKET_BUFFER_SIZE]; 53 | RingBuffer in_buffer; 54 | int queue_count; 55 | bool _was_string; 56 | 57 | public: 58 | void read_msg(uint8_t *p_data, uint32_t p_size, bool p_is_string); 59 | void set_sock(int sock); 60 | virtual int get_available_packet_count() const; 61 | virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); 62 | virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); 63 | virtual int get_max_packet_size() const { return PACKET_BUFFER_SIZE; }; 64 | 65 | virtual void close(); 66 | virtual bool is_connected_to_host() const; 67 | virtual IP_Address get_connected_host() const; 68 | virtual uint16_t get_connected_port() const; 69 | 70 | virtual WriteMode get_write_mode() const; 71 | virtual void set_write_mode(WriteMode p_mode); 72 | virtual bool was_string_packet() const; 73 | 74 | void set_wsi(struct lws *wsi); 75 | Error read_wsi(void *in, size_t len); 76 | Error write_wsi(); 77 | 78 | EMWSPeer(); 79 | ~EMWSPeer(); 80 | }; 81 | 82 | #endif // JAVASCRIPT_ENABLED 83 | 84 | #endif // LSWPEER_H 85 | -------------------------------------------------------------------------------- /modules/websocket/emws_server.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* emws_server.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifdef JAVASCRIPT_ENABLED 30 | 31 | #include "emws_server.h" 32 | #include "core/os/os.h" 33 | 34 | Error EMWSServer::listen(int p_port, PoolVector p_protocols, bool gd_mp_api) { 35 | 36 | return FAILED; 37 | } 38 | 39 | bool EMWSServer::is_listening() const { 40 | return false; 41 | } 42 | 43 | void EMWSServer::stop() { 44 | } 45 | 46 | bool EMWSServer::has_peer(int p_id) const { 47 | return false; 48 | } 49 | 50 | Ref EMWSServer::get_peer(int p_id) const { 51 | return NULL; 52 | } 53 | 54 | PoolVector EMWSServer::get_protocols() const { 55 | PoolVector out; 56 | 57 | return out; 58 | } 59 | 60 | EMWSServer::EMWSServer() { 61 | } 62 | 63 | EMWSServer::~EMWSServer() { 64 | } 65 | 66 | #endif // JAVASCRIPT_ENABLED 67 | -------------------------------------------------------------------------------- /modules/websocket/emws_server.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* emws_server.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef EMWSSERVER_H 30 | #define EMWSSERVER_H 31 | 32 | #ifdef JAVASCRIPT_ENABLED 33 | 34 | #include "core/reference.h" 35 | #include "emws_peer.h" 36 | #include "websocket_server.h" 37 | 38 | class EMWSServer : public WebSocketServer { 39 | 40 | GDCIIMPL(EMWSServer, WebSocketServer); 41 | 42 | public: 43 | Error listen(int p_port, PoolVector p_protocols = PoolVector(), bool gd_mp_api = false); 44 | void stop(); 45 | bool is_listening() const; 46 | bool has_peer(int p_id) const; 47 | Ref get_peer(int p_id) const; 48 | virtual void poll(); 49 | virtual PoolVector get_protocols() const; 50 | 51 | EMWSServer(); 52 | ~EMWSServer(); 53 | }; 54 | 55 | #endif 56 | 57 | #endif // LWSSERVER_H 58 | -------------------------------------------------------------------------------- /modules/websocket/lws_client.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* lws_client.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef LWSCLIENT_H 30 | #define LWSCLIENT_H 31 | 32 | #ifndef JAVASCRIPT_ENABLED 33 | 34 | #include "core/error_list.h" 35 | #include "lws_helper.h" 36 | #include "lws_peer.h" 37 | #include "websocket_client.h" 38 | 39 | class LWSClient : public WebSocketClient { 40 | 41 | GDCIIMPL(LWSClient, WebSocketClient); 42 | 43 | LWS_HELPER(LWSClient); 44 | 45 | public: 46 | Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector p_protocol = PoolVector()); 47 | Ref get_peer(int p_peer_id) const; 48 | void disconnect_from_host(); 49 | IP_Address get_connected_host() const; 50 | uint16_t get_connected_port() const; 51 | virtual ConnectionStatus get_connection_status() const; 52 | virtual void poll(); 53 | 54 | LWSClient(); 55 | ~LWSClient(); 56 | }; 57 | 58 | #endif // JAVASCRIPT_ENABLED 59 | 60 | #endif // LWSCLIENT_H 61 | -------------------------------------------------------------------------------- /modules/websocket/lws_peer.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* lws_peer.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef LWSPEER_H 30 | #define LWSPEER_H 31 | 32 | #ifndef JAVASCRIPT_ENABLED 33 | 34 | #include "core/error_list.h" 35 | #include "core/io/packet_peer.h" 36 | #include "core/ring_buffer.h" 37 | #include "libwebsockets.h" 38 | #include "lws_config.h" 39 | #include "websocket_peer.h" 40 | 41 | class LWSPeer : public WebSocketPeer { 42 | 43 | GDCIIMPL(LWSPeer, WebSocketPeer); 44 | 45 | private: 46 | enum { 47 | PACKET_BUFFER_SIZE = 65536 - 5 // 4 bytes for the size, 1 for the type 48 | }; 49 | 50 | uint8_t packet_buffer[PACKET_BUFFER_SIZE]; 51 | struct lws *wsi; 52 | WriteMode write_mode; 53 | bool _was_string; 54 | 55 | public: 56 | struct PeerData { 57 | uint32_t peer_id; 58 | bool force_close; 59 | RingBuffer rbw; 60 | RingBuffer rbr; 61 | mutable uint8_t input_buffer[PACKET_BUFFER_SIZE]; 62 | uint32_t in_size; 63 | int in_count; 64 | int out_count; 65 | }; 66 | 67 | virtual int get_available_packet_count() const; 68 | virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); 69 | virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); 70 | virtual int get_max_packet_size() const { return PACKET_BUFFER_SIZE; }; 71 | 72 | virtual void close(); 73 | virtual bool is_connected_to_host() const; 74 | virtual IP_Address get_connected_host() const; 75 | virtual uint16_t get_connected_port() const; 76 | 77 | virtual WriteMode get_write_mode() const; 78 | virtual void set_write_mode(WriteMode p_mode); 79 | virtual bool was_string_packet() const; 80 | 81 | void set_wsi(struct lws *wsi); 82 | Error read_wsi(void *in, size_t len); 83 | Error write_wsi(); 84 | 85 | LWSPeer(); 86 | ~LWSPeer(); 87 | }; 88 | 89 | #endif // JAVASCRIPT_ENABLED 90 | 91 | #endif // LSWPEER_H 92 | -------------------------------------------------------------------------------- /modules/websocket/lws_server.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* lws_server.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef JAVASCRIPT_ENABLED 30 | 31 | #include "lws_server.h" 32 | #include "core/os/os.h" 33 | 34 | Error LWSServer::listen(int p_port, PoolVector p_protocols, bool gd_mp_api) { 35 | 36 | ERR_FAIL_COND_V(context != NULL, FAILED); 37 | 38 | _is_multiplayer = gd_mp_api; 39 | 40 | struct lws_context_creation_info info; 41 | memset(&info, 0, sizeof info); 42 | 43 | if (p_protocols.size() == 0) // default to binary protocol 44 | p_protocols.append(String("binary")); 45 | 46 | // Prepare lws protocol structs 47 | _lws_make_protocols(this, &LWSServer::_lws_gd_callback, p_protocols, &_lws_ref); 48 | 49 | info.port = p_port; 50 | info.user = _lws_ref; 51 | info.protocols = _lws_ref->lws_structs; 52 | info.gid = -1; 53 | info.uid = -1; 54 | //info.ws_ping_pong_interval = 5; 55 | 56 | context = lws_create_context(&info); 57 | 58 | if (context == NULL) { 59 | _lws_free_ref(_lws_ref); 60 | _lws_ref = NULL; 61 | ERR_EXPLAIN("Unable to create LWS context"); 62 | ERR_FAIL_V(FAILED); 63 | } 64 | 65 | return OK; 66 | } 67 | 68 | bool LWSServer::is_listening() const { 69 | return context != NULL; 70 | } 71 | 72 | int LWSServer::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { 73 | 74 | LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user; 75 | 76 | switch (reason) { 77 | case LWS_CALLBACK_HTTP: 78 | // no http for now 79 | // closing immediately returning -1; 80 | return -1; 81 | 82 | case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: 83 | // check header here? 84 | break; 85 | 86 | case LWS_CALLBACK_ESTABLISHED: { 87 | int32_t id = _gen_unique_id(); 88 | 89 | Ref peer = Ref(memnew(LWSPeer)); 90 | peer->set_wsi(wsi); 91 | _peer_map[id] = peer; 92 | 93 | peer_data->peer_id = id; 94 | peer_data->in_size = 0; 95 | peer_data->in_count = 0; 96 | peer_data->out_count = 0; 97 | peer_data->rbw.resize(16); 98 | peer_data->rbr.resize(16); 99 | peer_data->force_close = false; 100 | 101 | _on_connect(id, lws_get_protocol(wsi)->name); 102 | break; 103 | } 104 | 105 | case LWS_CALLBACK_CLOSED: { 106 | if (peer_data == NULL) 107 | return 0; 108 | int32_t id = peer_data->peer_id; 109 | if (_peer_map.has(id)) { 110 | _peer_map[id]->close(); 111 | _peer_map.erase(id); 112 | } 113 | peer_data->in_count = 0; 114 | peer_data->out_count = 0; 115 | peer_data->rbr.resize(0); 116 | peer_data->rbw.resize(0); 117 | _on_disconnect(id); 118 | return 0; // we can end here 119 | } 120 | 121 | case LWS_CALLBACK_RECEIVE: { 122 | int32_t id = peer_data->peer_id; 123 | if (_peer_map.has(id)) { 124 | static_cast >(_peer_map[id])->read_wsi(in, len); 125 | if (_peer_map[id]->get_available_packet_count() > 0) 126 | _on_peer_packet(id); 127 | } 128 | break; 129 | } 130 | 131 | case LWS_CALLBACK_SERVER_WRITEABLE: { 132 | if (peer_data->force_close) 133 | return -1; 134 | 135 | int id = peer_data->peer_id; 136 | if (_peer_map.has(id)) 137 | static_cast >(_peer_map[id])->write_wsi(); 138 | break; 139 | } 140 | 141 | default: 142 | break; 143 | } 144 | 145 | return 0; 146 | } 147 | 148 | void LWSServer::stop() { 149 | if (context == NULL) 150 | return; 151 | 152 | _peer_map.clear(); 153 | destroy_context(); 154 | context = NULL; 155 | } 156 | 157 | bool LWSServer::has_peer(int p_id) const { 158 | return _peer_map.has(p_id); 159 | } 160 | 161 | Ref LWSServer::get_peer(int p_id) const { 162 | ERR_FAIL_COND_V(!has_peer(p_id), NULL); 163 | return _peer_map[p_id]; 164 | } 165 | 166 | LWSServer::LWSServer() { 167 | context = NULL; 168 | _lws_ref = NULL; 169 | } 170 | 171 | LWSServer::~LWSServer() { 172 | invalidate_lws_ref(); // we do not want any more callbacks 173 | stop(); 174 | } 175 | 176 | #endif // JAVASCRIPT_ENABLED 177 | -------------------------------------------------------------------------------- /modules/websocket/lws_server.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* lws_server.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef LWSSERVER_H 30 | #define LWSSERVER_H 31 | 32 | #ifndef JAVASCRIPT_ENABLED 33 | 34 | #include "core/reference.h" 35 | #include "lws_helper.h" 36 | #include "lws_peer.h" 37 | #include "websocket_server.h" 38 | 39 | class LWSServer : public WebSocketServer { 40 | 41 | GDCIIMPL(LWSServer, WebSocketServer); 42 | 43 | LWS_HELPER(LWSServer); 44 | 45 | private: 46 | Map > peer_map; 47 | 48 | public: 49 | Error listen(int p_port, PoolVector p_protocols = PoolVector(), bool gd_mp_api = false); 50 | void stop(); 51 | bool is_listening() const; 52 | bool has_peer(int p_id) const; 53 | Ref get_peer(int p_id) const; 54 | virtual void poll() { _lws_poll(); } 55 | 56 | LWSServer(); 57 | ~LWSServer(); 58 | }; 59 | 60 | #endif // JAVASCRIPT_ENABLED 61 | 62 | #endif // LWSSERVER_H 63 | -------------------------------------------------------------------------------- /modules/websocket/register_types.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* register_types.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #include "register_types.h" 30 | #include "error_macros.h" 31 | #ifdef JAVASCRIPT_ENABLED 32 | #include "emscripten.h" 33 | #include "emws_client.h" 34 | #include "emws_peer.h" 35 | #include "emws_server.h" 36 | #else 37 | #include "lws_client.h" 38 | #include "lws_peer.h" 39 | #include "lws_server.h" 40 | #endif 41 | 42 | void register_websocket_types() { 43 | #ifdef JAVASCRIPT_ENABLED 44 | EM_ASM({ 45 | var IDHandler = {}; 46 | IDHandler["ids"] = {}; 47 | IDHandler["has"] = function(id) { 48 | return IDHandler.ids.hasOwnProperty(id); 49 | }; 50 | IDHandler["add"] = function(obj) { 51 | var id = crypto.getRandomValues(new Int32Array(32))[0]; 52 | IDHandler.ids[id] = obj; 53 | return id; 54 | }; 55 | IDHandler["get"] = function(id) { 56 | return IDHandler.ids[id]; 57 | }; 58 | IDHandler["remove"] = function(id) { 59 | delete IDHandler.ids[id]; 60 | }; 61 | Module["IDHandler"] = IDHandler; 62 | }); 63 | EMWSPeer::make_default(); 64 | EMWSClient::make_default(); 65 | EMWSServer::make_default(); 66 | #else 67 | LWSPeer::make_default(); 68 | LWSClient::make_default(); 69 | LWSServer::make_default(); 70 | #endif 71 | 72 | ClassDB::register_virtual_class(); 73 | ClassDB::register_custom_instance_class(); 74 | ClassDB::register_custom_instance_class(); 75 | ClassDB::register_custom_instance_class(); 76 | } 77 | 78 | void unregister_websocket_types() {} 79 | -------------------------------------------------------------------------------- /modules/websocket/register_types.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* register_types.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | void register_websocket_types(); 30 | void unregister_websocket_types(); 31 | -------------------------------------------------------------------------------- /modules/websocket/websocket_client.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_client.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #include "websocket_client.h" 30 | 31 | GDCINULL(WebSocketClient); 32 | 33 | WebSocketClient::WebSocketClient() { 34 | } 35 | 36 | WebSocketClient::~WebSocketClient() { 37 | } 38 | 39 | Error WebSocketClient::connect_to_url(String p_url, PoolVector p_protocols, bool gd_mp_api) { 40 | _is_multiplayer = gd_mp_api; 41 | 42 | String host = p_url; 43 | String path = "/"; 44 | int p_len = -1; 45 | int port = 80; 46 | bool ssl = false; 47 | if (host.begins_with("wss://")) { 48 | ssl = true; // we should implement this 49 | host = host.substr(6, host.length() - 6); 50 | port = 443; 51 | } else { 52 | ssl = false; 53 | if (host.begins_with("ws://")) 54 | host = host.substr(5, host.length() - 5); 55 | } 56 | 57 | // Path 58 | p_len = host.find("/"); 59 | if (p_len != -1) { 60 | path = host.substr(p_len, host.length() - p_len); 61 | host = host.substr(0, p_len); 62 | } 63 | 64 | // Port 65 | p_len = host.find_last(":"); 66 | if (p_len != -1 && p_len == host.find(":")) { 67 | port = host.substr(p_len, host.length() - p_len).to_int(); 68 | host = host.substr(0, p_len); 69 | } 70 | 71 | return connect_to_host(host, path, port, ssl, p_protocols); 72 | } 73 | 74 | bool WebSocketClient::is_server() const { 75 | 76 | return false; 77 | } 78 | 79 | void WebSocketClient::_on_peer_packet() { 80 | 81 | if (_is_multiplayer) { 82 | _process_multiplayer(get_peer(1), 1); 83 | } else { 84 | emit_signal("data_received"); 85 | } 86 | } 87 | 88 | void WebSocketClient::_on_connect(String p_protocol) { 89 | 90 | if (_is_multiplayer) { 91 | // need to wait for ID confirmation... 92 | } else { 93 | emit_signal("connection_established", p_protocol); 94 | } 95 | } 96 | 97 | void WebSocketClient::_on_disconnect() { 98 | 99 | if (_is_multiplayer) { 100 | emit_signal("connection_failed"); 101 | } else { 102 | emit_signal("connection_closed"); 103 | } 104 | } 105 | 106 | void WebSocketClient::_on_error() { 107 | 108 | if (_is_multiplayer) { 109 | emit_signal("connection_failed"); 110 | } else { 111 | emit_signal("connection_error"); 112 | } 113 | } 114 | 115 | void WebSocketClient::_bind_methods() { 116 | ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api"), &WebSocketClient::connect_to_url, DEFVAL(PoolVector()), DEFVAL(false)); 117 | ClassDB::bind_method(D_METHOD("disconnect_from_host"), &WebSocketClient::disconnect_from_host); 118 | 119 | ADD_SIGNAL(MethodInfo("data_received")); 120 | ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol"))); 121 | ADD_SIGNAL(MethodInfo("connection_closed")); 122 | ADD_SIGNAL(MethodInfo("connection_error")); 123 | } 124 | -------------------------------------------------------------------------------- /modules/websocket/websocket_client.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_client.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef WEBSOCKET_CLIENT_H 30 | #define WEBSOCKET_CLIENT_H 31 | 32 | #include "core/error_list.h" 33 | #include "websocket_multiplayer.h" 34 | #include "websocket_peer.h" 35 | 36 | class WebSocketClient : public WebSocketMultiplayerPeer { 37 | 38 | GDCLASS(WebSocketClient, WebSocketMultiplayerPeer); 39 | GDCICLASS(WebSocketClient); 40 | 41 | protected: 42 | Ref _peer; 43 | 44 | static void _bind_methods(); 45 | 46 | public: 47 | Error connect_to_url(String p_url, PoolVector p_protocols = PoolVector(), bool gd_mp_api = false); 48 | 49 | virtual void poll() = 0; 50 | virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector p_protocol = PoolVector()) = 0; 51 | virtual void disconnect_from_host() = 0; 52 | virtual IP_Address get_connected_host() const = 0; 53 | virtual uint16_t get_connected_port() const = 0; 54 | 55 | virtual bool is_server() const; 56 | virtual ConnectionStatus get_connection_status() const = 0; 57 | 58 | void _on_peer_packet(); 59 | void _on_connect(String p_protocol); 60 | void _on_disconnect(); 61 | void _on_error(); 62 | 63 | WebSocketClient(); 64 | ~WebSocketClient(); 65 | }; 66 | 67 | #endif // WEBSOCKET_CLIENT_H 68 | -------------------------------------------------------------------------------- /modules/websocket/websocket_macros.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_macros.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef WEBSOCKETMACTOS_H 30 | #define WEBSOCKETMACTOS_H 31 | 32 | /* clang-format off */ 33 | #define GDCICLASS(CNAME) \ 34 | public:\ 35 | static CNAME *(*_create)();\ 36 | \ 37 | static Ref create_ref() {\ 38 | \ 39 | if (!_create)\ 40 | return Ref();\ 41 | return Ref(_create());\ 42 | }\ 43 | \ 44 | static CNAME *create() {\ 45 | \ 46 | if (!_create)\ 47 | return NULL;\ 48 | return _create();\ 49 | }\ 50 | protected:\ 51 | 52 | #define GDCINULL(CNAME) \ 53 | CNAME *(*CNAME::_create)() = NULL; 54 | 55 | #define GDCIIMPL(IMPNAME, CNAME) \ 56 | public:\ 57 | static CNAME *_create() { return memnew(IMPNAME); }\ 58 | static void make_default() { CNAME::_create = IMPNAME::_create; }\ 59 | protected:\ 60 | /* clang-format on */ 61 | 62 | #endif // WEBSOCKETMACTOS_H 63 | -------------------------------------------------------------------------------- /modules/websocket/websocket_multiplayer.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_multiplayer.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef WEBSOCKET_MULTIPLAYER_PEER_H 30 | #define WEBSOCKET_MULTIPLAYER_PEER_H 31 | 32 | #include "core/error_list.h" 33 | #include "core/io/networked_multiplayer_peer.h" 34 | #include "core/list.h" 35 | #include "websocket_peer.h" 36 | 37 | class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer { 38 | 39 | GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer); 40 | 41 | private: 42 | PoolVector _make_pkt(uint32_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size); 43 | void _store_pkt(int32_t p_source, int32_t p_dest, const uint8_t *p_data, uint32_t p_data_size); 44 | Error _server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size); 45 | 46 | protected: 47 | enum { 48 | SYS_NONE = 0, 49 | SYS_ADD = 1, 50 | SYS_DEL = 2, 51 | SYS_ID = 3, 52 | 53 | PROTO_SIZE = 9, 54 | SYS_PACKET_SIZE = 13, 55 | MAX_PACKET_SIZE = 65536 - 14 // 5 websocket, 9 multiplayer 56 | }; 57 | 58 | struct Packet { 59 | int source; 60 | int destination; 61 | uint8_t *data; 62 | uint32_t size; 63 | }; 64 | 65 | List _incoming_packets; 66 | Map > _peer_map; 67 | Packet _current_packet; 68 | 69 | bool _is_multiplayer; 70 | int _target_peer; 71 | int _peer_id; 72 | int _refusing; 73 | 74 | static void _bind_methods(); 75 | 76 | void _send_add(int32_t p_peer_id); 77 | void _send_sys(Ref p_peer, uint8_t p_type, int32_t p_peer_id); 78 | void _send_del(int32_t p_peer_id); 79 | int _gen_unique_id() const; 80 | 81 | public: 82 | /* NetworkedMultiplayerPeer */ 83 | void set_transfer_mode(TransferMode p_mode); 84 | TransferMode get_transfer_mode() const; 85 | void set_target_peer(int p_peer_id); 86 | int get_packet_peer() const; 87 | int get_unique_id() const; 88 | virtual bool is_server() const = 0; 89 | void set_refuse_new_connections(bool p_enable); 90 | bool is_refusing_new_connections() const; 91 | virtual ConnectionStatus get_connection_status() const = 0; 92 | 93 | /* PacketPeer */ 94 | virtual int get_available_packet_count() const; 95 | virtual int get_max_packet_size() const; 96 | virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); 97 | virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); 98 | 99 | /* WebSocketPeer */ 100 | virtual Ref get_peer(int p_peer_id) const = 0; 101 | 102 | void _process_multiplayer(Ref p_peer, uint32_t p_peer_id); 103 | void _clear(); 104 | 105 | WebSocketMultiplayerPeer(); 106 | ~WebSocketMultiplayerPeer(); 107 | }; 108 | 109 | #endif // WEBSOCKET_MULTIPLAYER_PEER_H 110 | -------------------------------------------------------------------------------- /modules/websocket/websocket_peer.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_peer.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #include "websocket_peer.h" 30 | 31 | GDCINULL(WebSocketPeer); 32 | 33 | WebSocketPeer::WebSocketPeer() { 34 | } 35 | 36 | WebSocketPeer::~WebSocketPeer() { 37 | } 38 | 39 | void WebSocketPeer::_bind_methods() { 40 | ClassDB::bind_method(D_METHOD("get_write_mode"), &WebSocketPeer::get_write_mode); 41 | ClassDB::bind_method(D_METHOD("set_write_mode", "mode"), &WebSocketPeer::set_write_mode); 42 | ClassDB::bind_method(D_METHOD("is_connected_to_host"), &WebSocketPeer::is_connected_to_host); 43 | ClassDB::bind_method(D_METHOD("was_string_packet"), &WebSocketPeer::was_string_packet); 44 | ClassDB::bind_method(D_METHOD("close"), &WebSocketPeer::close); 45 | 46 | BIND_ENUM_CONSTANT(WRITE_MODE_TEXT); 47 | BIND_ENUM_CONSTANT(WRITE_MODE_BINARY); 48 | } 49 | -------------------------------------------------------------------------------- /modules/websocket/websocket_peer.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_peer.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef WEBSOCKETPEER_H 30 | #define WEBSOCKETPEER_H 31 | 32 | #include "core/error_list.h" 33 | #include "core/io/packet_peer.h" 34 | #include "core/ring_buffer.h" 35 | #include "websocket_macros.h" 36 | 37 | class WebSocketPeer : public PacketPeer { 38 | 39 | GDCLASS(WebSocketPeer, PacketPeer); 40 | GDCICLASS(WebSocketPeer); 41 | 42 | public: 43 | enum WriteMode { 44 | WRITE_MODE_TEXT, 45 | WRITE_MODE_BINARY, 46 | }; 47 | 48 | protected: 49 | static void _bind_methods(); 50 | 51 | public: 52 | virtual int get_available_packet_count() const = 0; 53 | virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) = 0; 54 | virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) = 0; 55 | virtual int get_max_packet_size() const = 0; 56 | 57 | virtual WriteMode get_write_mode() const = 0; 58 | virtual void set_write_mode(WriteMode p_mode) = 0; 59 | 60 | virtual void close() = 0; 61 | 62 | virtual bool is_connected_to_host() const = 0; 63 | virtual IP_Address get_connected_host() const = 0; 64 | virtual uint16_t get_connected_port() const = 0; 65 | virtual bool was_string_packet() const = 0; 66 | 67 | WebSocketPeer(); 68 | ~WebSocketPeer(); 69 | }; 70 | 71 | VARIANT_ENUM_CAST(WebSocketPeer::WriteMode); 72 | #endif // WEBSOCKETPEER_H 73 | -------------------------------------------------------------------------------- /modules/websocket/websocket_server.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_server.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #include "websocket_server.h" 30 | 31 | GDCINULL(WebSocketServer); 32 | 33 | WebSocketServer::WebSocketServer() { 34 | _peer_id = 1; 35 | } 36 | 37 | WebSocketServer::~WebSocketServer() { 38 | } 39 | 40 | void WebSocketServer::_bind_methods() { 41 | 42 | ClassDB::bind_method(D_METHOD("is_listening"), &WebSocketServer::is_listening); 43 | ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(PoolVector()), DEFVAL(false)); 44 | ClassDB::bind_method(D_METHOD("stop"), &WebSocketServer::stop); 45 | ClassDB::bind_method(D_METHOD("has_peer", "id"), &WebSocketServer::has_peer); 46 | 47 | ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"))); 48 | ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"))); 49 | ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id"))); 50 | } 51 | 52 | NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const { 53 | if (is_listening()) 54 | return CONNECTION_CONNECTED; 55 | 56 | return CONNECTION_DISCONNECTED; 57 | }; 58 | 59 | bool WebSocketServer::is_server() const { 60 | 61 | return true; 62 | } 63 | 64 | void WebSocketServer::_on_peer_packet(int32_t p_peer_id) { 65 | 66 | if (_is_multiplayer) { 67 | _process_multiplayer(get_peer(p_peer_id), p_peer_id); 68 | } else { 69 | emit_signal("data_received", p_peer_id); 70 | } 71 | } 72 | 73 | void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol) { 74 | 75 | if (_is_multiplayer) { 76 | // Send add to clients 77 | _send_add(p_peer_id); 78 | emit_signal("peer_connected", p_peer_id); 79 | } else { 80 | emit_signal("client_connected", p_peer_id, p_protocol); 81 | } 82 | } 83 | 84 | void WebSocketServer::_on_disconnect(int32_t p_peer_id) { 85 | 86 | if (_is_multiplayer) { 87 | // Send delete to clients 88 | _send_del(p_peer_id); 89 | emit_signal("peer_disconnected", p_peer_id); 90 | } else { 91 | emit_signal("client_disconnected", p_peer_id); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /modules/websocket/websocket_server.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* websocket_server.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT WEBSOCKET MODULE */ 6 | /* https://github.com/LudiDorici/godot-websocket */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2017 Ludi Dorici, di Alessandrelli Fabio */ 9 | /* */ 10 | /* Permission is hereby granted, free of charge, to any person obtaining */ 11 | /* a copy of this software and associated documentation files (the */ 12 | /* "Software"), to deal in the Software without restriction, including */ 13 | /* without limitation the rights to use, copy, modify, merge, publish, */ 14 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 15 | /* permit persons to whom the Software is furnished to do so, subject to */ 16 | /* the following conditions: */ 17 | /* */ 18 | /* The above copyright notice and this permission notice shall be */ 19 | /* included in all copies or substantial portions of the Software. */ 20 | /* */ 21 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 22 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 23 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 24 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 25 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 26 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 27 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 28 | /*************************************************************************/ 29 | #ifndef WEBSOCKET_H 30 | #define WEBSOCKET_H 31 | 32 | #include "core/reference.h" 33 | #include "websocket_multiplayer.h" 34 | #include "websocket_peer.h" 35 | 36 | class WebSocketServer : public WebSocketMultiplayerPeer { 37 | 38 | GDCLASS(WebSocketServer, WebSocketMultiplayerPeer); 39 | GDCICLASS(WebSocketServer); 40 | 41 | protected: 42 | static void _bind_methods(); 43 | 44 | public: 45 | virtual void poll() = 0; 46 | virtual Error listen(int p_port, PoolVector p_protocols = PoolVector(), bool gd_mp_api = false) = 0; 47 | virtual void stop() = 0; 48 | virtual bool is_listening() const = 0; 49 | virtual bool has_peer(int p_id) const = 0; 50 | virtual Ref get_peer(int p_id) const = 0; 51 | virtual bool is_server() const; 52 | ConnectionStatus get_connection_status() const; 53 | 54 | void _on_peer_packet(int32_t p_peer_id); 55 | void _on_connect(int32_t p_peer_id, String p_protocol); 56 | void _on_disconnect(int32_t p_peer_id); 57 | 58 | WebSocketServer(); 59 | ~WebSocketServer(); 60 | }; 61 | 62 | #endif // WEBSOCKET_H 63 | -------------------------------------------------------------------------------- /multiplayer_demo/.gitignore: -------------------------------------------------------------------------------- 1 | .import/* 2 | *.import 3 | export_presets.cfg 4 | -------------------------------------------------------------------------------- /multiplayer_demo/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 5 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 6 | sky_curve = 0.25 7 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 8 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 9 | ground_curve = 0.01 10 | sun_energy = 16.0 11 | 12 | [resource] 13 | background_mode = 2 14 | background_sky = SubResource( 1 ) 15 | -------------------------------------------------------------------------------- /multiplayer_demo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LudiDorici/godot-websocket/db42508f8abc580e1c02f690434598cc02d2ed77/multiplayer_demo/icon.png -------------------------------------------------------------------------------- /multiplayer_demo/img/crown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LudiDorici/godot-websocket/db42508f8abc580e1c02f690434598cc02d2ed77/multiplayer_demo/img/crown.png -------------------------------------------------------------------------------- /multiplayer_demo/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | 14 | } 15 | 16 | [application] 17 | 18 | config/name="Websocket Multiplayer Demo" 19 | run/main_scene="res://scene/main.tscn" 20 | config/icon="res://icon.png" 21 | 22 | [rendering] 23 | 24 | environment/default_environment="res://default_env.tres" 25 | -------------------------------------------------------------------------------- /multiplayer_demo/scene/game.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://script/game.gd" type="Script" id=1] 4 | 5 | [node name="Game" type="Control"] 6 | 7 | anchor_left = 0.0 8 | anchor_top = 0.0 9 | anchor_right = 1.0 10 | anchor_bottom = 1.0 11 | rect_pivot_offset = Vector2( 0, 0 ) 12 | rect_clip_content = false 13 | mouse_filter = 1 14 | size_flags_horizontal = 3 15 | size_flags_vertical = 3 16 | script = ExtResource( 1 ) 17 | _sections_unfolded = [ "Size Flags" ] 18 | 19 | [node name="HBoxContainer" type="HBoxContainer" parent="."] 20 | 21 | anchor_left = 0.0 22 | anchor_top = 0.0 23 | anchor_right = 1.0 24 | anchor_bottom = 1.0 25 | rect_pivot_offset = Vector2( 0, 0 ) 26 | rect_clip_content = false 27 | mouse_filter = 1 28 | size_flags_horizontal = 1 29 | size_flags_vertical = 1 30 | alignment = 0 31 | 32 | [node name="RichTextLabel" type="RichTextLabel" parent="HBoxContainer"] 33 | 34 | anchor_left = 0.0 35 | anchor_top = 0.0 36 | anchor_right = 0.0 37 | anchor_bottom = 0.0 38 | margin_right = 510.0 39 | margin_bottom = 600.0 40 | rect_pivot_offset = Vector2( 0, 0 ) 41 | mouse_filter = 0 42 | size_flags_horizontal = 3 43 | size_flags_vertical = 1 44 | bbcode_enabled = false 45 | bbcode_text = "" 46 | visible_characters = -1 47 | percent_visible = 1.0 48 | override_selected_font_color = false 49 | _sections_unfolded = [ "Size Flags" ] 50 | 51 | [node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] 52 | 53 | anchor_left = 0.0 54 | anchor_top = 0.0 55 | anchor_right = 0.0 56 | anchor_bottom = 0.0 57 | margin_left = 514.0 58 | margin_right = 1024.0 59 | margin_bottom = 600.0 60 | rect_pivot_offset = Vector2( 0, 0 ) 61 | rect_clip_content = false 62 | mouse_filter = 1 63 | size_flags_horizontal = 3 64 | size_flags_vertical = 1 65 | alignment = 0 66 | _sections_unfolded = [ "Size Flags" ] 67 | 68 | [node name="Label" type="Label" parent="HBoxContainer/VBoxContainer"] 69 | 70 | anchor_left = 0.0 71 | anchor_top = 0.0 72 | anchor_right = 0.0 73 | anchor_bottom = 0.0 74 | margin_right = 510.0 75 | margin_bottom = 14.0 76 | rect_pivot_offset = Vector2( 0, 0 ) 77 | rect_clip_content = false 78 | mouse_filter = 2 79 | size_flags_horizontal = 1 80 | size_flags_vertical = 4 81 | text = "Players:" 82 | percent_visible = 1.0 83 | lines_skipped = 0 84 | max_lines_visible = -1 85 | 86 | [node name="ItemList" type="ItemList" parent="HBoxContainer/VBoxContainer"] 87 | 88 | anchor_left = 0.0 89 | anchor_top = 0.0 90 | anchor_right = 0.0 91 | anchor_bottom = 0.0 92 | margin_top = 18.0 93 | margin_right = 510.0 94 | margin_bottom = 576.0 95 | rect_pivot_offset = Vector2( 0, 0 ) 96 | mouse_filter = 0 97 | size_flags_horizontal = 3 98 | size_flags_vertical = 3 99 | items = [ ] 100 | select_mode = 0 101 | same_column_width = true 102 | icon_mode = 1 103 | _sections_unfolded = [ "Columns", "Mouse", "Size Flags" ] 104 | 105 | [node name="Action" type="Button" parent="HBoxContainer/VBoxContainer"] 106 | 107 | anchor_left = 0.0 108 | anchor_top = 0.0 109 | anchor_right = 0.0 110 | anchor_bottom = 0.0 111 | margin_top = 580.0 112 | margin_right = 510.0 113 | margin_bottom = 600.0 114 | rect_pivot_offset = Vector2( 0, 0 ) 115 | rect_clip_content = false 116 | mouse_filter = 0 117 | size_flags_horizontal = 1 118 | size_flags_vertical = 1 119 | disabled = true 120 | toggle_mode = false 121 | enabled_focus_mode = 2 122 | shortcut = null 123 | group = null 124 | text = "Do Action!" 125 | flat = false 126 | align = 1 127 | 128 | [connection signal="pressed" from="HBoxContainer/VBoxContainer/Action" to="." method="_on_Action_pressed"] 129 | 130 | 131 | -------------------------------------------------------------------------------- /multiplayer_demo/scene/main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://script/main.gd" type="Script" id=1] 4 | [ext_resource path="res://scene/game.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Control" type="Control"] 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | script = ExtResource( 1 ) 10 | 11 | [node name="Panel" type="Panel" parent="."] 12 | anchor_right = 1.0 13 | anchor_bottom = 1.0 14 | 15 | [node name="VBoxContainer" type="VBoxContainer" parent="Panel"] 16 | anchor_right = 1.0 17 | anchor_bottom = 1.0 18 | margin_left = 20.0 19 | margin_top = 20.0 20 | margin_right = -20.0 21 | margin_bottom = -20.0 22 | 23 | [node name="HBoxContainer" type="HBoxContainer" parent="Panel/VBoxContainer"] 24 | margin_right = 984.0 25 | margin_bottom = 24.0 26 | 27 | [node name="Label" type="Label" parent="Panel/VBoxContainer/HBoxContainer"] 28 | margin_top = 5.0 29 | margin_right = 326.0 30 | margin_bottom = 19.0 31 | size_flags_horizontal = 3 32 | text = "Name" 33 | 34 | [node name="NameEdit" type="LineEdit" parent="Panel/VBoxContainer/HBoxContainer"] 35 | margin_left = 330.0 36 | margin_right = 984.0 37 | margin_bottom = 24.0 38 | size_flags_horizontal = 3 39 | size_flags_stretch_ratio = 2.0 40 | text = "A Godot User" 41 | 42 | [node name="HBoxContainer2" type="HBoxContainer" parent="Panel/VBoxContainer"] 43 | margin_top = 28.0 44 | margin_right = 984.0 45 | margin_bottom = 52.0 46 | 47 | [node name="HBoxContainer" type="HBoxContainer" parent="Panel/VBoxContainer/HBoxContainer2"] 48 | margin_right = 326.0 49 | margin_bottom = 24.0 50 | size_flags_horizontal = 3 51 | 52 | [node name="Host" type="Button" parent="Panel/VBoxContainer/HBoxContainer2/HBoxContainer"] 53 | margin_right = 42.0 54 | margin_bottom = 24.0 55 | text = "Host" 56 | 57 | [node name="Control" type="Control" parent="Panel/VBoxContainer/HBoxContainer2/HBoxContainer"] 58 | margin_left = 46.0 59 | margin_right = 241.0 60 | margin_bottom = 24.0 61 | size_flags_horizontal = 3 62 | 63 | [node name="Connect" type="Button" parent="Panel/VBoxContainer/HBoxContainer2/HBoxContainer"] 64 | margin_left = 245.0 65 | margin_right = 326.0 66 | margin_bottom = 24.0 67 | text = "Connect to" 68 | 69 | [node name="Disconnect" type="Button" parent="Panel/VBoxContainer/HBoxContainer2/HBoxContainer"] 70 | visible = false 71 | margin_left = 68.0 72 | margin_right = 152.0 73 | margin_bottom = 24.0 74 | text = "Disconnect" 75 | 76 | [node name="Hostname" type="LineEdit" parent="Panel/VBoxContainer/HBoxContainer2"] 77 | margin_left = 330.0 78 | margin_right = 984.0 79 | margin_bottom = 24.0 80 | size_flags_horizontal = 3 81 | size_flags_stretch_ratio = 2.0 82 | text = "localhost" 83 | placeholder_text = "localhost" 84 | 85 | [node name="Control" type="Control" parent="Panel/VBoxContainer"] 86 | margin_top = 56.0 87 | margin_right = 984.0 88 | margin_bottom = 76.0 89 | rect_min_size = Vector2( 0, 20 ) 90 | 91 | [node name="Game" parent="Panel/VBoxContainer" instance=ExtResource( 2 )] 92 | anchor_right = 0.0 93 | anchor_bottom = 0.0 94 | margin_top = 80.0 95 | margin_right = 984.0 96 | margin_bottom = 560.0 97 | 98 | [node name="AcceptDialog" type="AcceptDialog" parent="."] 99 | anchor_left = 0.5 100 | anchor_top = 0.5 101 | anchor_right = 0.5 102 | anchor_bottom = 0.5 103 | margin_left = -200.0 104 | margin_top = -100.0 105 | margin_right = 200.0 106 | margin_bottom = 100.0 107 | dialog_text = "Connection closed" 108 | [connection signal="pressed" from="Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Host" to="." method="_on_Host_pressed"] 109 | [connection signal="pressed" from="Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Connect" to="." method="_on_Connect_pressed"] 110 | [connection signal="pressed" from="Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Disconnect" to="." method="_on_Disconnect_pressed"] 111 | -------------------------------------------------------------------------------- /multiplayer_demo/script/game.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | const _crown = preload("res://img/crown.png") 4 | 5 | onready var _list = $HBoxContainer/VBoxContainer/ItemList 6 | onready var _action = $HBoxContainer/VBoxContainer/Action 7 | 8 | var _players = [] 9 | var _turn = -1 10 | 11 | master func set_player_name(name): 12 | var sender = get_tree().get_rpc_sender_id() 13 | rpc("update_player_name", sender, name) 14 | 15 | sync func update_player_name(player, name): 16 | var pos = _players.find(player) 17 | if pos != -1: 18 | _list.set_item_text(pos, name) 19 | 20 | master func request_action(action): 21 | var sender = get_tree().get_rpc_sender_id() 22 | if _players[_turn] != get_tree().get_rpc_sender_id(): 23 | rpc("_log", "Someone is trying to cheat! %s" % str(sender)) 24 | return 25 | do_action(action) 26 | next_turn() 27 | 28 | sync func do_action(action): 29 | var name = _list.get_item_text(_turn) 30 | _log("%s: %ss %d" % [name, action, randi() % 100]) 31 | 32 | sync func set_turn(turn): 33 | _turn = turn 34 | if turn >= _players.size(): 35 | return 36 | for i in range(0, _players.size()): 37 | if i == turn: 38 | _list.set_item_icon(i, _crown) 39 | else: 40 | _list.set_item_icon(i, null) 41 | _action.disabled = _players[turn] != get_tree().get_network_unique_id() 42 | 43 | sync func del_player(id): 44 | var pos = _players.find(id) 45 | if pos == -1: 46 | return 47 | _players.remove(pos) 48 | _list.remove_item(pos) 49 | if _turn > pos: 50 | _turn -= 1 51 | if get_tree().is_network_server(): 52 | rpc("set_turn", _turn) 53 | 54 | sync func add_player(id, name=""): 55 | _players.append(id) 56 | if name == "": 57 | _list.add_item("... connecting ...", null, false) 58 | else: 59 | _list.add_item(name, null, false) 60 | 61 | func get_player_name(pos): 62 | if pos < _list.get_item_count(): 63 | return _list.get_item_text(pos) 64 | else: 65 | return "Error!" 66 | 67 | func next_turn(): 68 | _turn += 1 69 | if _turn >= _players.size(): 70 | _turn = 0 71 | rpc("set_turn", _turn) 72 | 73 | func start(): 74 | set_turn(0) 75 | 76 | func stop(): 77 | _players.clear() 78 | _list.clear() 79 | _turn = 0 80 | _action.disabled = true 81 | 82 | func on_peer_add(id): 83 | if not get_tree().is_network_server(): 84 | return 85 | for i in range(0, _players.size()): 86 | rpc_id(id, "add_player", _players[i], get_player_name(i)) 87 | rpc("add_player", id) 88 | rpc_id(id, "set_turn", _turn) 89 | 90 | func on_peer_del(id): 91 | if not get_tree().is_network_server(): 92 | return 93 | rpc("del_player", id) 94 | 95 | sync func _log(what): 96 | $HBoxContainer/RichTextLabel.add_text(what + "\n") 97 | 98 | func _on_Action_pressed(): 99 | if get_tree().is_network_server(): 100 | rpc("do_action", "roll") 101 | next_turn() 102 | else: 103 | rpc("request_action", "roll") -------------------------------------------------------------------------------- /multiplayer_demo/script/main.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | const DEF_PORT = 8080 4 | const PROTO_NAME = "ludus" 5 | 6 | onready var _host_btn = $Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Host 7 | onready var _connect_btn = $Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Connect 8 | onready var _disconnect_btn = $Panel/VBoxContainer/HBoxContainer2/HBoxContainer/Disconnect 9 | onready var _name_edit = $Panel/VBoxContainer/HBoxContainer/NameEdit 10 | onready var _host_edit = $Panel/VBoxContainer/HBoxContainer2/Hostname 11 | onready var _game = $Panel/VBoxContainer/Game 12 | 13 | func _ready(): 14 | get_tree().connect("network_peer_disconnected", self, "_peer_disconnected") 15 | get_tree().connect("network_peer_connected", self, "_peer_connected") 16 | $AcceptDialog.get_label().align = Label.ALIGN_CENTER 17 | $AcceptDialog.get_label().valign = Label.VALIGN_CENTER 18 | 19 | func start_game(): 20 | _host_btn.disabled = true 21 | _name_edit.editable = false 22 | _host_edit.editable = false 23 | _connect_btn.hide() 24 | _disconnect_btn.show() 25 | _game.start() 26 | 27 | func stop_game(): 28 | _host_btn.disabled = false 29 | _name_edit.editable = true 30 | _host_edit.editable = true 31 | _disconnect_btn.hide() 32 | _connect_btn.show() 33 | _game.stop() 34 | 35 | func _close_network(): 36 | if get_tree().is_connected("server_disconnected", self, "_close_network"): 37 | get_tree().disconnect("server_disconnected", self, "_close_network") 38 | if get_tree().is_connected("connection_failed", self, "_close_network"): 39 | get_tree().disconnect("connection_failed", self, "_close_network") 40 | if get_tree().is_connected("connected_to_server", self, "_connected"): 41 | get_tree().disconnect("connected_to_server", self, "_connected") 42 | stop_game() 43 | $AcceptDialog.show_modal() 44 | $AcceptDialog.get_close_button().grab_focus() 45 | get_tree().set_network_peer(null) 46 | 47 | func _connected(): 48 | _game.rpc("set_player_name", _name_edit.text) 49 | 50 | func _peer_connected(id): 51 | _game.on_peer_add(id) 52 | 53 | func _peer_disconnected(id): 54 | _game.on_peer_del(id) 55 | 56 | func _on_Host_pressed(): 57 | var host = WebSocketServer.new() 58 | host.listen(DEF_PORT, PoolStringArray(["ludus"]), true) 59 | get_tree().connect("server_disconnected", self, "_close_network") 60 | get_tree().set_network_peer(host) 61 | _game.add_player(1, _name_edit.text) 62 | start_game() 63 | 64 | func _on_Disconnect_pressed(): 65 | _close_network() 66 | 67 | func _on_Connect_pressed(): 68 | var host = WebSocketClient.new() 69 | host.connect_to_url("ws://" + _host_edit.text + ":" + str(DEF_PORT), PoolStringArray([PROTO_NAME]), true) 70 | get_tree().connect("connection_failed", self, "_close_network") 71 | get_tree().connect("connected_to_server", self, "_connected") 72 | get_tree().set_network_peer(host) 73 | start_game() -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LudiDorici/godot-websocket/db42508f8abc580e1c02f690434598cc02d2ed77/screenshot.png -------------------------------------------------------------------------------- /thirdparty/lws/alloc.c: -------------------------------------------------------------------------------- 1 | #include "private-libwebsockets.h" 2 | 3 | #if defined(LWS_PLAT_OPTEE) 4 | 5 | #define TEE_USER_MEM_HINT_NO_FILL_ZERO 0x80000000 6 | 7 | void *__attribute__((weak)) 8 | TEE_Malloc(uint32_t size, uint32_t hint) 9 | { 10 | return NULL; 11 | } 12 | void *__attribute__((weak)) 13 | TEE_Realloc(void *buffer, uint32_t newSize) 14 | { 15 | return NULL; 16 | } 17 | void __attribute__((weak)) 18 | TEE_Free(void *buffer) 19 | { 20 | } 21 | 22 | void *lws_realloc(void *ptr, size_t size, const char *reason) 23 | { 24 | return TEE_Realloc(ptr, size); 25 | } 26 | 27 | void *lws_malloc(size_t size, const char *reason) 28 | { 29 | return TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 30 | } 31 | 32 | void lws_free(void *p) 33 | { 34 | TEE_Free(p); 35 | } 36 | 37 | void *lws_zalloc(size_t size, const char *reason) 38 | { 39 | void *ptr = TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 40 | if (ptr) 41 | memset(ptr, 0, size); 42 | return ptr; 43 | } 44 | 45 | void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason)) 46 | { 47 | (void)cb; 48 | } 49 | #else 50 | 51 | static void *_realloc(void *ptr, size_t size, const char *reason) 52 | { 53 | if (size) { 54 | #if defined(LWS_PLAT_ESP32) 55 | lwsl_notice("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); 56 | #else 57 | lwsl_debug("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); 58 | #endif 59 | #if defined(LWS_PLAT_OPTEE) 60 | return (void *)TEE_Realloc(ptr, size); 61 | #else 62 | return (void *)realloc(ptr, size); 63 | #endif 64 | } 65 | if (ptr) 66 | free(ptr); 67 | 68 | return NULL; 69 | } 70 | 71 | void *(*_lws_realloc)(void *ptr, size_t size, const char *reason) = _realloc; 72 | 73 | void *lws_realloc(void *ptr, size_t size, const char *reason) 74 | { 75 | return _lws_realloc(ptr, size, reason); 76 | } 77 | 78 | void *lws_zalloc(size_t size, const char *reason) 79 | { 80 | void *ptr = _lws_realloc(NULL, size, reason); 81 | if (ptr) 82 | memset(ptr, 0, size); 83 | return ptr; 84 | } 85 | 86 | void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason)) 87 | { 88 | _lws_realloc = cb; 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /thirdparty/lws/ext/extension-permessage-deflate.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER 1 5 | #define DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT Z_DEFAULT_COMPRESSION 6 | 7 | enum arg_indexes { 8 | PMD_SERVER_NO_CONTEXT_TAKEOVER, 9 | PMD_CLIENT_NO_CONTEXT_TAKEOVER, 10 | PMD_SERVER_MAX_WINDOW_BITS, 11 | PMD_CLIENT_MAX_WINDOW_BITS, 12 | PMD_RX_BUF_PWR2, 13 | PMD_TX_BUF_PWR2, 14 | PMD_COMP_LEVEL, 15 | PMD_MEM_LEVEL, 16 | 17 | PMD_ARG_COUNT 18 | }; 19 | 20 | struct lws_ext_pm_deflate_priv { 21 | z_stream rx; 22 | z_stream tx; 23 | 24 | unsigned char *buf_rx_inflated; /* RX inflated output buffer */ 25 | unsigned char *buf_tx_deflated; /* TX deflated output buffer */ 26 | 27 | size_t count_rx_between_fin; 28 | 29 | unsigned char args[PMD_ARG_COUNT]; 30 | unsigned char tx_held[5]; 31 | unsigned char rx_held; 32 | 33 | unsigned char tx_init:1; 34 | unsigned char rx_init:1; 35 | unsigned char compressed_out:1; 36 | unsigned char rx_held_valid:1; 37 | unsigned char tx_held_valid:1; 38 | unsigned char rx_append_trailer:1; 39 | unsigned char pending_tx_trailer:1; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /thirdparty/lws/http2/ssl-http2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets - small server side websockets and web server implementation 3 | * 4 | * Copyright (C) 2010-2017 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | * 21 | * Some or all of this file is based on code from nghttp2, which has the 22 | * following license. Since it's more liberal than lws license, you're also 23 | * at liberty to get the original code from 24 | * https://github.com/tatsuhiro-t/nghttp2 under his liberal terms alone. 25 | * 26 | * nghttp2 - HTTP/2.0 C Library 27 | * 28 | * Copyright (c) 2012 Tatsuhiro Tsujikawa 29 | * 30 | * Permission is hereby granted, free of charge, to any person obtaining 31 | * a copy of this software and associated documentation files (the 32 | * "Software"), to deal in the Software without restriction, including 33 | * without limitation the rights to use, copy, modify, merge, publish, 34 | * distribute, sublicense, and/or sell copies of the Software, and to 35 | * permit persons to whom the Software is furnished to do so, subject to 36 | * the following conditions: 37 | * 38 | * The above copyright notice and this permission notice shall be 39 | * included in all copies or substantial portions of the Software. 40 | * 41 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 42 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 43 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 44 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 45 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 46 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 47 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | */ 49 | 50 | #include "private-libwebsockets.h" 51 | 52 | #if !defined(LWS_NO_SERVER) 53 | #if defined(LWS_OPENSSL_SUPPORT) 54 | 55 | #if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ 56 | OPENSSL_VERSION_NUMBER >= 0x10002000L) 57 | 58 | struct alpn_ctx { 59 | unsigned char *data; 60 | unsigned short len; 61 | }; 62 | 63 | 64 | static int 65 | alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, 66 | const unsigned char *in, unsigned int inlen, void *arg) 67 | { 68 | #if !defined(LWS_WITH_MBEDTLS) 69 | struct alpn_ctx *alpn_ctx = arg; 70 | 71 | if (SSL_select_next_proto((unsigned char **)out, outlen, alpn_ctx->data, 72 | alpn_ctx->len, in, inlen) != 73 | OPENSSL_NPN_NEGOTIATED) 74 | return SSL_TLSEXT_ERR_NOACK; 75 | #endif 76 | return SSL_TLSEXT_ERR_OK; 77 | } 78 | #endif 79 | 80 | LWS_VISIBLE void 81 | lws_context_init_http2_ssl(struct lws_vhost *vhost) 82 | { 83 | #if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ 84 | OPENSSL_VERSION_NUMBER >= 0x10002000L) 85 | static struct alpn_ctx protos = { (unsigned char *)"\x02h2" 86 | "\x08http/1.1", 6 + 9 }; 87 | 88 | SSL_CTX_set_alpn_select_cb(vhost->ssl_ctx, alpn_cb, &protos); 89 | lwsl_notice(" HTTP2 / ALPN enabled\n"); 90 | #else 91 | lwsl_notice( 92 | " HTTP2 / ALPN configured but not supported by OpenSSL 0x%lx\n", 93 | OPENSSL_VERSION_NUMBER); 94 | #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L 95 | } 96 | 97 | int lws_h2_configure_if_upgraded(struct lws *wsi) 98 | { 99 | #if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ 100 | OPENSSL_VERSION_NUMBER >= 0x10002000L) 101 | struct allocated_headers *ah; 102 | const unsigned char *name = NULL; 103 | char cstr[10]; 104 | unsigned len; 105 | 106 | SSL_get0_alpn_selected(wsi->ssl, &name, &len); 107 | if (!len) { 108 | lwsl_info("no ALPN upgrade\n"); 109 | return 0; 110 | } 111 | 112 | if (len > sizeof(cstr) - 1) 113 | len = sizeof(cstr) - 1; 114 | 115 | memcpy(cstr, name, len); 116 | cstr[len] = '\0'; 117 | 118 | lwsl_info("negotiated '%s' using ALPN\n", cstr); 119 | wsi->use_ssl = 1; 120 | if (strncmp((char *)name, "http/1.1", 8) == 0) 121 | return 0; 122 | 123 | /* http2 */ 124 | 125 | wsi->upgraded_to_http2 = 1; 126 | wsi->vhost->conn_stats.h2_alpn++; 127 | 128 | /* adopt the header info */ 129 | 130 | ah = wsi->u.hdr.ah; 131 | 132 | lws_union_transition(wsi, LWSCM_HTTP2_SERVING); 133 | wsi->state = LWSS_HTTP2_AWAIT_CLIENT_PREFACE; 134 | 135 | /* http2 union member has http union struct at start */ 136 | wsi->u.http.ah = ah; 137 | 138 | wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n), "h2n"); 139 | if (!wsi->u.h2.h2n) 140 | return 1; 141 | 142 | lws_h2_init(wsi); 143 | 144 | /* HTTP2 union */ 145 | 146 | lws_hpack_dynamic_size(wsi, wsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); 147 | wsi->u.h2.tx_cr = 65535; 148 | 149 | lwsl_info("%s: wsi %p: configured for h2\n", __func__, wsi); 150 | #endif 151 | return 0; 152 | } 153 | #endif 154 | #endif 155 | -------------------------------------------------------------------------------- /thirdparty/lws/lextable-strings.h: -------------------------------------------------------------------------------- 1 | /* set of parsable strings -- ALL LOWER CASE */ 2 | 3 | #if !defined(STORE_IN_ROM) 4 | #define STORE_IN_ROM 5 | #endif 6 | 7 | STORE_IN_ROM static const char * const set[] = { 8 | "get ", 9 | "post ", 10 | "options ", 11 | "host:", 12 | "connection:", 13 | "upgrade:", 14 | "origin:", 15 | "sec-websocket-draft:", 16 | "\x0d\x0a", 17 | 18 | "sec-websocket-extensions:", 19 | "sec-websocket-key1:", 20 | "sec-websocket-key2:", 21 | "sec-websocket-protocol:", 22 | 23 | "sec-websocket-accept:", 24 | "sec-websocket-nonce:", 25 | "http/1.1 ", 26 | "http2-settings:", 27 | 28 | "accept:", 29 | "access-control-request-headers:", 30 | "if-modified-since:", 31 | "if-none-match:", 32 | "accept-encoding:", 33 | "accept-language:", 34 | "pragma:", 35 | "cache-control:", 36 | "authorization:", 37 | "cookie:", 38 | "content-length:", 39 | "content-type:", 40 | "date:", 41 | "range:", 42 | "referer:", 43 | "sec-websocket-key:", 44 | "sec-websocket-version:", 45 | "sec-websocket-origin:", 46 | 47 | ":authority", 48 | ":method", 49 | ":path", 50 | ":scheme", 51 | ":status", 52 | 53 | "accept-charset:", 54 | "accept-ranges:", 55 | "access-control-allow-origin:", 56 | "age:", 57 | "allow:", 58 | "content-disposition:", 59 | "content-encoding:", 60 | "content-language:", 61 | "content-location:", 62 | "content-range:", 63 | "etag:", 64 | "expect:", 65 | "expires:", 66 | "from:", 67 | "if-match:", 68 | "if-range:", 69 | "if-unmodified-since:", 70 | "last-modified:", 71 | "link:", 72 | "location:", 73 | "max-forwards:", 74 | "proxy-authenticate:", 75 | "proxy-authorization:", 76 | "refresh:", 77 | "retry-after:", 78 | "server:", 79 | "set-cookie:", 80 | "strict-transport-security:", 81 | "transfer-encoding:", 82 | "user-agent:", 83 | "vary:", 84 | "via:", 85 | "www-authenticate:", 86 | 87 | "patch", 88 | "put", 89 | "delete", 90 | 91 | "uri-args", /* fake header used for uri-only storage */ 92 | 93 | "proxy ", 94 | "x-real-ip:", 95 | "http/1.0 ", 96 | 97 | "x-forwarded-for", 98 | "connect ", 99 | "head ", 100 | "te:", /* http/2 wants it to reject it */ 101 | 102 | "", /* not matchable */ 103 | 104 | }; 105 | -------------------------------------------------------------------------------- /thirdparty/lws/lws_config.h: -------------------------------------------------------------------------------- 1 | /* lws_config.h Generated from lws_config.h.in */ 2 | #include "lws_config_private.h" 3 | 4 | #ifndef NDEBUG 5 | #ifndef _DEBUG 6 | #define _DEBUG 7 | #endif 8 | #endif 9 | 10 | #define LWS_INSTALL_DATADIR "/usr/local/share" 11 | 12 | /* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL. 13 | * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ 14 | /* #undef USE_WOLFSSL */ 15 | 16 | /* Also define to 1 (in addition to USE_WOLFSSL) when using the 17 | (older) CyaSSL library */ 18 | /* #undef USE_OLD_CYASSL */ 19 | /* #undef LWS_WITH_BORINGSSL */ 20 | 21 | /* #undef LWS_WITH_MBEDTLS */ 22 | /* #undef LWS_WITH_POLARSSL */ 23 | /* #undef LWS_WITH_ESP8266 */ 24 | /* #undef LWS_WITH_ESP32 */ 25 | 26 | /* #undef LWS_WITH_PLUGINS */ 27 | /* #undef LWS_WITH_NO_LOGS */ 28 | #ifndef DEBUG_ENABLED 29 | #define LWS_WITH_NO_LOGS 30 | #endif 31 | 32 | /* The Libwebsocket version */ 33 | #define LWS_LIBRARY_VERSION "2.4.1" 34 | 35 | #define LWS_LIBRARY_VERSION_MAJOR 2 36 | #define LWS_LIBRARY_VERSION_MINOR 4 37 | #define LWS_LIBRARY_VERSION_PATCH 1 38 | /* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */ 39 | #define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH 40 | 41 | /* The current git commit hash that we're building from */ 42 | #define LWS_BUILD_HASH "55f97b7806e07db2d4c8a158172cd309d0faf450" 43 | 44 | /* Build with OpenSSL support */ 45 | #define LWS_OPENSSL_SUPPORT 46 | 47 | /* The client should load and trust CA root certs it finds in the OS */ 48 | #define LWS_SSL_CLIENT_USE_OS_CA_CERTS 49 | 50 | /* Sets the path where the client certs should be installed. */ 51 | #define LWS_OPENSSL_CLIENT_CERTS "../share" 52 | 53 | /* Turn off websocket extensions */ 54 | /* #undef LWS_NO_EXTENSIONS */ 55 | 56 | /* Enable libev io loop */ 57 | /* #undef LWS_WITH_LIBEV */ 58 | #undef LWS_WITH_LIBEV 59 | 60 | /* Enable libuv io loop */ 61 | /* #undef LWS_WITH_LIBUV */ 62 | #undef LWS_WITH_LIBUV 63 | 64 | /* Enable libevent io loop */ 65 | /* #undef LWS_WITH_LIBEVENT */ 66 | #undef LWS_WITH_LIBEVENT 67 | 68 | /* Build with support for ipv6 */ 69 | /* #undef LWS_WITH_IPV6 */ 70 | 71 | /* Build with support for UNIX domain socket */ 72 | /* #undef LWS_WITH_UNIX_SOCK */ 73 | #ifdef WINDOWS_ENABLED 74 | #undef LWS_USE_UNIX_SOCK 75 | #endif 76 | 77 | /* Build with support for HTTP2 */ 78 | /* #undef LWS_WITH_HTTP2 */ 79 | 80 | /* Turn on latency measuring code */ 81 | /* #undef LWS_LATENCY */ 82 | 83 | /* Don't build the daemonizeation api */ 84 | #define LWS_NO_DAEMONIZE 85 | 86 | /* Build without server support */ 87 | /* #undef LWS_NO_SERVER */ 88 | 89 | /* Build without client support */ 90 | /* #undef LWS_NO_CLIENT */ 91 | 92 | /* If we should compile with MinGW support */ 93 | /* #undef LWS_MINGW_SUPPORT */ 94 | 95 | /* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */ 96 | /* #undef LWS_BUILTIN_GETIFADDRS */ 97 | 98 | /* use SHA1() not internal libwebsockets_SHA1 */ 99 | /* #undef LWS_SHA1_USE_OPENSSL_NAME */ 100 | 101 | /* SSL server using ECDH certificate */ 102 | /* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */ 103 | #define LWS_HAVE_SSL_CTX_set1_param 104 | #define LWS_HAVE_X509_VERIFY_PARAM_set1_host 105 | /* #undef LWS_HAVE_RSA_SET0_KEY */ 106 | 107 | /* #undef LWS_HAVE_UV_VERSION_H */ 108 | 109 | /* CGI apis */ 110 | /* #undef LWS_WITH_CGI */ 111 | 112 | /* whether the Openssl is recent enough, and / or built with, ecdh */ 113 | #define LWS_HAVE_OPENSSL_ECDH_H 114 | 115 | /* HTTP Proxy support */ 116 | /* #undef LWS_WITH_HTTP_PROXY */ 117 | 118 | /* HTTP Ranges support */ 119 | #define LWS_WITH_RANGES 120 | 121 | /* Http access log support */ 122 | /* #undef LWS_WITH_ACCESS_LOG */ 123 | /* #undef LWS_WITH_SERVER_STATUS */ 124 | 125 | /* #undef LWS_WITH_STATEFUL_URLDECODE */ 126 | /* #undef LWS_WITH_PEER_LIMITS */ 127 | 128 | /* Maximum supported service threads */ 129 | #define LWS_MAX_SMP 1 130 | 131 | /* Lightweight JSON Parser */ 132 | /* #undef LWS_WITH_LEJP */ 133 | 134 | /* SMTP */ 135 | /* #undef LWS_WITH_SMTP */ 136 | 137 | /* OPTEE */ 138 | /* #undef LWS_PLAT_OPTEE */ 139 | 140 | /* ZIP FOPS */ 141 | #define LWS_WITH_ZIP_FOPS 142 | #define LWS_HAVE_STDINT_H 143 | 144 | /* #undef LWS_AVOID_SIGPIPE_IGN */ 145 | 146 | /* #undef LWS_FALLBACK_GETHOSTBYNAME */ 147 | 148 | /* #undef LWS_WITH_STATS */ 149 | /* #undef LWS_WITH_SOCKS5 */ 150 | 151 | /* #undef LWS_HAVE_SYS_CAPABILITY_H */ 152 | /* #undef LWS_HAVE_LIBCAP */ 153 | 154 | #define LWS_HAVE_ATOLL 155 | /* #undef LWS_HAVE__ATOI64 */ 156 | /* #undef LWS_HAVE__STAT32I64 */ 157 | 158 | /* OpenSSL various APIs */ 159 | 160 | /* #undef LWS_HAVE_TLS_CLIENT_METHOD */ 161 | #define LWS_HAVE_TLSV1_2_CLIENT_METHOD 162 | #define LWS_HAVE_SSL_SET_INFO_CALLBACK 163 | 164 | #define LWS_HAS_INTPTR_T 165 | 166 | 167 | -------------------------------------------------------------------------------- /thirdparty/lws/lws_config_private.h: -------------------------------------------------------------------------------- 1 | /* lws_config_private.h.in. Private compilation options. */ 2 | #ifndef DEBUG_ENABLED 3 | #define NDEBUG 4 | #endif 5 | 6 | #ifndef NDEBUG 7 | #ifndef _DEBUG 8 | #define _DEBUG 9 | #endif 10 | #endif 11 | 12 | /* Define to 1 to use CyaSSL as a replacement for OpenSSL. 13 | * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ 14 | /* #undef USE_CYASSL */ 15 | 16 | /* Define to 1 if you have the `bzero' function. */ 17 | #define LWS_HAVE_BZERO 18 | /* Windows has no bzero function */ 19 | #ifdef WINDOWS_ENABLED 20 | #undef LWS_HAVE_BZERO 21 | #endif 22 | 23 | /* Define to 1 if you have the header file. */ 24 | #define LWS_HAVE_DLFCN_H 25 | 26 | /* Define to 1 if you have the header file. */ 27 | #define LWS_HAVE_FCNTL_H 28 | #ifdef NO_FCNTL 29 | #undef LWS_HAVE_FCNTL_H 30 | #endif 31 | 32 | /* Define to 1 if you have the `fork' function. */ 33 | #define LWS_HAVE_FORK 34 | 35 | /* Define to 1 if you have the `getenv’ function. */ 36 | #define LWS_HAVE_GETENV 37 | 38 | /* Define to 1 if you have the header file. */ 39 | /* #undef LWS_HAVE_IN6ADDR_H */ 40 | 41 | /* Define to 1 if you have the header file. */ 42 | #define LWS_HAVE_INTTYPES_H 43 | 44 | /* Define to 1 if you have the `ssl' library (-lssl). */ 45 | /* #undef LWS_HAVE_LIBSSL */ 46 | 47 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and 48 | to 0 otherwise. */ 49 | #define LWS_HAVE_MALLOC 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #define LWS_HAVE_MEMORY_H 53 | 54 | /* Define to 1 if you have the `memset' function. */ 55 | #define LWS_HAVE_MEMSET 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #define LWS_HAVE_NETINET_IN_H 59 | 60 | /* Define to 1 if your system has a GNU libc compatible `realloc' function, 61 | and to 0 otherwise. */ 62 | #define LWS_HAVE_REALLOC 63 | 64 | /* Define to 1 if you have the `socket' function. */ 65 | #define LWS_HAVE_SOCKET 66 | 67 | /* Define to 1 if you have the header file. */ 68 | #define LWS_HAVE_STDINT_H 69 | 70 | /* Define to 1 if you have the header file. */ 71 | #define LWS_HAVE_STDLIB_H 72 | 73 | /* Define to 1 if you have the `strerror' function. */ 74 | #define LWS_HAVE_STRERROR 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #define LWS_HAVE_STRINGS_H 78 | 79 | /* Define to 1 if you have the header file. */ 80 | #define LWS_HAVE_STRING_H 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #define LWS_HAVE_SYS_PRCTL_H 84 | #if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) 85 | #undef LWS_HAVE_SYS_PRCTL_H 86 | #endif 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #define LWS_HAVE_SYS_SOCKET_H 90 | 91 | /* Define to 1 if you have the header file. */ 92 | /* #undef LWS_HAVE_SYS_SOCKIO_H */ 93 | 94 | /* Define to 1 if you have the header file. */ 95 | #define LWS_HAVE_SYS_STAT_H 96 | 97 | /* Define to 1 if you have the header file. */ 98 | #define LWS_HAVE_SYS_TYPES_H 99 | 100 | /* Define to 1 if you have the header file. */ 101 | #define LWS_HAVE_UNISTD_H 102 | 103 | /* Define to 1 if you have the `vfork' function. */ 104 | #define LWS_HAVE_VFORK 105 | 106 | /* Define to 1 if you have the header file. */ 107 | /* #undef LWS_HAVE_VFORK_H */ 108 | 109 | /* Define to 1 if `fork' works. */ 110 | #define LWS_HAVE_WORKING_FORK 111 | 112 | /* Define to 1 if `vfork' works. */ 113 | #define LWS_HAVE_WORKING_VFORK 114 | 115 | /* Define to 1 if execvpe() exists */ 116 | #define LWS_HAVE_EXECVPE 117 | 118 | /* Define to 1 if you have the header file. */ 119 | #define LWS_HAVE_ZLIB_H 120 | 121 | #define LWS_HAVE_GETLOADAVG 122 | 123 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 124 | */ 125 | #undef LT_OBJDIR // We're not using libtool 126 | 127 | /* Define to rpl_malloc if the replacement function should be used. */ 128 | /* #undef malloc */ 129 | 130 | /* Define to rpl_realloc if the replacement function should be used. */ 131 | /* #undef realloc */ 132 | 133 | /* Define to 1 if we have getifaddrs */ 134 | #define LWS_HAVE_GETIFADDRS 135 | #if defined(ANDROID_ENABLED) 136 | #undef LWS_HAVE_GETIFADDRS 137 | #define LWS_BUILTIN_GETIFADDRS 138 | #endif 139 | 140 | /* Define if the inline keyword doesn't exist. */ 141 | /* #undef inline */ 142 | 143 | 144 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl3.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL3_H_ 16 | #define _SSL3_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | # define SSL3_AD_CLOSE_NOTIFY 0 23 | # define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ 24 | # define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ 25 | # define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ 26 | # define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ 27 | # define SSL3_AD_NO_CERTIFICATE 41 28 | # define SSL3_AD_BAD_CERTIFICATE 42 29 | # define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 30 | # define SSL3_AD_CERTIFICATE_REVOKED 44 31 | # define SSL3_AD_CERTIFICATE_EXPIRED 45 32 | # define SSL3_AD_CERTIFICATE_UNKNOWN 46 33 | # define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ 34 | 35 | # define SSL3_AL_WARNING 1 36 | # define SSL3_AL_FATAL 2 37 | 38 | #define SSL3_VERSION 0x0300 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_cert.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_CERT_H_ 16 | #define _SSL_CERT_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include "ssl_types.h" 23 | 24 | /** 25 | * @brief create a certification object include private key object according to input certification 26 | * 27 | * @param ic - input certification point 28 | * 29 | * @return certification object point 30 | */ 31 | CERT *__ssl_cert_new(CERT *ic); 32 | 33 | /** 34 | * @brief create a certification object include private key object 35 | * 36 | * @param none 37 | * 38 | * @return certification object point 39 | */ 40 | CERT* ssl_cert_new(void); 41 | 42 | /** 43 | * @brief free a certification object 44 | * 45 | * @param cert - certification object point 46 | * 47 | * @return none 48 | */ 49 | void ssl_cert_free(CERT *cert); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_code.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_CODE_H_ 16 | #define _SSL_CODE_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include "ssl3.h" 23 | #include "tls1.h" 24 | #include "x509_vfy.h" 25 | 26 | /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ 27 | # define SSL_SENT_SHUTDOWN 1 28 | # define SSL_RECEIVED_SHUTDOWN 2 29 | 30 | # define SSL_VERIFY_NONE 0x00 31 | # define SSL_VERIFY_PEER 0x01 32 | # define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 33 | # define SSL_VERIFY_CLIENT_ONCE 0x04 34 | 35 | /* 36 | * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you 37 | * should not need these 38 | */ 39 | # define SSL_ST_READ_HEADER 0xF0 40 | # define SSL_ST_READ_BODY 0xF1 41 | # define SSL_ST_READ_DONE 0xF2 42 | 43 | # define SSL_NOTHING 1 44 | # define SSL_WRITING 2 45 | # define SSL_READING 3 46 | # define SSL_X509_LOOKUP 4 47 | # define SSL_ASYNC_PAUSED 5 48 | # define SSL_ASYNC_NO_JOBS 6 49 | 50 | 51 | # define SSL_ERROR_NONE 0 52 | # define SSL_ERROR_SSL 1 53 | # define SSL_ERROR_WANT_READ 2 54 | # define SSL_ERROR_WANT_WRITE 3 55 | # define SSL_ERROR_WANT_X509_LOOKUP 4 56 | # define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */ 57 | # define SSL_ERROR_ZERO_RETURN 6 58 | # define SSL_ERROR_WANT_CONNECT 7 59 | # define SSL_ERROR_WANT_ACCEPT 8 60 | # define SSL_ERROR_WANT_ASYNC 9 61 | # define SSL_ERROR_WANT_ASYNC_JOB 10 62 | 63 | /* Message flow states */ 64 | typedef enum { 65 | /* No handshake in progress */ 66 | MSG_FLOW_UNINITED, 67 | /* A permanent error with this connection */ 68 | MSG_FLOW_ERROR, 69 | /* We are about to renegotiate */ 70 | MSG_FLOW_RENEGOTIATE, 71 | /* We are reading messages */ 72 | MSG_FLOW_READING, 73 | /* We are writing messages */ 74 | MSG_FLOW_WRITING, 75 | /* Handshake has finished */ 76 | MSG_FLOW_FINISHED 77 | } MSG_FLOW_STATE; 78 | 79 | /* SSL subsystem states */ 80 | typedef enum { 81 | TLS_ST_BEFORE, 82 | TLS_ST_OK, 83 | DTLS_ST_CR_HELLO_VERIFY_REQUEST, 84 | TLS_ST_CR_SRVR_HELLO, 85 | TLS_ST_CR_CERT, 86 | TLS_ST_CR_CERT_STATUS, 87 | TLS_ST_CR_KEY_EXCH, 88 | TLS_ST_CR_CERT_REQ, 89 | TLS_ST_CR_SRVR_DONE, 90 | TLS_ST_CR_SESSION_TICKET, 91 | TLS_ST_CR_CHANGE, 92 | TLS_ST_CR_FINISHED, 93 | TLS_ST_CW_CLNT_HELLO, 94 | TLS_ST_CW_CERT, 95 | TLS_ST_CW_KEY_EXCH, 96 | TLS_ST_CW_CERT_VRFY, 97 | TLS_ST_CW_CHANGE, 98 | TLS_ST_CW_NEXT_PROTO, 99 | TLS_ST_CW_FINISHED, 100 | TLS_ST_SW_HELLO_REQ, 101 | TLS_ST_SR_CLNT_HELLO, 102 | DTLS_ST_SW_HELLO_VERIFY_REQUEST, 103 | TLS_ST_SW_SRVR_HELLO, 104 | TLS_ST_SW_CERT, 105 | TLS_ST_SW_KEY_EXCH, 106 | TLS_ST_SW_CERT_REQ, 107 | TLS_ST_SW_SRVR_DONE, 108 | TLS_ST_SR_CERT, 109 | TLS_ST_SR_KEY_EXCH, 110 | TLS_ST_SR_CERT_VRFY, 111 | TLS_ST_SR_NEXT_PROTO, 112 | TLS_ST_SR_CHANGE, 113 | TLS_ST_SR_FINISHED, 114 | TLS_ST_SW_SESSION_TICKET, 115 | TLS_ST_SW_CERT_STATUS, 116 | TLS_ST_SW_CHANGE, 117 | TLS_ST_SW_FINISHED 118 | } OSSL_HANDSHAKE_STATE; 119 | 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_lib.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_LIB_H_ 16 | #define _SSL_LIB_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include "ssl_types.h" 23 | 24 | void _ssl_set_alpn_list(const SSL *ssl); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_methods.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_METHODS_H_ 16 | #define _SSL_METHODS_H_ 17 | 18 | #include "ssl_types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | /** 25 | * TLS method function implement 26 | */ 27 | #define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ 28 | new, free, \ 29 | handshake, shutdown, clear, \ 30 | read, send, pending, \ 31 | set_fd, get_fd, \ 32 | set_bufflen, \ 33 | get_verify_result, \ 34 | get_state) \ 35 | static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ 36 | new, \ 37 | free, \ 38 | handshake, \ 39 | shutdown, \ 40 | clear, \ 41 | read, \ 42 | send, \ 43 | pending, \ 44 | set_fd, \ 45 | get_fd, \ 46 | set_bufflen, \ 47 | get_verify_result, \ 48 | get_state \ 49 | }; 50 | 51 | #define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ 52 | const SSL_METHOD* func_name(void) { \ 53 | static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ 54 | ver, \ 55 | mode, \ 56 | &(fun), \ 57 | }; \ 58 | return &func_name##_data; \ 59 | } 60 | 61 | #define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ 62 | const SSL_METHOD* func_name(void) { \ 63 | static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ 64 | ver, \ 65 | mode, \ 66 | &(fun), \ 67 | }; \ 68 | return &func_name##_data; \ 69 | } 70 | 71 | #define IMPLEMENT_X509_METHOD(func_name, \ 72 | new, \ 73 | free, \ 74 | load, \ 75 | show_info) \ 76 | const X509_METHOD* func_name(void) { \ 77 | static const X509_METHOD func_name##_data LOCAL_ATRR = { \ 78 | new, \ 79 | free, \ 80 | load, \ 81 | show_info \ 82 | }; \ 83 | return &func_name##_data; \ 84 | } 85 | 86 | #define IMPLEMENT_PKEY_METHOD(func_name, \ 87 | new, \ 88 | free, \ 89 | load) \ 90 | const PKEY_METHOD* func_name(void) { \ 91 | static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \ 92 | new, \ 93 | free, \ 94 | load \ 95 | }; \ 96 | return &func_name##_data; \ 97 | } 98 | 99 | /** 100 | * @brief get X509 object method 101 | * 102 | * @param none 103 | * 104 | * @return X509 object method point 105 | */ 106 | const X509_METHOD* X509_method(void); 107 | 108 | /** 109 | * @brief get private key object method 110 | * 111 | * @param none 112 | * 113 | * @return private key object method point 114 | */ 115 | const PKEY_METHOD* EVP_PKEY_method(void); 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_pkey.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_PKEY_H_ 16 | #define _SSL_PKEY_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include "ssl_types.h" 23 | 24 | /** 25 | * @brief create a private key object according to input private key 26 | * 27 | * @param ipk - input private key point 28 | * 29 | * @return new private key object point 30 | */ 31 | EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk); 32 | 33 | /** 34 | * @brief create a private key object 35 | * 36 | * @param none 37 | * 38 | * @return private key object point 39 | */ 40 | EVP_PKEY* EVP_PKEY_new(void); 41 | 42 | /** 43 | * @brief load a character key context into system context. If '*a' is pointed to the 44 | * private key, then load key into it. Or create a new private key object 45 | * 46 | * @param type - private key type 47 | * @param a - a point pointed to a private key point 48 | * @param pp - a point pointed to the key context memory point 49 | * @param length - key bytes 50 | * 51 | * @return private key object point 52 | */ 53 | EVP_PKEY* d2i_PrivateKey(int type, 54 | EVP_PKEY **a, 55 | const unsigned char **pp, 56 | long length); 57 | 58 | /** 59 | * @brief free a private key object 60 | * 61 | * @param pkey - private key object point 62 | * 63 | * @return none 64 | */ 65 | void EVP_PKEY_free(EVP_PKEY *x); 66 | 67 | /** 68 | * @brief load private key into the SSL 69 | * 70 | * @param type - private key type 71 | * @param ssl - SSL point 72 | * @param len - data bytes 73 | * @param d - data point 74 | * 75 | * @return result 76 | * 0 : failed 77 | * 1 : OK 78 | */ 79 | int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len); 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_stack.h: -------------------------------------------------------------------------------- 1 | #ifndef _SSL_STACK_H_ 2 | #define _SSL_STACK_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "ssl_types.h" 9 | 10 | #define STACK_OF(type) struct stack_st_##type 11 | 12 | #define SKM_DEFINE_STACK_OF(t1, t2, t3) \ 13 | STACK_OF(t1); \ 14 | static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ 15 | { \ 16 | return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ 17 | } \ 18 | 19 | #define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) 20 | 21 | /** 22 | * @brief create a openssl stack object 23 | * 24 | * @param c - stack function 25 | * 26 | * @return openssl stack object point 27 | */ 28 | OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c); 29 | 30 | /** 31 | * @brief create a NULL function openssl stack object 32 | * 33 | * @param none 34 | * 35 | * @return openssl stack object point 36 | */ 37 | OPENSSL_STACK *OPENSSL_sk_new_null(void); 38 | 39 | /** 40 | * @brief free openssl stack object 41 | * 42 | * @param openssl stack object point 43 | * 44 | * @return none 45 | */ 46 | void OPENSSL_sk_free(OPENSSL_STACK *stack); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/ssl_x509.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_X509_H_ 16 | #define _SSL_X509_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include "ssl_types.h" 23 | #include "ssl_stack.h" 24 | 25 | DEFINE_STACK_OF(X509_NAME) 26 | 27 | /** 28 | * @brief create a X509 certification object according to input X509 certification 29 | * 30 | * @param ix - input X509 certification point 31 | * 32 | * @return new X509 certification object point 33 | */ 34 | X509* __X509_new(X509 *ix); 35 | 36 | /** 37 | * @brief create a X509 certification object 38 | * 39 | * @param none 40 | * 41 | * @return X509 certification object point 42 | */ 43 | X509* X509_new(void); 44 | 45 | /** 46 | * @brief load a character certification context into system context. If '*cert' is pointed to the 47 | * certification, then load certification into it. Or create a new X509 certification object 48 | * 49 | * @param cert - a point pointed to X509 certification 50 | * @param buffer - a point pointed to the certification context memory point 51 | * @param length - certification bytes 52 | * 53 | * @return X509 certification object point 54 | */ 55 | X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); 56 | 57 | /** 58 | * @brief free a X509 certification object 59 | * 60 | * @param x - X509 certification object point 61 | * 62 | * @return none 63 | */ 64 | void X509_free(X509 *x); 65 | 66 | /** 67 | * @brief set SSL context client CA certification 68 | * 69 | * @param ctx - SSL context point 70 | * @param x - X509 certification point 71 | * 72 | * @return result 73 | * 0 : failed 74 | * 1 : OK 75 | */ 76 | int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); 77 | 78 | /** 79 | * @brief add CA client certification into the SSL 80 | * 81 | * @param ssl - SSL point 82 | * @param x - X509 certification point 83 | * 84 | * @return result 85 | * 0 : failed 86 | * 1 : OK 87 | */ 88 | int SSL_add_client_CA(SSL *ssl, X509 *x); 89 | 90 | /** 91 | * @brief load certification into the SSL 92 | * 93 | * @param ssl - SSL point 94 | * @param len - data bytes 95 | * @param d - data point 96 | * 97 | * @return result 98 | * 0 : failed 99 | * 1 : OK 100 | * 101 | */ 102 | int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); 103 | 104 | const char *X509_verify_cert_error_string(long n); 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/internal/tls1.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _TLS1_H_ 16 | #define _TLS1_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | # define TLS1_AD_DECRYPTION_FAILED 21 23 | # define TLS1_AD_RECORD_OVERFLOW 22 24 | # define TLS1_AD_UNKNOWN_CA 48/* fatal */ 25 | # define TLS1_AD_ACCESS_DENIED 49/* fatal */ 26 | # define TLS1_AD_DECODE_ERROR 50/* fatal */ 27 | # define TLS1_AD_DECRYPT_ERROR 51 28 | # define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ 29 | # define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ 30 | # define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ 31 | # define TLS1_AD_INTERNAL_ERROR 80/* fatal */ 32 | # define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ 33 | # define TLS1_AD_USER_CANCELLED 90 34 | # define TLS1_AD_NO_RENEGOTIATION 100 35 | /* codes 110-114 are from RFC3546 */ 36 | # define TLS1_AD_UNSUPPORTED_EXTENSION 110 37 | # define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 38 | # define TLS1_AD_UNRECOGNIZED_NAME 112 39 | # define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 40 | # define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 41 | # define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ 42 | # define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ 43 | 44 | /* Special value for method supporting multiple versions */ 45 | #define TLS_ANY_VERSION 0x10000 46 | 47 | #define TLS1_VERSION 0x0301 48 | #define TLS1_1_VERSION 0x0302 49 | #define TLS1_2_VERSION 0x0303 50 | 51 | #define SSL_TLSEXT_ERR_OK 0 52 | #define SSL_TLSEXT_ERR_NOACK 3 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/platform/ssl_pm.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_PM_H_ 16 | #define _SSL_PM_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "ssl_types.h" 24 | #include "ssl_port.h" 25 | 26 | #define LOCAL_ATRR 27 | 28 | int ssl_pm_new(SSL *ssl); 29 | void ssl_pm_free(SSL *ssl); 30 | 31 | int ssl_pm_handshake(SSL *ssl); 32 | int ssl_pm_shutdown(SSL *ssl); 33 | int ssl_pm_clear(SSL *ssl); 34 | 35 | int ssl_pm_read(SSL *ssl, void *buffer, int len); 36 | int ssl_pm_send(SSL *ssl, const void *buffer, int len); 37 | int ssl_pm_pending(const SSL *ssl); 38 | 39 | void ssl_pm_set_fd(SSL *ssl, int fd, int mode); 40 | int ssl_pm_get_fd(const SSL *ssl, int mode); 41 | 42 | OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); 43 | 44 | void ssl_pm_set_bufflen(SSL *ssl, int len); 45 | 46 | int x509_pm_show_info(X509 *x); 47 | int x509_pm_new(X509 *x, X509 *m_x); 48 | void x509_pm_free(X509 *x); 49 | int x509_pm_load(X509 *x, const unsigned char *buffer, int len); 50 | 51 | int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk); 52 | void pkey_pm_free(EVP_PKEY *pk); 53 | int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len); 54 | 55 | long ssl_pm_get_verify_result(const SSL *ssl); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _SSL_PORT_H_ 16 | #define _SSL_PORT_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /* 23 | #include "esp_types.h" 24 | #include "esp_log.h" 25 | */ 26 | #include "string.h" 27 | #include "malloc.h" 28 | 29 | void *ssl_mem_zalloc(size_t size); 30 | 31 | #define ssl_mem_malloc malloc 32 | #define ssl_mem_free free 33 | 34 | #define ssl_memcpy memcpy 35 | #define ssl_strlen strlen 36 | 37 | #define ssl_speed_up_enter() 38 | #define ssl_speed_up_exit() 39 | 40 | #define SSL_DEBUG_FL 41 | #define SSL_DEBUG_LOG(fmt, ...) ESP_LOGI("openssl", fmt, ##__VA_ARGS__) 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/library/ssl_cert.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ssl_cert.h" 16 | #include "ssl_pkey.h" 17 | #include "ssl_x509.h" 18 | #include "ssl_dbg.h" 19 | #include "ssl_port.h" 20 | 21 | /** 22 | * @brief create a certification object according to input certification 23 | */ 24 | CERT *__ssl_cert_new(CERT *ic) 25 | { 26 | CERT *cert; 27 | 28 | X509 *ix; 29 | EVP_PKEY *ipk; 30 | 31 | cert = ssl_mem_zalloc(sizeof(CERT)); 32 | if (!cert) { 33 | SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "no enough memory > (cert)"); 34 | goto no_mem; 35 | } 36 | 37 | if (ic) { 38 | ipk = ic->pkey; 39 | ix = ic->x509; 40 | } else { 41 | ipk = NULL; 42 | ix = NULL; 43 | } 44 | 45 | cert->pkey = __EVP_PKEY_new(ipk); 46 | if (!cert->pkey) { 47 | SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__EVP_PKEY_new() return NULL"); 48 | goto pkey_err; 49 | } 50 | 51 | cert->x509 = __X509_new(ix); 52 | if (!cert->x509) { 53 | SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__X509_new() return NULL"); 54 | goto x509_err; 55 | } 56 | 57 | return cert; 58 | 59 | x509_err: 60 | EVP_PKEY_free(cert->pkey); 61 | pkey_err: 62 | ssl_mem_free(cert); 63 | no_mem: 64 | return NULL; 65 | } 66 | 67 | /** 68 | * @brief create a certification object include private key object 69 | */ 70 | CERT *ssl_cert_new(void) 71 | { 72 | return __ssl_cert_new(NULL); 73 | } 74 | 75 | /** 76 | * @brief free a certification object 77 | */ 78 | void ssl_cert_free(CERT *cert) 79 | { 80 | SSL_ASSERT3(cert); 81 | 82 | X509_free(cert->x509); 83 | 84 | EVP_PKEY_free(cert->pkey); 85 | 86 | ssl_mem_free(cert); 87 | } 88 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/library/ssl_methods.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ssl_methods.h" 16 | #include "ssl_pm.h" 17 | 18 | /** 19 | * TLS method function collection 20 | */ 21 | IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, 22 | ssl_pm_new, ssl_pm_free, 23 | ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear, 24 | ssl_pm_read, ssl_pm_send, ssl_pm_pending, 25 | ssl_pm_set_fd, ssl_pm_get_fd, 26 | ssl_pm_set_bufflen, 27 | ssl_pm_get_verify_result, 28 | ssl_pm_get_state); 29 | 30 | /** 31 | * TLS or SSL client method collection 32 | */ 33 | IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); 34 | 35 | IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method); 36 | 37 | IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method); 38 | 39 | IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); 40 | 41 | IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); 42 | 43 | /** 44 | * TLS or SSL server method collection 45 | */ 46 | IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); 47 | 48 | IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method); 49 | 50 | IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method); 51 | 52 | IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); 53 | 54 | IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); 55 | 56 | /** 57 | * TLS or SSL method collection 58 | */ 59 | IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); 60 | 61 | IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method); 62 | 63 | IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method); 64 | 65 | IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); 66 | 67 | IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); 68 | 69 | /** 70 | * @brief get X509 object method 71 | */ 72 | IMPLEMENT_X509_METHOD(X509_method, 73 | x509_pm_new, x509_pm_free, 74 | x509_pm_load, x509_pm_show_info); 75 | 76 | /** 77 | * @brief get private key object method 78 | */ 79 | IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, 80 | pkey_pm_new, pkey_pm_free, 81 | pkey_pm_load); 82 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/library/ssl_pkey.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ssl_pkey.h" 16 | #include "ssl_methods.h" 17 | #include "ssl_dbg.h" 18 | #include "ssl_port.h" 19 | 20 | /** 21 | * @brief create a private key object according to input private key 22 | */ 23 | EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) 24 | { 25 | int ret; 26 | EVP_PKEY *pkey; 27 | 28 | pkey = ssl_mem_zalloc(sizeof(EVP_PKEY)); 29 | if (!pkey) { 30 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)"); 31 | goto no_mem; 32 | } 33 | 34 | if (ipk) { 35 | pkey->method = ipk->method; 36 | } else { 37 | pkey->method = EVP_PKEY_method(); 38 | } 39 | 40 | ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk); 41 | if (ret) { 42 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret); 43 | goto failed; 44 | } 45 | 46 | return pkey; 47 | 48 | failed: 49 | ssl_mem_free(pkey); 50 | no_mem: 51 | return NULL; 52 | } 53 | 54 | /** 55 | * @brief create a private key object 56 | */ 57 | EVP_PKEY* EVP_PKEY_new(void) 58 | { 59 | return __EVP_PKEY_new(NULL); 60 | } 61 | 62 | /** 63 | * @brief free a private key object 64 | */ 65 | void EVP_PKEY_free(EVP_PKEY *pkey) 66 | { 67 | SSL_ASSERT3(pkey); 68 | 69 | EVP_PKEY_METHOD_CALL(free, pkey); 70 | 71 | ssl_mem_free(pkey); 72 | } 73 | 74 | /** 75 | * @brief load a character key context into system context. If '*a' is pointed to the 76 | * private key, then load key into it. Or create a new private key object 77 | */ 78 | EVP_PKEY *d2i_PrivateKey(int type, 79 | EVP_PKEY **a, 80 | const unsigned char **pp, 81 | long length) 82 | { 83 | int m = 0; 84 | int ret; 85 | EVP_PKEY *pkey; 86 | 87 | SSL_ASSERT2(pp); 88 | SSL_ASSERT2(*pp); 89 | SSL_ASSERT2(length); 90 | 91 | if (a && *a) { 92 | pkey = *a; 93 | } else { 94 | pkey = EVP_PKEY_new();; 95 | if (!pkey) { 96 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL"); 97 | goto failed1; 98 | } 99 | 100 | m = 1; 101 | } 102 | 103 | ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); 104 | if (ret) { 105 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret); 106 | goto failed2; 107 | } 108 | 109 | if (a) 110 | *a = pkey; 111 | 112 | return pkey; 113 | 114 | failed2: 115 | if (m) 116 | EVP_PKEY_free(pkey); 117 | failed1: 118 | return NULL; 119 | } 120 | 121 | /** 122 | * @brief set the SSL context private key 123 | */ 124 | int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) 125 | { 126 | SSL_ASSERT1(ctx); 127 | SSL_ASSERT1(pkey); 128 | 129 | if (ctx->cert->pkey == pkey) 130 | return 1; 131 | 132 | if (ctx->cert->pkey) 133 | EVP_PKEY_free(ctx->cert->pkey); 134 | 135 | ctx->cert->pkey = pkey; 136 | 137 | return 1; 138 | } 139 | 140 | /** 141 | * @brief set the SSL private key 142 | */ 143 | int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) 144 | { 145 | SSL_ASSERT1(ssl); 146 | SSL_ASSERT1(pkey); 147 | 148 | if (ssl->cert->pkey == pkey) 149 | return 1; 150 | 151 | if (ssl->cert->pkey) 152 | EVP_PKEY_free(ssl->cert->pkey); 153 | 154 | ssl->cert->pkey = pkey; 155 | 156 | return 1; 157 | } 158 | 159 | /** 160 | * @brief load private key into the SSL context 161 | */ 162 | int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, 163 | const unsigned char *d, long len) 164 | { 165 | int ret; 166 | EVP_PKEY *pk; 167 | 168 | pk = d2i_PrivateKey(0, NULL, &d, len); 169 | if (!pk) { 170 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); 171 | goto failed1; 172 | } 173 | 174 | ret = SSL_CTX_use_PrivateKey(ctx, pk); 175 | if (!ret) { 176 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret); 177 | goto failed2; 178 | } 179 | 180 | return 1; 181 | 182 | failed2: 183 | EVP_PKEY_free(pk); 184 | failed1: 185 | return 0; 186 | } 187 | 188 | /** 189 | * @brief load private key into the SSL 190 | */ 191 | int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, 192 | const unsigned char *d, long len) 193 | { 194 | int ret; 195 | EVP_PKEY *pk; 196 | 197 | pk = d2i_PrivateKey(0, NULL, &d, len); 198 | if (!pk) { 199 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); 200 | goto failed1; 201 | } 202 | 203 | ret = SSL_use_PrivateKey(ssl, pk); 204 | if (!ret) { 205 | SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret); 206 | goto failed2; 207 | } 208 | 209 | return 1; 210 | 211 | failed2: 212 | EVP_PKEY_free(pk); 213 | failed1: 214 | return 0; 215 | } 216 | 217 | /** 218 | * @brief load the private key file into SSL context 219 | */ 220 | int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 221 | { 222 | return 0; 223 | } 224 | 225 | /** 226 | * @brief load the private key file into SSL 227 | */ 228 | int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 229 | { 230 | return 0; 231 | } 232 | 233 | /** 234 | * @brief load the RSA ASN1 private key into SSL context 235 | */ 236 | int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) 237 | { 238 | return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len); 239 | } 240 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/library/ssl_stack.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ssl_stack.h" 16 | #include "ssl_dbg.h" 17 | #include "ssl_port.h" 18 | 19 | #ifndef CONFIG_MIN_NODES 20 | #define MIN_NODES 4 21 | #else 22 | #define MIN_NODES CONFIG_MIN_NODES 23 | #endif 24 | 25 | /** 26 | * @brief create a openssl stack object 27 | */ 28 | OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) 29 | { 30 | OPENSSL_STACK *stack; 31 | char **data; 32 | 33 | stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK)); 34 | if (!stack) { 35 | SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (stack)"); 36 | goto no_mem1; 37 | } 38 | 39 | data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES); 40 | if (!data) { 41 | SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (data)"); 42 | goto no_mem2; 43 | } 44 | 45 | stack->data = data; 46 | stack->num_alloc = MIN_NODES; 47 | stack->c = c; 48 | 49 | return stack; 50 | 51 | no_mem2: 52 | ssl_mem_free(stack); 53 | no_mem1: 54 | return NULL; 55 | } 56 | 57 | /** 58 | * @brief create a NULL function openssl stack object 59 | */ 60 | OPENSSL_STACK *OPENSSL_sk_new_null(void) 61 | { 62 | return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL); 63 | } 64 | 65 | /** 66 | * @brief free openssl stack object 67 | */ 68 | void OPENSSL_sk_free(OPENSSL_STACK *stack) 69 | { 70 | SSL_ASSERT3(stack); 71 | 72 | ssl_mem_free(stack->data); 73 | ssl_mem_free(stack); 74 | } 75 | -------------------------------------------------------------------------------- /thirdparty/lws/mbedtls_wrapper/platform/ssl_port.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ssl_port.h" 16 | 17 | /*********************************************************************************************/ 18 | /********************************* SSL general interface *************************************/ 19 | 20 | void *ssl_mem_zalloc(size_t size) 21 | { 22 | void *p = malloc(size); 23 | 24 | if (p) 25 | memset(p, 0, size); 26 | 27 | return p; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /thirdparty/lws/minilex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * minilex.c 3 | * 4 | * High efficiency lexical state parser 5 | * 6 | * Copyright (C)2011-2014 Andy Green 7 | * 8 | * Licensed under LGPL2 9 | * 10 | * Usage: gcc minilex.c -o minilex && ./minilex > lextable.h 11 | * 12 | * Run it twice to test parsing on the generated table on stderr 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "lextable-strings.h" 20 | 21 | /* 22 | * b7 = 0 = 1-byte seq 23 | * 0x08 = fail 24 | * 2-byte seq 25 | * 0x00 - 0x07, then terminal as given in 2nd byte 26 | 3-byte seq 27 | * no match: go fwd 3 byte, match: jump fwd by amt in +1/+2 bytes 28 | * = 1 = 1-byte seq 29 | * no match: die, match go fwd 1 byte 30 | */ 31 | 32 | unsigned char lextable[] = { 33 | #include "lextable.h" 34 | }; 35 | 36 | #define PARALLEL 30 37 | 38 | struct state { 39 | char c[PARALLEL]; 40 | int state[PARALLEL]; 41 | int count; 42 | int bytepos; 43 | 44 | int real_pos; 45 | }; 46 | 47 | struct state state[1000]; 48 | int next = 1; 49 | 50 | #define FAIL_CHAR 0x08 51 | 52 | int lextable_decode(int pos, char c) 53 | { 54 | while (1) { 55 | if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */ 56 | if ((lextable[pos] & 0x7f) != c) 57 | return -1; 58 | /* fall thru */ 59 | pos++; 60 | if (lextable[pos] == FAIL_CHAR) 61 | return -1; 62 | return pos; 63 | } else { /* b7 = 0, end or 3-byte */ 64 | if (lextable[pos] < FAIL_CHAR) /* terminal marker */ 65 | return pos; 66 | 67 | if (lextable[pos] == c) /* goto */ 68 | return pos + (lextable[pos + 1]) + 69 | (lextable[pos + 2] << 8); 70 | /* fall thru goto */ 71 | pos += 3; 72 | /* continue */ 73 | } 74 | } 75 | } 76 | 77 | int main(void) 78 | { 79 | int n = 0; 80 | int m = 0; 81 | int prev; 82 | char c; 83 | int walk; 84 | int saw; 85 | int y; 86 | int j; 87 | int pos = 0; 88 | 89 | while (n < sizeof(set) / sizeof(set[0])) { 90 | 91 | m = 0; 92 | walk = 0; 93 | prev = 0; 94 | 95 | if (set[n][0] == '\0') { 96 | n++; 97 | continue; 98 | } 99 | 100 | while (set[n][m]) { 101 | 102 | saw = 0; 103 | for (y = 0; y < state[walk].count; y++) 104 | if (state[walk].c[y] == set[n][m]) { 105 | /* exists -- go forward */ 106 | walk = state[walk].state[y]; 107 | saw = 1; 108 | break; 109 | } 110 | 111 | if (saw) 112 | goto again; 113 | 114 | /* something we didn't see before */ 115 | 116 | state[walk].c[state[walk].count] = set[n][m]; 117 | 118 | state[walk].state[state[walk].count] = next; 119 | state[walk].count++; 120 | walk = next++; 121 | again: 122 | m++; 123 | } 124 | 125 | state[walk].c[0] = n++; 126 | state[walk].state[0] = 0; /* terminal marker */ 127 | state[walk].count = 1; 128 | } 129 | 130 | walk = 0; 131 | for (n = 0; n < next; n++) { 132 | state[n].bytepos = walk; 133 | walk += (2 * state[n].count); 134 | } 135 | 136 | /* compute everyone's position first */ 137 | 138 | pos = 0; 139 | walk = 0; 140 | for (n = 0; n < next; n++) { 141 | 142 | state[n].real_pos = pos; 143 | 144 | for (m = 0; m < state[n].count; m++) { 145 | 146 | if (state[n].state[m] == 0) 147 | pos += 2; /* terminal marker */ 148 | else { /* c is a character */ 149 | if ((state[state[n].state[m]].bytepos - 150 | walk) == 2) 151 | pos++; 152 | else { 153 | pos += 3; 154 | if (m == state[n].count - 1) 155 | pos++; /* fail */ 156 | } 157 | } 158 | walk += 2; 159 | } 160 | } 161 | 162 | walk = 0; 163 | pos = 0; 164 | for (n = 0; n < next; n++) { 165 | for (m = 0; m < state[n].count; m++) { 166 | 167 | if (!m) 168 | fprintf(stdout, "/* pos %04x: %3d */ ", 169 | state[n].real_pos, n); 170 | else 171 | fprintf(stdout, " "); 172 | 173 | y = state[n].c[m]; 174 | saw = state[n].state[m]; 175 | 176 | if (saw == 0) { // c is a terminal then 177 | 178 | if (y > 0x7ff) { 179 | fprintf(stderr, "terminal too big\n"); 180 | return 2; 181 | } 182 | 183 | fprintf(stdout, " 0x%02X, 0x%02X " 184 | " " 185 | "/* - terminal marker %2d - */,\n", 186 | y >> 8, y & 0xff, y & 0x7f); 187 | pos += 2; 188 | walk += 2; 189 | continue; 190 | } 191 | 192 | /* c is a character */ 193 | 194 | prev = y &0x7f; 195 | if (prev < 32 || prev > 126) 196 | prev = '.'; 197 | 198 | 199 | if ((state[saw].bytepos - walk) == 2) { 200 | fprintf(stdout, " 0x%02X /* '%c' -> */,\n", 201 | y | 0x80, prev); 202 | pos++; 203 | walk += 2; 204 | continue; 205 | } 206 | 207 | j = state[saw].real_pos - pos; 208 | 209 | if (j > 0xffff) { 210 | fprintf(stderr, 211 | "Jump > 64K bytes ahead (%d to %d)\n", 212 | state[n].real_pos, state[saw].real_pos); 213 | return 1; 214 | } 215 | fprintf(stdout, " 0x%02X /* '%c' */, 0x%02X, 0x%02X " 216 | "/* (to 0x%04X state %3d) */,\n", 217 | y, prev, 218 | j & 0xff, j >> 8, 219 | state[saw].real_pos, saw); 220 | pos += 3; 221 | 222 | if (m == state[n].count - 1) { 223 | fprintf(stdout, 224 | " 0x%02X, /* fail */\n", 225 | FAIL_CHAR); 226 | pos++; /* fail */ 227 | } 228 | 229 | walk += 2; 230 | } 231 | } 232 | 233 | fprintf(stdout, "/* total size %d bytes */\n", pos); 234 | 235 | /* 236 | * Try to parse every legal input string 237 | */ 238 | 239 | for (n = 0; n < sizeof(set) / sizeof(set[0]); n++) { 240 | walk = 0; 241 | m = 0; 242 | y = -1; 243 | 244 | if (set[n][0] == '\0') 245 | continue; 246 | 247 | fprintf(stderr, " trying '%s'\n", set[n]); 248 | 249 | while (set[n][m]) { 250 | walk = lextable_decode(walk, set[n][m]); 251 | if (walk < 0) { 252 | fprintf(stderr, "failed\n"); 253 | return 3; 254 | } 255 | 256 | if (lextable[walk] < FAIL_CHAR) { 257 | y = (lextable[walk] << 8) + lextable[walk + 1]; 258 | break; 259 | } 260 | m++; 261 | } 262 | 263 | if (y != n) { 264 | fprintf(stderr, "decode failed %d\n", y); 265 | return 4; 266 | } 267 | } 268 | 269 | fprintf(stderr, "All decode OK\n"); 270 | 271 | return 0; 272 | } 273 | -------------------------------------------------------------------------------- /thirdparty/lws/misc/getifaddrs.h: -------------------------------------------------------------------------------- 1 | #ifndef LWS_HAVE_GETIFADDRS 2 | #define LWS_HAVE_GETIFADDRS 0 3 | #endif 4 | 5 | #if LWS_HAVE_GETIFADDRS 6 | #include 7 | #include 8 | #else 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | /* 13 | * Copyright (c) 2000 Kungliga Tekniska H�gskolan 14 | * (Royal Institute of Technology, Stockholm, Sweden). 15 | * All rights reserved. 16 | * 17 | * Redistribution and use in source and binary forms, with or without 18 | * modification, are permitted provided that the following conditions 19 | * are met: 20 | * 21 | * 1. Redistributions of source code must retain the above copyright 22 | * notice, this list of conditions and the following disclaimer. 23 | * 24 | * 2. Redistributions in binary form must reproduce the above copyright 25 | * notice, this list of conditions and the following disclaimer in the 26 | * documentation and/or other materials provided with the distribution. 27 | * 28 | * 3. Neither the name of the Institute nor the names of its contributors 29 | * may be used to endorse or promote products derived from this software 30 | * without specific prior written permission. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 33 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 36 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 | * SUCH DAMAGE. 43 | */ 44 | 45 | /* $KTH: ifaddrs.hin,v 1.3 2000/12/11 00:01:13 assar Exp $ */ 46 | 47 | #ifndef ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 48 | #define ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 49 | 50 | /* 51 | * the interface is defined in terms of the fields below, and this is 52 | * sometimes #define'd, so there seems to be no simple way of solving 53 | * this and this seemed the best. */ 54 | 55 | #undef ifa_dstaddr 56 | 57 | struct ifaddrs { 58 | struct ifaddrs *ifa_next; 59 | char *ifa_name; 60 | unsigned int ifa_flags; 61 | struct sockaddr *ifa_addr; 62 | struct sockaddr *ifa_netmask; 63 | struct sockaddr *ifa_dstaddr; 64 | void *ifa_data; 65 | }; 66 | 67 | #ifndef ifa_broadaddr 68 | #define ifa_broadaddr ifa_dstaddr 69 | #endif 70 | 71 | int getifaddrs(struct ifaddrs **); 72 | 73 | void freeifaddrs(struct ifaddrs *); 74 | 75 | #endif /* __ifaddrs_h__ */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | #endif 81 | -------------------------------------------------------------------------------- /thirdparty/lws/misc/lws-genhash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets - small server side websockets and web server implementation 3 | * 4 | * Copyright (C) 2017 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | * 21 | * lws_genhash provides a hash abstraction api in lws that works the same 22 | * whether you are using openssl or mbedtls hash functions underneath. 23 | */ 24 | #include "libwebsockets.h" 25 | 26 | size_t 27 | lws_genhash_size(int type) 28 | { 29 | switch(type) { 30 | case LWS_GENHASH_TYPE_SHA1: 31 | return 20; 32 | case LWS_GENHASH_TYPE_SHA256: 33 | return 32; 34 | case LWS_GENHASH_TYPE_SHA512: 35 | return 64; 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | int 42 | lws_genhash_init(struct lws_genhash_ctx *ctx, int type) 43 | { 44 | ctx->type = type; 45 | 46 | #if defined(LWS_WITH_MBEDTLS) 47 | switch (ctx->type) { 48 | case LWS_GENHASH_TYPE_SHA1: 49 | mbedtls_sha1_init(&ctx->u.sha1); 50 | mbedtls_sha1_starts(&ctx->u.sha1); 51 | break; 52 | case LWS_GENHASH_TYPE_SHA256: 53 | mbedtls_sha256_init(&ctx->u.sha256); 54 | mbedtls_sha256_starts(&ctx->u.sha256, 0); 55 | break; 56 | case LWS_GENHASH_TYPE_SHA512: 57 | mbedtls_sha512_init(&ctx->u.sha512); 58 | mbedtls_sha512_starts(&ctx->u.sha512, 0); 59 | break; 60 | default: 61 | return 1; 62 | } 63 | #else 64 | ctx->mdctx = EVP_MD_CTX_create(); 65 | if (!ctx->mdctx) 66 | return 1; 67 | 68 | switch (ctx->type) { 69 | case LWS_GENHASH_TYPE_SHA1: 70 | ctx->evp_type = EVP_sha1(); 71 | break; 72 | case LWS_GENHASH_TYPE_SHA256: 73 | ctx->evp_type = EVP_sha256(); 74 | break; 75 | case LWS_GENHASH_TYPE_SHA512: 76 | ctx->evp_type = EVP_sha512(); 77 | break; 78 | default: 79 | return 1; 80 | } 81 | 82 | if (EVP_DigestInit_ex(ctx->mdctx, ctx->evp_type, NULL) != 1) { 83 | EVP_MD_CTX_destroy(ctx->mdctx); 84 | 85 | return 1; 86 | } 87 | 88 | #endif 89 | return 0; 90 | } 91 | 92 | int 93 | lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len) 94 | { 95 | #if defined(LWS_WITH_MBEDTLS) 96 | switch (ctx->type) { 97 | case LWS_GENHASH_TYPE_SHA1: 98 | mbedtls_sha1_update(&ctx->u.sha1, in, len); 99 | break; 100 | case LWS_GENHASH_TYPE_SHA256: 101 | mbedtls_sha256_update(&ctx->u.sha256, in, len); 102 | break; 103 | case LWS_GENHASH_TYPE_SHA512: 104 | mbedtls_sha512_update(&ctx->u.sha512, in, len); 105 | break; 106 | } 107 | #else 108 | return EVP_DigestUpdate(ctx->mdctx, in, len) != 1; 109 | #endif 110 | 111 | return 0; 112 | } 113 | 114 | int 115 | lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result) 116 | { 117 | #if defined(LWS_WITH_MBEDTLS) 118 | switch (ctx->type) { 119 | case LWS_GENHASH_TYPE_SHA1: 120 | mbedtls_sha1_finish(&ctx->u.sha1, result); 121 | mbedtls_sha1_free(&ctx->u.sha1); 122 | break; 123 | case LWS_GENHASH_TYPE_SHA256: 124 | mbedtls_sha256_finish(&ctx->u.sha256, result); 125 | mbedtls_sha256_free(&ctx->u.sha256); 126 | break; 127 | case LWS_GENHASH_TYPE_SHA512: 128 | mbedtls_sha512_finish(&ctx->u.sha512, result); 129 | mbedtls_sha512_free(&ctx->u.sha512); 130 | break; 131 | } 132 | 133 | return 0; 134 | #else 135 | unsigned int len; 136 | int ret = 0; 137 | 138 | if (result) 139 | ret = EVP_DigestFinal_ex(ctx->mdctx, result, &len) != 1; 140 | 141 | (void)len; 142 | 143 | EVP_MD_CTX_destroy(ctx->mdctx); 144 | 145 | return ret; 146 | #endif 147 | } 148 | 149 | 150 | -------------------------------------------------------------------------------- /thirdparty/lws/misc/romfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 National Institute of Advanced Industrial Science 3 | * and Technology (AIST) 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of AIST nor the names of its contributors may be used 18 | * to endorse or promote products derived from this software without specific 19 | * prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include "romfs.h" 38 | #include "esp_spi_flash.h" 39 | 40 | #define RFS_STRING_MAX 96 41 | 42 | static u32_be_t cache[(RFS_STRING_MAX + 32) / 4]; 43 | static romfs_inode_t ci = (romfs_inode_t)cache; 44 | static romfs_t cr = (romfs_t)cache; 45 | 46 | static void 47 | set_cache(romfs_inode_t inode, size_t len) 48 | { 49 | spi_flash_read((uint32_t)inode, cache, len); 50 | } 51 | 52 | static uint32_t 53 | ntohl(const u32_be_t be) 54 | { 55 | return ((be >> 24) & 0xff) | 56 | ((be >> 16) & 0xff) << 8 | 57 | ((be >> 8) & 0xff) << 16 | 58 | (be & 0xff) << 24; 59 | } 60 | static romfs_inode_t 61 | romfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path); 62 | 63 | static int 64 | plus_padding(const uint8_t *s) 65 | { 66 | int n; 67 | 68 | set_cache((romfs_inode_t)s, RFS_STRING_MAX); 69 | n = strlen((const char *)cache); 70 | 71 | if (!(n & 15)) 72 | n += 0x10; 73 | 74 | return (n + 15) & ~15; 75 | } 76 | 77 | static romfs_inode_t 78 | skip_and_pad(romfs_inode_t ri) 79 | { 80 | const uint8_t *p = ((const uint8_t *)ri) + sizeof(*ri); 81 | 82 | return (romfs_inode_t)(p + plus_padding(p)); 83 | } 84 | 85 | size_t 86 | romfs_mount_check(romfs_t romfs) 87 | { 88 | set_cache((romfs_inode_t)romfs, sizeof(*romfs)); 89 | 90 | if (cr->magic1 != 0x6d6f722d || 91 | cr->magic2 != 0x2d736631) 92 | return 0; 93 | 94 | return ntohl(cr->size); 95 | } 96 | 97 | static romfs_inode_t 98 | romfs_symlink(romfs_t romfs, romfs_inode_t level, romfs_inode_t i) 99 | { 100 | const char *p = (const char *)skip_and_pad(i); 101 | 102 | if (*p == '/') { 103 | level = skip_and_pad((romfs_inode_t)romfs); 104 | p++; 105 | } 106 | 107 | return romfs_lookup(romfs, level, p); 108 | } 109 | 110 | static romfs_inode_t 111 | dir_link(romfs_t romfs, romfs_inode_t i) 112 | { 113 | set_cache(i, sizeof(*i)); 114 | return (romfs_inode_t)((const uint8_t *)romfs + 115 | ntohl(ci->dir_start)); 116 | } 117 | 118 | static romfs_inode_t 119 | romfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path) 120 | { 121 | romfs_inode_t level, i = start, i_in; 122 | const char *p, *n, *cp; 123 | uint32_t next_be; 124 | 125 | if (start == (romfs_inode_t)romfs) 126 | i = skip_and_pad((romfs_inode_t)romfs); 127 | level = i; 128 | while (i != (romfs_inode_t)romfs) { 129 | p = path; 130 | n = ((const char *)i) + sizeof(*i); 131 | i_in = i; 132 | 133 | set_cache(i, sizeof(*i)); 134 | next_be = ci->next; 135 | 136 | cp = (const char *)cache; 137 | set_cache((romfs_inode_t)n, RFS_STRING_MAX); 138 | 139 | while (*p && *p != '/' && *cp && *p == *cp && (p - path) < RFS_STRING_MAX) { 140 | p++; 141 | n++; 142 | cp++; 143 | } 144 | 145 | if (!*cp && (!*p || *p == '/') && 146 | (ntohl(next_be) & 7) == RFST_HARDLINK) { 147 | set_cache(i, sizeof(*i)); 148 | return (romfs_inode_t) 149 | ((const uint8_t *)romfs + 150 | (ntohl(ci->dir_start) & ~15)); 151 | } 152 | 153 | if (!*p && !*cp) { 154 | set_cache(i, sizeof(*i)); 155 | if ((ntohl(ci->next) & 7) == RFST_SYMLINK) { 156 | i = romfs_symlink(romfs, level, i); 157 | continue; 158 | } 159 | return i; 160 | } 161 | 162 | if (!*p && *cp == '/') 163 | return NULL; 164 | 165 | if (*p == '/' && !*cp) { 166 | set_cache(i, sizeof(*i)); 167 | switch (ntohl(ci->next) & 7) { 168 | case RFST_SYMLINK: 169 | i = romfs_symlink(romfs, level, i); 170 | if (!i) 171 | return NULL; 172 | i = dir_link(romfs, i); 173 | while (*path != '/' && *path) 174 | path++; 175 | if (!*path) 176 | return NULL; 177 | path++; 178 | continue; 179 | case RFST_DIR: 180 | path = p + 1; 181 | i = dir_link(romfs, i); 182 | break; 183 | default: 184 | path = p + 1; 185 | i = skip_and_pad(i); 186 | break; 187 | } 188 | level = i; 189 | continue; 190 | } 191 | 192 | set_cache(i, sizeof(*i)); 193 | if (!(ntohl(ci->next) & ~15)) 194 | return NULL; 195 | 196 | i = (romfs_inode_t)((const uint8_t *)romfs + 197 | (ntohl(ci->next) & ~15)); 198 | if (i == i_in) 199 | return NULL; 200 | } 201 | 202 | return NULL; 203 | } 204 | 205 | const void * 206 | romfs_get_info(romfs_t romfs, const char *path, size_t *len, size_t *csum) 207 | { 208 | romfs_inode_t i; 209 | 210 | if (*path == '/') 211 | path++; 212 | 213 | i = romfs_lookup(romfs, (romfs_inode_t)romfs, path); 214 | 215 | if (!i) 216 | return NULL; 217 | 218 | set_cache(i, sizeof(*i)); 219 | *len = ntohl(ci->size); 220 | if (csum) 221 | *csum = ntohl(ci->checksum); 222 | 223 | return (void *)skip_and_pad(i); 224 | } 225 | -------------------------------------------------------------------------------- /thirdparty/lws/misc/romfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 National Institute of Advanced Industrial Science 3 | * and Technology (AIST) 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of AIST nor the names of its contributors may be used 18 | * to endorse or promote products derived from this software without specific 19 | * prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | typedef uint32_t u32_be_t; 35 | 36 | struct romfs_superblock { 37 | u32_be_t magic1; 38 | u32_be_t magic2; 39 | u32_be_t size; 40 | u32_be_t checksum; 41 | }; 42 | 43 | struct romfs_i { 44 | u32_be_t next; 45 | u32_be_t dir_start; 46 | u32_be_t size; 47 | u32_be_t checksum; 48 | }; 49 | 50 | enum { 51 | RFST_HARDLINK = 0, 52 | RFST_DIR = 1, 53 | RFST_SYMLINK = 3, 54 | }; 55 | 56 | typedef const struct romfs_i *romfs_inode_t; 57 | typedef const struct romfs_superblock *romfs_t; 58 | 59 | const void * 60 | romfs_get_info(romfs_t romfs, const char *path, size_t *len, size_t *csum); 61 | size_t 62 | romfs_mount_check(romfs_t romfs); 63 | 64 | -------------------------------------------------------------------------------- /thirdparty/lws/server/access-log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets - server access log handling 3 | * 4 | * Copyright (C) 2010-2017 Andy Green 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation: 9 | * version 2.1 of the License. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301 USA 20 | */ 21 | 22 | #include "private-libwebsockets.h" 23 | 24 | /* 25 | * Produce Apache-compatible log string for wsi, like this: 26 | * 27 | * 2.31.234.19 - - [27/Mar/2016:03:22:44 +0800] 28 | * "GET /aep-screen.png HTTP/1.1" 29 | * 200 152987 "https://libwebsockets.org/index.html" 30 | * "Mozilla/5.0 (Macint... Chrome/49.0.2623.87 Safari/537.36" 31 | * 32 | */ 33 | 34 | extern const char * const method_names[]; 35 | 36 | static const char * const hver[] = { 37 | "HTTP/1.0", "HTTP/1.1", "HTTP/2" 38 | }; 39 | 40 | void 41 | lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth) 42 | { 43 | #ifdef LWS_WITH_IPV6 44 | char ads[INET6_ADDRSTRLEN]; 45 | #else 46 | char ads[INET_ADDRSTRLEN]; 47 | #endif 48 | char da[64]; 49 | const char *pa, *me; 50 | struct tm *tmp; 51 | time_t t = time(NULL); 52 | int l = 256, m; 53 | 54 | if (wsi->access_log_pending) 55 | lws_access_log(wsi); 56 | 57 | wsi->access_log.header_log = lws_malloc(l, "access log"); 58 | if (wsi->access_log.header_log) { 59 | 60 | tmp = localtime(&t); 61 | if (tmp) 62 | strftime(da, sizeof(da), "%d/%b/%Y:%H:%M:%S %z", tmp); 63 | else 64 | strcpy(da, "01/Jan/1970:00:00:00 +0000"); 65 | 66 | pa = lws_get_peer_simple(wsi, ads, sizeof(ads)); 67 | if (!pa) 68 | pa = "(unknown)"; 69 | 70 | if (wsi->http2_substream) 71 | me = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD); 72 | else 73 | me = method_names[meth]; 74 | if (!me) 75 | me = "(null)"; 76 | 77 | lws_snprintf(wsi->access_log.header_log, l, 78 | "%s - - [%s] \"%s %s %s\"", 79 | pa, da, me, uri_ptr, 80 | hver[wsi->u.http.request_version]); 81 | 82 | l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT); 83 | if (l) { 84 | wsi->access_log.user_agent = lws_malloc(l + 2, "access log"); 85 | if (!wsi->access_log.user_agent) { 86 | lwsl_err("OOM getting user agent\n"); 87 | lws_free_set_NULL(wsi->access_log.header_log); 88 | return; 89 | } 90 | 91 | lws_hdr_copy(wsi, wsi->access_log.user_agent, 92 | l + 1, WSI_TOKEN_HTTP_USER_AGENT); 93 | 94 | for (m = 0; m < l; m++) 95 | if (wsi->access_log.user_agent[m] == '\"') 96 | wsi->access_log.user_agent[m] = '\''; 97 | } 98 | l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_REFERER); 99 | if (l) { 100 | wsi->access_log.referrer = lws_malloc(l + 2, "referrer"); 101 | if (!wsi->access_log.referrer) { 102 | lwsl_err("OOM getting user agent\n"); 103 | lws_free_set_NULL(wsi->access_log.user_agent); 104 | lws_free_set_NULL(wsi->access_log.header_log); 105 | return; 106 | } 107 | lws_hdr_copy(wsi, wsi->access_log.referrer, 108 | l + 1, WSI_TOKEN_HTTP_REFERER); 109 | 110 | for (m = 0; m < l; m++) 111 | if (wsi->access_log.referrer[m] == '\"') 112 | wsi->access_log.referrer[m] = '\''; 113 | } 114 | wsi->access_log_pending = 1; 115 | } 116 | } 117 | 118 | 119 | int 120 | lws_access_log(struct lws *wsi) 121 | { 122 | char *p = wsi->access_log.user_agent, ass[512], 123 | *p1 = wsi->access_log.referrer; 124 | int l; 125 | 126 | if (!wsi->access_log_pending) 127 | return 0; 128 | 129 | if (!wsi->access_log.header_log) 130 | return 0; 131 | 132 | if (!p) 133 | p = ""; 134 | 135 | if (!p1) 136 | p1 = ""; 137 | 138 | /* 139 | * We do this in two parts to restrict an oversize referrer such that 140 | * we will always have space left to append an empty useragent, while 141 | * maintaining the structure of the log text 142 | */ 143 | l = lws_snprintf(ass, sizeof(ass) - 7, "%s %d %lu \"%s", 144 | wsi->access_log.header_log, 145 | wsi->access_log.response, wsi->access_log.sent, p1); 146 | if (strlen(p) > sizeof(ass) - 6 - l) 147 | p[sizeof(ass) - 6 - l] = '\0'; 148 | l += lws_snprintf(ass + l, sizeof(ass) - 1 - l, "\" \"%s\"\n", p); 149 | 150 | if (wsi->vhost->log_fd != (int)LWS_INVALID_FILE) { 151 | if (write(wsi->vhost->log_fd, ass, l) != l) 152 | lwsl_err("Failed to write log\n"); 153 | } else 154 | lwsl_err("%s", ass); 155 | 156 | if (wsi->access_log.header_log) { 157 | lws_free(wsi->access_log.header_log); 158 | wsi->access_log.header_log = NULL; 159 | } 160 | if (wsi->access_log.user_agent) { 161 | lws_free(wsi->access_log.user_agent); 162 | wsi->access_log.user_agent = NULL; 163 | } 164 | if (wsi->access_log.referrer) { 165 | lws_free(wsi->access_log.referrer); 166 | wsi->access_log.referrer = NULL; 167 | } 168 | wsi->access_log_pending = 0; 169 | 170 | return 0; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /thirdparty/lws/server/daemonize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This code is mainly taken from Doug Potter's page 3 | * 4 | * http://www-theorie.physik.unizh.ch/~dpotter/howto/daemonize 5 | * 6 | * I contacted him 2007-04-16 about the license for the original code, 7 | * he replied it is Public Domain. Use the URL above to get the original 8 | * Public Domain version if you want it. 9 | * 10 | * This version is LGPL2.1+SLE like the rest of libwebsockets and is 11 | * Copyright (c)2006 - 2013 Andy Green 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "private-libwebsockets.h" 26 | 27 | int pid_daemon; 28 | static char *lock_path; 29 | 30 | int get_daemonize_pid() 31 | { 32 | return pid_daemon; 33 | } 34 | 35 | static void 36 | child_handler(int signum) 37 | { 38 | int fd, len, sent; 39 | char sz[20]; 40 | 41 | switch (signum) { 42 | 43 | case SIGALRM: /* timed out daemonizing */ 44 | exit(0); 45 | break; 46 | 47 | case SIGUSR1: /* positive confirmation we daemonized well */ 48 | 49 | if (lock_path) { 50 | /* Create the lock file as the current user */ 51 | 52 | fd = open(lock_path, O_TRUNC | O_RDWR | O_CREAT, 0640); 53 | if (fd < 0) { 54 | fprintf(stderr, 55 | "unable to create lock file %s, code=%d (%s)\n", 56 | lock_path, errno, strerror(errno)); 57 | exit(0); 58 | } 59 | len = sprintf(sz, "%u", pid_daemon); 60 | sent = write(fd, sz, len); 61 | if (sent != len) 62 | fprintf(stderr, 63 | "unable to write pid to lock file %s, code=%d (%s)\n", 64 | lock_path, errno, strerror(errno)); 65 | 66 | close(fd); 67 | } 68 | exit(0); 69 | //!!(sent == len)); 70 | 71 | case SIGCHLD: /* daemonization failed */ 72 | exit(0); 73 | break; 74 | } 75 | } 76 | 77 | static void lws_daemon_closing(int sigact) 78 | { 79 | if (getpid() == pid_daemon) 80 | if (lock_path) { 81 | unlink(lock_path); 82 | lws_free_set_NULL(lock_path); 83 | } 84 | 85 | kill(getpid(), SIGKILL); 86 | } 87 | 88 | /* 89 | * You just need to call this from your main(), when it 90 | * returns you are all set "in the background" decoupled 91 | * from the console you were started from. 92 | * 93 | * The process context you called from has been terminated then. 94 | */ 95 | 96 | LWS_VISIBLE int 97 | lws_daemonize(const char *_lock_path) 98 | { 99 | struct sigaction act; 100 | pid_t sid, parent; 101 | int n, fd, ret; 102 | char buf[10]; 103 | 104 | /* already a daemon */ 105 | // if (getppid() == 1) 106 | // return 1; 107 | 108 | if (_lock_path) { 109 | fd = open(_lock_path, O_RDONLY); 110 | if (fd >= 0) { 111 | n = read(fd, buf, sizeof(buf)); 112 | close(fd); 113 | if (n) { 114 | n = atoi(buf); 115 | ret = kill(n, 0); 116 | if (ret >= 0) { 117 | fprintf(stderr, 118 | "Daemon already running from pid %d\n", n); 119 | exit(1); 120 | } 121 | fprintf(stderr, 122 | "Removing stale lock file %s from dead pid %d\n", 123 | _lock_path, n); 124 | unlink(lock_path); 125 | } 126 | } 127 | 128 | n = strlen(_lock_path) + 1; 129 | lock_path = lws_malloc(n, "daemonize lock"); 130 | if (!lock_path) { 131 | fprintf(stderr, "Out of mem in lws_daemonize\n"); 132 | return 1; 133 | } 134 | strcpy(lock_path, _lock_path); 135 | } 136 | 137 | /* Trap signals that we expect to receive */ 138 | signal(SIGCHLD, child_handler); /* died */ 139 | signal(SIGUSR1, child_handler); /* was happy */ 140 | signal(SIGALRM, child_handler); /* timeout daemonizing */ 141 | 142 | /* Fork off the parent process */ 143 | pid_daemon = fork(); 144 | if (pid_daemon < 0) { 145 | fprintf(stderr, "unable to fork daemon, code=%d (%s)", 146 | errno, strerror(errno)); 147 | exit(9); 148 | } 149 | 150 | /* If we got a good PID, then we can exit the parent process. */ 151 | if (pid_daemon > 0) { 152 | 153 | /* 154 | * Wait for confirmation signal from the child via 155 | * SIGCHILD / USR1, or for two seconds to elapse 156 | * (SIGALRM). pause() should not return. 157 | */ 158 | alarm(2); 159 | 160 | pause(); 161 | /* should not be reachable */ 162 | exit(1); 163 | } 164 | 165 | /* At this point we are executing as the child process */ 166 | parent = getppid(); 167 | pid_daemon = getpid(); 168 | 169 | /* Cancel certain signals */ 170 | signal(SIGCHLD, SIG_DFL); /* A child process dies */ 171 | signal(SIGTSTP, SIG_IGN); /* Various TTY signals */ 172 | signal(SIGTTOU, SIG_IGN); 173 | signal(SIGTTIN, SIG_IGN); 174 | signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */ 175 | 176 | /* Change the file mode mask */ 177 | umask(0); 178 | 179 | /* Create a new SID for the child process */ 180 | sid = setsid(); 181 | if (sid < 0) { 182 | fprintf(stderr, 183 | "unable to create a new session, code %d (%s)", 184 | errno, strerror(errno)); 185 | exit(2); 186 | } 187 | 188 | /* 189 | * Change the current working directory. This prevents the current 190 | * directory from being locked; hence not being able to remove it. 191 | */ 192 | if (chdir("/tmp") < 0) { 193 | fprintf(stderr, 194 | "unable to change directory to %s, code %d (%s)", 195 | "/", errno, strerror(errno)); 196 | exit(3); 197 | } 198 | 199 | /* Redirect standard files to /dev/null */ 200 | if (!freopen("/dev/null", "r", stdin)) 201 | fprintf(stderr, "unable to freopen() stdin, code %d (%s)", 202 | errno, strerror(errno)); 203 | 204 | if (!freopen("/dev/null", "w", stdout)) 205 | fprintf(stderr, "unable to freopen() stdout, code %d (%s)", 206 | errno, strerror(errno)); 207 | 208 | if (!freopen("/dev/null", "w", stderr)) 209 | fprintf(stderr, "unable to freopen() stderr, code %d (%s)", 210 | errno, strerror(errno)); 211 | 212 | /* Tell the parent process that we are A-okay */ 213 | kill(parent, SIGUSR1); 214 | 215 | act.sa_handler = lws_daemon_closing; 216 | sigemptyset(&act.sa_mask); 217 | act.sa_flags = 0; 218 | 219 | sigaction(SIGTERM, &act, NULL); 220 | 221 | /* return to continue what is now "the daemon" */ 222 | 223 | return 0; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /thirdparty/lws/server/ranges.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libwebsockets - small server side websockets and web server implementation 3 | * 4 | * RFC7233 ranges parser 5 | * 6 | * Copyright (C) 2016 Andy Green 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation: 11 | * version 2.1 of the License. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 | * MA 02110-1301 USA 22 | */ 23 | 24 | #include "private-libwebsockets.h" 25 | 26 | /* 27 | * RFC7233 examples 28 | * 29 | * o The first 500 bytes (byte offsets 0-499, inclusive): 30 | * 31 | * bytes=0-499 32 | * 33 | * o The second 500 bytes (byte offsets 500-999, inclusive): 34 | * 35 | * bytes=500-999 36 | * 37 | * o The final 500 bytes (byte offsets 9500-9999, inclusive): 38 | * 39 | * bytes=-500 40 | * 41 | * Or: 42 | * 43 | * bytes=9500- 44 | * 45 | * o The first and last bytes only (bytes 0 and 9999): 46 | * 47 | * bytes=0-0,-1 48 | * 49 | * o Other valid (but not canonical) specifications of the second 500 50 | * bytes (byte offsets 500-999, inclusive): 51 | * 52 | * bytes=500-600,601-999 53 | * bytes=500-700,601-999 54 | */ 55 | 56 | /* 57 | * returns 1 if the range struct represents a usable range 58 | * if no ranges header, you get one of these for the whole 59 | * file. Otherwise you get one for each valid range in the 60 | * header. 61 | * 62 | * returns 0 if no further valid range forthcoming; rp->state 63 | * may be LWSRS_SYNTAX or LWSRS_COMPLETED 64 | */ 65 | 66 | int 67 | lws_ranges_next(struct lws_range_parsing *rp) 68 | { 69 | static const char * const beq = "bytes="; 70 | char c; 71 | 72 | while (1) { 73 | 74 | c = rp->buf[rp->pos]; 75 | 76 | switch (rp->state) { 77 | case LWSRS_SYNTAX: 78 | case LWSRS_COMPLETED: 79 | return 0; 80 | 81 | case LWSRS_NO_ACTIVE_RANGE: 82 | rp->state = LWSRS_COMPLETED; 83 | return 0; 84 | 85 | case LWSRS_BYTES_EQ: // looking for "bytes=" 86 | if (c != beq[rp->pos]) { 87 | rp->state = LWSRS_SYNTAX; 88 | return -1; 89 | } 90 | if (rp->pos == 5) 91 | rp->state = LWSRS_FIRST; 92 | break; 93 | 94 | case LWSRS_FIRST: 95 | rp->start = 0; 96 | rp->end = 0; 97 | rp->start_valid = 0; 98 | rp->end_valid = 0; 99 | 100 | rp->state = LWSRS_STARTING; 101 | 102 | // fallthru 103 | 104 | case LWSRS_STARTING: 105 | if (c == '-') { 106 | rp->state = LWSRS_ENDING; 107 | break; 108 | } 109 | 110 | if (!(c >= '0' && c <= '9')) { 111 | rp->state = LWSRS_SYNTAX; 112 | return 0; 113 | } 114 | rp->start = (rp->start * 10) + (c - '0'); 115 | rp->start_valid = 1; 116 | break; 117 | 118 | case LWSRS_ENDING: 119 | if (c == ',' || c == '\0') { 120 | rp->state = LWSRS_FIRST; 121 | if (c == ',') 122 | rp->pos++; 123 | 124 | /* 125 | * By the end of this, start and end are 126 | * always valid if the range still is 127 | */ 128 | 129 | if (!rp->start_valid) { /* eg, -500 */ 130 | if (rp->end > rp->extent) 131 | rp->end = rp->extent; 132 | 133 | rp->start = rp->extent - rp->end; 134 | rp->end = rp->extent - 1; 135 | } else 136 | if (!rp->end_valid) 137 | rp->end = rp->extent - 1; 138 | 139 | rp->did_try = 1; 140 | 141 | /* end must be >= start or ignore it */ 142 | if (rp->end < rp->start) { 143 | if (c == ',') 144 | break; 145 | rp->state = LWSRS_COMPLETED; 146 | return 0; 147 | } 148 | 149 | return 1; /* issue range */ 150 | } 151 | 152 | if (!(c >= '0' && c <= '9')) { 153 | rp->state = LWSRS_SYNTAX; 154 | return 0; 155 | } 156 | rp->end = (rp->end * 10) + (c - '0'); 157 | rp->end_valid = 1; 158 | break; 159 | } 160 | 161 | rp->pos++; 162 | } 163 | } 164 | 165 | void 166 | lws_ranges_reset(struct lws_range_parsing *rp) 167 | { 168 | rp->pos = 0; 169 | rp->ctr = 0; 170 | rp->start = 0; 171 | rp->end = 0; 172 | rp->start_valid = 0; 173 | rp->end_valid = 0; 174 | rp->state = LWSRS_BYTES_EQ; 175 | } 176 | 177 | /* 178 | * returns count of valid ranges 179 | */ 180 | int 181 | lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp, 182 | unsigned long long extent) 183 | { 184 | rp->agg = 0; 185 | rp->send_ctr = 0; 186 | rp->inside = 0; 187 | rp->count_ranges = 0; 188 | rp->did_try = 0; 189 | lws_ranges_reset(rp); 190 | rp->state = LWSRS_COMPLETED; 191 | 192 | rp->extent = extent; 193 | 194 | if (lws_hdr_copy(wsi, (char *)rp->buf, sizeof(rp->buf), 195 | WSI_TOKEN_HTTP_RANGE) <= 0) 196 | return 0; 197 | 198 | rp->state = LWSRS_BYTES_EQ; 199 | 200 | while (lws_ranges_next(rp)) { 201 | rp->count_ranges++; 202 | rp->agg += rp->end - rp->start + 1; 203 | } 204 | 205 | lwsl_debug("%s: count %d\n", __func__, rp->count_ranges); 206 | lws_ranges_reset(rp); 207 | 208 | if (rp->did_try && !rp->count_ranges) 209 | return -1; /* "not satisfiable */ 210 | 211 | lws_ranges_next(rp); 212 | 213 | return rp->count_ranges; 214 | } 215 | -------------------------------------------------------------------------------- /thirdparty/lws/server/rewrite.c: -------------------------------------------------------------------------------- 1 | #include "private-libwebsockets.h" 2 | 3 | 4 | LWS_EXTERN struct lws_rewrite * 5 | lws_rewrite_create(struct lws *wsi, hubbub_callback_t cb, const char *from, const char *to) 6 | { 7 | struct lws_rewrite *r = lws_malloc(sizeof(*r), "rewrite"); 8 | 9 | if (!r) { 10 | lwsl_err("OOM\n"); 11 | return NULL; 12 | } 13 | 14 | if (hubbub_parser_create("UTF-8", false, &r->parser) != HUBBUB_OK) { 15 | lws_free(r); 16 | 17 | return NULL; 18 | } 19 | r->from = from; 20 | r->from_len = strlen(from); 21 | r->to = to; 22 | r->to_len = strlen(to); 23 | r->params.token_handler.handler = cb; 24 | r->wsi = wsi; 25 | r->params.token_handler.pw = (void *)r; 26 | if (hubbub_parser_setopt(r->parser, HUBBUB_PARSER_TOKEN_HANDLER, 27 | &r->params) != HUBBUB_OK) { 28 | lws_free(r); 29 | 30 | return NULL; 31 | } 32 | 33 | return r; 34 | } 35 | 36 | LWS_EXTERN int 37 | lws_rewrite_parse(struct lws_rewrite *r, 38 | const unsigned char *in, int in_len) 39 | { 40 | if (hubbub_parser_parse_chunk(r->parser, in, in_len) != HUBBUB_OK) 41 | return -1; 42 | 43 | return 0; 44 | } 45 | 46 | LWS_EXTERN void 47 | lws_rewrite_destroy(struct lws_rewrite *r) 48 | { 49 | hubbub_parser_destroy(r->parser); 50 | lws_free(r); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /thirdparty/lws/win32helpers/getopt.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1987, 1993, 1994 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the University of 18 | * California, Berkeley and its contributors. 19 | * 4. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | */ 35 | 36 | #if 0 37 | static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 38 | #endif 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define __P(x) x 46 | #define _DIAGASSERT(x) assert(x) 47 | 48 | #ifdef __weak_alias 49 | __weak_alias(getopt,_getopt); 50 | #endif 51 | 52 | 53 | int opterr = 1, /* if error message should be printed */ 54 | optind = 1, /* index into parent argv vector */ 55 | optopt, /* character checked for validity */ 56 | optreset; /* reset getopt */ 57 | char *optarg; /* argument associated with option */ 58 | 59 | static char * _progname __P((char *)); 60 | int getopt_internal __P((int, char * const *, const char *)); 61 | 62 | static char * 63 | _progname(nargv0) 64 | char * nargv0; 65 | { 66 | char * tmp; 67 | 68 | _DIAGASSERT(nargv0 != NULL); 69 | 70 | tmp = strrchr(nargv0, '/'); 71 | if (tmp) 72 | tmp++; 73 | else 74 | tmp = nargv0; 75 | return(tmp); 76 | } 77 | 78 | #define BADCH (int)'?' 79 | #define BADARG (int)':' 80 | #define EMSG "" 81 | 82 | /* 83 | * getopt -- 84 | * Parse argc/argv argument vector. 85 | */ 86 | int 87 | getopt(nargc, nargv, ostr) 88 | int nargc; 89 | char * const nargv[]; 90 | const char *ostr; 91 | { 92 | static char *__progname = 0; 93 | static char *place = EMSG; /* option letter processing */ 94 | char *oli; /* option letter list index */ 95 | __progname = __progname?__progname:_progname(*nargv); 96 | 97 | _DIAGASSERT(nargv != NULL); 98 | _DIAGASSERT(ostr != NULL); 99 | 100 | if (optreset || !*place) { /* update scanning pointer */ 101 | optreset = 0; 102 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 103 | place = EMSG; 104 | return (-1); 105 | } 106 | if (place[1] && *++place == '-' /* found "--" */ 107 | && place[1] == '\0') { 108 | ++optind; 109 | place = EMSG; 110 | return (-1); 111 | } 112 | } /* option letter okay? */ 113 | if ((optopt = (int)*place++) == (int)':' || 114 | !(oli = strchr(ostr, optopt))) { 115 | /* 116 | * if the user didn't specify '-' as an option, 117 | * assume it means -1. 118 | */ 119 | if (optopt == (int)'-') 120 | return (-1); 121 | if (!*place) 122 | ++optind; 123 | if (opterr && *ostr != ':') 124 | (void)fprintf(stderr, 125 | "%s: illegal option -- %c\n", __progname, optopt); 126 | return (BADCH); 127 | } 128 | if (*++oli != ':') { /* don't need argument */ 129 | optarg = NULL; 130 | if (!*place) 131 | ++optind; 132 | } 133 | else { /* need an argument */ 134 | if (*place) /* no white space */ 135 | optarg = place; 136 | else if (nargc <= ++optind) { /* no arg */ 137 | place = EMSG; 138 | if (*ostr == ':') 139 | return (BADARG); 140 | if (opterr) 141 | (void)fprintf(stderr, 142 | "%s: option requires an argument -- %c\n", 143 | __progname, optopt); 144 | return (BADCH); 145 | } 146 | else /* white space */ 147 | optarg = nargv[optind]; 148 | place = EMSG; 149 | ++optind; 150 | } 151 | return (optopt); /* dump back option letter */ 152 | } 153 | 154 | -------------------------------------------------------------------------------- /thirdparty/lws/win32helpers/getopt.h: -------------------------------------------------------------------------------- 1 | #ifndef __GETOPT_H__ 2 | #define __GETOPT_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern int opterr; /* if error message should be printed */ 9 | extern int optind; /* index into parent argv vector */ 10 | extern int optopt; /* character checked for validity */ 11 | extern int optreset; /* reset getopt */ 12 | extern char *optarg; /* argument associated with option */ 13 | 14 | struct option 15 | { 16 | const char *name; 17 | int has_arg; 18 | int *flag; 19 | int val; 20 | }; 21 | 22 | #define no_argument 0 23 | #define required_argument 1 24 | #define optional_argument 2 25 | 26 | int getopt(int, char**, char*); 27 | int getopt_long(int, char**, char*, struct option*, int*); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif /* __GETOPT_H__ */ 34 | -------------------------------------------------------------------------------- /thirdparty/lws/win32helpers/gettimeofday.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include //I've omitted context line 3 | 4 | #include "gettimeofday.h" 5 | 6 | int gettimeofday(struct timeval *tv, struct timezone *tz) 7 | { 8 | FILETIME ft; 9 | unsigned __int64 tmpres = 0; 10 | static int tzflag; 11 | 12 | if (NULL != tv) { 13 | GetSystemTimeAsFileTime(&ft); 14 | 15 | tmpres |= ft.dwHighDateTime; 16 | tmpres <<= 32; 17 | tmpres |= ft.dwLowDateTime; 18 | 19 | /*converting file time to unix epoch*/ 20 | tmpres /= 10; /*convert into microseconds*/ 21 | tmpres -= DELTA_EPOCH_IN_MICROSECS; 22 | tv->tv_sec = (long)(tmpres / 1000000UL); 23 | tv->tv_usec = (long)(tmpres % 1000000UL); 24 | } 25 | 26 | if (NULL != tz) { 27 | if (!tzflag) { 28 | _tzset(); 29 | tzflag++; 30 | } 31 | tz->tz_minuteswest = _timezone / 60; 32 | tz->tz_dsttime = _daylight; 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /thirdparty/lws/win32helpers/gettimeofday.h: -------------------------------------------------------------------------------- 1 | #ifndef _GET_TIME_OF_DAY_H 2 | #define _GET_TIME_OF_DAY_H 3 | 4 | #include 5 | 6 | #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 7 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 8 | #else 9 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL 10 | #endif 11 | 12 | #ifdef LWS_MINGW_SUPPORT 13 | #include 14 | #endif 15 | 16 | #ifndef _TIMEZONE_DEFINED 17 | struct timezone 18 | { 19 | int tz_minuteswest; /* minutes W of Greenwich */ 20 | int tz_dsttime; /* type of dst correction */ 21 | }; 22 | 23 | #endif 24 | 25 | int gettimeofday(struct timeval *tv, struct timezone *tz); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /websocket_chat_demo/.gitignore: -------------------------------------------------------------------------------- 1 | .import/* 2 | *.import 3 | export_presets.cfg 4 | -------------------------------------------------------------------------------- /websocket_chat_demo/client/client.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | onready var _log_dest = get_parent().get_node("Panel/VBoxContainer/RichTextLabel") 4 | 5 | var _client = WebSocketClient.new() 6 | var _write_mode = WebSocketPeer.WRITE_MODE_BINARY 7 | var _use_multiplayer = true 8 | var last_connected_client = 0 9 | 10 | func _init(): 11 | _client.connect("connection_established", self, "_client_connected") 12 | _client.connect("connection_error", self, "_client_disconnected") 13 | _client.connect("connection_closed", self, "_client_disconnected") 14 | _client.connect("server_close_request", self, "_client_close_request") 15 | _client.connect("data_received", self, "_client_received") 16 | 17 | _client.connect("peer_packet", self, "_client_received") 18 | _client.connect("peer_connected", self, "_peer_connected") 19 | _client.connect("connection_succeeded", self, "_client_connected", ["multiplayer_protocol"]) 20 | _client.connect("connection_failed", self, "_client_disconnected") 21 | 22 | func _client_close_request(code, reason): 23 | Utils._log(_log_dest, "Close code: %d, reason: %s" % [code, reason]) 24 | 25 | func _peer_connected(id): 26 | Utils._log(_log_dest, "%s: Client just connected" % id) 27 | last_connected_client = id 28 | 29 | func _exit_tree(): 30 | _client.disconnect_from_host(1001, "Bye bye!") 31 | 32 | func _process(delta): 33 | if _client.get_connection_status() == WebSocketClient.CONNECTION_DISCONNECTED: 34 | return 35 | 36 | _client.poll() 37 | 38 | func _client_connected(protocol): 39 | Utils._log(_log_dest, "Client just connected with protocol: %s" % protocol) 40 | _client.get_peer(1).set_write_mode(_write_mode) 41 | 42 | func _client_disconnected(clean=true): 43 | Utils._log(_log_dest, "Client just disconnected. Was clean: %s" % clean) 44 | 45 | func _client_received(p_id = 1): 46 | if _use_multiplayer: 47 | var peer_id = _client.get_packet_peer() 48 | var packet = _client.get_packet() 49 | Utils._log(_log_dest, "MPAPI: From %s Data: %s" % [str(peer_id), Utils.decode_data(packet, false)]) 50 | else: 51 | var packet = _client.get_peer(1).get_packet() 52 | var is_string = _client.get_peer(1).was_string_packet() 53 | Utils._log(_log_dest, "Received data. BINARY: %s: %s" % [not is_string, Utils.decode_data(packet, is_string)]) 54 | 55 | func connect_to_url(host, protocols, multiplayer): 56 | _use_multiplayer = multiplayer 57 | if _use_multiplayer: 58 | _write_mode = WebSocketPeer.WRITE_MODE_BINARY 59 | return _client.connect_to_url(host, protocols, multiplayer) 60 | 61 | func disconnect_from_host(): 62 | _client.disconnect_from_host(1000, "Bye bye!") 63 | 64 | func send_data(data, dest): 65 | _client.get_peer(1).set_write_mode(_write_mode) 66 | if _use_multiplayer: 67 | _client.set_target_peer(dest) 68 | _client.put_packet(Utils.encode_data(data, _write_mode)) 69 | else: 70 | _client.get_peer(1).put_packet(Utils.encode_data(data, _write_mode)) 71 | 72 | func set_write_mode(mode): 73 | _write_mode = mode -------------------------------------------------------------------------------- /websocket_chat_demo/client/client.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://client/client_ui.gd" type="Script" id=1] 4 | [ext_resource path="res://client/client.gd" type="Script" id=2] 5 | 6 | [node name="Client" type="Control"] 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | script = ExtResource( 1 ) 10 | 11 | [node name="Panel" type="Panel" parent="."] 12 | anchor_right = 1.0 13 | anchor_bottom = 1.0 14 | 15 | [node name="VBoxContainer" type="VBoxContainer" parent="Panel"] 16 | anchor_right = 1.0 17 | anchor_bottom = 1.0 18 | 19 | [node name="Connect" type="HBoxContainer" parent="Panel/VBoxContainer"] 20 | margin_right = 1024.0 21 | margin_bottom = 24.0 22 | 23 | [node name="Host" type="LineEdit" parent="Panel/VBoxContainer/Connect"] 24 | margin_right = 956.0 25 | margin_bottom = 24.0 26 | size_flags_horizontal = 3 27 | text = "ws://localhost:8000/test/" 28 | placeholder_text = "ws://my.server/path/" 29 | 30 | [node name="Connect" type="Button" parent="Panel/VBoxContainer/Connect"] 31 | margin_left = 960.0 32 | margin_right = 1024.0 33 | margin_bottom = 24.0 34 | toggle_mode = true 35 | text = "Connect" 36 | 37 | [node name="Settings" type="HBoxContainer" parent="Panel/VBoxContainer"] 38 | margin_top = 28.0 39 | margin_right = 1024.0 40 | margin_bottom = 52.0 41 | 42 | [node name="Mode" type="OptionButton" parent="Panel/VBoxContainer/Settings"] 43 | margin_right = 41.0 44 | margin_bottom = 24.0 45 | 46 | [node name="Multiplayer" type="CheckBox" parent="Panel/VBoxContainer/Settings"] 47 | margin_left = 45.0 48 | margin_right = 171.0 49 | margin_bottom = 24.0 50 | pressed = true 51 | text = "Multiplayer API" 52 | 53 | [node name="Destination" type="OptionButton" parent="Panel/VBoxContainer/Settings"] 54 | margin_left = 175.0 55 | margin_right = 216.0 56 | margin_bottom = 24.0 57 | 58 | [node name="Send" type="HBoxContainer" parent="Panel/VBoxContainer"] 59 | margin_top = 56.0 60 | margin_right = 1024.0 61 | margin_bottom = 80.0 62 | 63 | [node name="LineEdit" type="LineEdit" parent="Panel/VBoxContainer/Send"] 64 | margin_right = 977.0 65 | margin_bottom = 24.0 66 | size_flags_horizontal = 3 67 | placeholder_text = "Enter some text to send..." 68 | 69 | [node name="Send" type="Button" parent="Panel/VBoxContainer/Send"] 70 | margin_left = 981.0 71 | margin_right = 1024.0 72 | margin_bottom = 24.0 73 | text = "Send" 74 | 75 | [node name="RichTextLabel" type="RichTextLabel" parent="Panel/VBoxContainer"] 76 | margin_top = 84.0 77 | margin_right = 1024.0 78 | margin_bottom = 600.0 79 | size_flags_vertical = 3 80 | 81 | [node name="Client" type="Node" parent="."] 82 | script = ExtResource( 2 ) 83 | [connection signal="toggled" from="Panel/VBoxContainer/Connect/Connect" to="." method="_on_Connect_toggled"] 84 | [connection signal="item_selected" from="Panel/VBoxContainer/Settings/Mode" to="Client" method="_on_Mode_item_selected"] 85 | [connection signal="item_selected" from="Panel/VBoxContainer/Settings/Mode" to="." method="_on_Mode_item_selected"] 86 | [connection signal="pressed" from="Panel/VBoxContainer/Send/Send" to="." method="_on_Send_pressed"] 87 | -------------------------------------------------------------------------------- /websocket_chat_demo/client/client_ui.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | onready var _client = get_node("Client") 4 | onready var _log_dest = get_node("Panel/VBoxContainer/RichTextLabel") 5 | onready var _line_edit = get_node("Panel/VBoxContainer/Send/LineEdit") 6 | onready var _host = get_node("Panel/VBoxContainer/Connect/Host") 7 | onready var _multiplayer = get_node("Panel/VBoxContainer/Settings/Multiplayer") 8 | onready var _write_mode = get_node("Panel/VBoxContainer/Settings/Mode") 9 | onready var _destination = get_node("Panel/VBoxContainer/Settings/Destination") 10 | 11 | func _ready(): 12 | _write_mode.clear() 13 | _write_mode.add_item("BINARY") 14 | _write_mode.set_item_metadata(0, WebSocketPeer.WRITE_MODE_BINARY) 15 | _write_mode.add_item("TEXT") 16 | _write_mode.set_item_metadata(1, WebSocketPeer.WRITE_MODE_TEXT) 17 | 18 | _destination.add_item("Broadcast") 19 | _destination.set_item_metadata(0, 0) 20 | _destination.add_item("Last connected") 21 | _destination.set_item_metadata(1, 1) 22 | _destination.add_item("All But last connected") 23 | _destination.set_item_metadata(2, -1) 24 | _destination.select(0) 25 | 26 | func _on_Mode_item_selected( ID ): 27 | _client.set_write_mode(_write_mode.get_selected_metadata()) 28 | 29 | func _on_Send_pressed(): 30 | if _line_edit.text == "": 31 | return 32 | 33 | var dest = _destination.get_selected_metadata() 34 | if dest > 0: 35 | dest = _client.last_connected_client 36 | elif dest < 0: 37 | dest = -_client.last_connected_client 38 | 39 | Utils._log(_log_dest, "Sending data %s to %s" % [_line_edit.text, dest]) 40 | _client.send_data(_line_edit.text, dest) 41 | _line_edit.text = "" 42 | 43 | func _on_Connect_toggled( pressed ): 44 | if pressed: 45 | var multiplayer = _multiplayer.pressed 46 | if multiplayer: 47 | _write_mode.disabled = true 48 | else: 49 | _destination.disabled = true 50 | _multiplayer.disabled = true 51 | if _host.text != "": 52 | Utils._log(_log_dest, "Connecting to host: %s" % [_host.text]) 53 | _client.connect_to_url(_host.text, PoolStringArray(), multiplayer) 54 | else: 55 | _destination.disabled = false 56 | _write_mode.disabled = false 57 | _multiplayer.disabled = false 58 | _client.disconnect_from_host() 59 | -------------------------------------------------------------------------------- /websocket_chat_demo/combo/combo.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://server/server.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://client/client.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Combo" type="Control"] 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | mouse_filter = 1 10 | 11 | [node name="Box" type="HBoxContainer" parent="."] 12 | anchor_right = 1.0 13 | anchor_bottom = 1.0 14 | custom_constants/separation = 20 15 | 16 | [node name="ServerControl" parent="Box" instance=ExtResource( 1 )] 17 | anchor_right = 0.0 18 | anchor_bottom = 0.0 19 | margin_right = 502.0 20 | margin_bottom = 600.0 21 | size_flags_horizontal = 3 22 | 23 | [node name="VBoxContainer" type="VBoxContainer" parent="Box"] 24 | margin_left = 522.0 25 | margin_right = 1024.0 26 | margin_bottom = 600.0 27 | size_flags_horizontal = 3 28 | 29 | [node name="Client" parent="Box/VBoxContainer" instance=ExtResource( 2 )] 30 | anchor_right = 0.0 31 | anchor_bottom = 0.0 32 | margin_right = 502.0 33 | margin_bottom = 197.0 34 | size_flags_horizontal = 3 35 | size_flags_vertical = 3 36 | 37 | [node name="Client2" parent="Box/VBoxContainer" instance=ExtResource( 2 )] 38 | anchor_right = 0.0 39 | anchor_bottom = 0.0 40 | margin_top = 201.0 41 | margin_right = 502.0 42 | margin_bottom = 398.0 43 | size_flags_horizontal = 3 44 | size_flags_vertical = 3 45 | 46 | [node name="Client3" parent="Box/VBoxContainer" instance=ExtResource( 2 )] 47 | anchor_right = 0.0 48 | anchor_bottom = 0.0 49 | margin_top = 402.0 50 | margin_right = 502.0 51 | margin_bottom = 600.0 52 | size_flags_horizontal = 3 53 | size_flags_vertical = 3 54 | -------------------------------------------------------------------------------- /websocket_chat_demo/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 5 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 6 | sky_curve = 0.25 7 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 8 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 9 | ground_curve = 0.01 10 | sun_energy = 16.0 11 | 12 | [resource] 13 | background_mode = 2 14 | background_sky = SubResource( 1 ) 15 | ssao_blur = 1 16 | -------------------------------------------------------------------------------- /websocket_chat_demo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LudiDorici/godot-websocket/db42508f8abc580e1c02f690434598cc02d2ed77/websocket_chat_demo/icon.png -------------------------------------------------------------------------------- /websocket_chat_demo/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | 14 | } 15 | 16 | [application] 17 | 18 | config/name="Websocket Chat Demo" 19 | run/main_scene="res://combo/combo.tscn" 20 | config/icon="res://icon.png" 21 | 22 | [autoload] 23 | 24 | Utils="*res://utils.gd" 25 | 26 | [gdnative] 27 | 28 | singletons=[ ] 29 | 30 | [rendering] 31 | 32 | environment/default_environment="res://default_env.tres" 33 | -------------------------------------------------------------------------------- /websocket_chat_demo/server/server.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | onready var _log_dest = get_parent().get_node("Panel/VBoxContainer/RichTextLabel") 4 | 5 | var _server = WebSocketServer.new() 6 | var _clients = {} 7 | var _write_mode = WebSocketPeer.WRITE_MODE_BINARY 8 | var _use_multiplayer = true 9 | var last_connected_client = 0 10 | 11 | func _init(): 12 | _server.connect("client_connected", self, "_client_connected") 13 | _server.connect("client_disconnected", self, "_client_disconnected") 14 | _server.connect("client_close_request", self, "_client_close_request") 15 | _server.connect("data_received", self, "_client_receive") 16 | 17 | _server.connect("peer_packet", self, "_client_receive") 18 | _server.connect("peer_connected", self, "_client_connected", ["multiplayer_protocol"]) 19 | _server.connect("peer_disconnected", self, "_client_disconnected") 20 | 21 | func _exit_tree(): 22 | _clients.clear() 23 | _server.stop() 24 | 25 | func _process(delta): 26 | if _server.is_listening(): 27 | _server.poll() 28 | 29 | func _client_close_request(id, code, reason): 30 | Utils._log(_log_dest, "Client %s close code: %d, reason: %s" % [id, code, reason]) 31 | 32 | func _client_connected(id, protocol): 33 | _clients[id] = _server.get_peer(id) 34 | _clients[id].set_write_mode(_write_mode) 35 | last_connected_client = id 36 | Utils._log(_log_dest, "%s: Client connected with protocol %s" % [id, protocol]) 37 | 38 | func _client_disconnected(id, clean = true): 39 | Utils._log(_log_dest, "Client %s disconnected. Was clean: %s" % [id, clean]) 40 | if _clients.has(id): 41 | _clients.erase(id) 42 | 43 | func _client_receive(id): 44 | if _use_multiplayer: 45 | var peer_id = _server.get_packet_peer() 46 | var packet = _server.get_packet() 47 | Utils._log(_log_dest, "MPAPI: From %s data: %s" % [peer_id, Utils.decode_data(packet, false)]) 48 | else: 49 | var packet = _server.get_peer(id).get_packet() 50 | var is_string = _server.get_peer(id).was_string_packet() 51 | Utils._log(_log_dest, "Data from %s BINARY: %s: %s" % [id, not is_string, Utils.decode_data(packet, is_string)]) 52 | 53 | func send_data(data, dest): 54 | if _use_multiplayer: 55 | _server.set_target_peer(dest) 56 | _server.put_packet(Utils.encode_data(data, _write_mode)) 57 | else: 58 | for id in _clients: 59 | _server.get_peer(id).put_packet(Utils.encode_data(data, _write_mode)) 60 | 61 | func listen(port, supported_protocols, multiplayer): 62 | _use_multiplayer = multiplayer 63 | if _use_multiplayer: 64 | set_write_mode(WebSocketPeer.WRITE_MODE_BINARY) 65 | return _server.listen(port, supported_protocols, multiplayer) 66 | 67 | func stop(): 68 | _server.stop() 69 | 70 | func set_write_mode(mode): 71 | _write_mode = mode 72 | for c in _clients: 73 | _clients[c].set_write_mode(_write_mode) -------------------------------------------------------------------------------- /websocket_chat_demo/server/server.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://server/server_ui.gd" type="Script" id=1] 4 | [ext_resource path="res://server/server.gd" type="Script" id=2] 5 | 6 | [node name="ServerControl" type="Control"] 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | script = ExtResource( 1 ) 10 | 11 | [node name="Server" type="Node" parent="."] 12 | script = ExtResource( 2 ) 13 | 14 | [node name="Panel" type="Panel" parent="."] 15 | anchor_right = 1.0 16 | anchor_bottom = 1.0 17 | 18 | [node name="VBoxContainer" type="VBoxContainer" parent="Panel"] 19 | anchor_right = 1.0 20 | anchor_bottom = 1.0 21 | 22 | [node name="HBoxContainer" type="HBoxContainer" parent="Panel/VBoxContainer"] 23 | margin_right = 1024.0 24 | margin_bottom = 24.0 25 | 26 | [node name="Port" type="SpinBox" parent="Panel/VBoxContainer/HBoxContainer"] 27 | margin_right = 74.0 28 | margin_bottom = 24.0 29 | min_value = 1.0 30 | max_value = 65535.0 31 | value = 8000.0 32 | 33 | [node name="Listen" type="Button" parent="Panel/VBoxContainer/HBoxContainer"] 34 | margin_left = 78.0 35 | margin_right = 129.0 36 | margin_bottom = 24.0 37 | toggle_mode = true 38 | text = "Listen" 39 | 40 | [node name="HBoxContainer2" type="HBoxContainer" parent="Panel/VBoxContainer"] 41 | margin_top = 28.0 42 | margin_right = 1024.0 43 | margin_bottom = 52.0 44 | 45 | [node name="WriteMode" type="OptionButton" parent="Panel/VBoxContainer/HBoxContainer2"] 46 | margin_right = 41.0 47 | margin_bottom = 24.0 48 | 49 | [node name="MPAPI" type="CheckBox" parent="Panel/VBoxContainer/HBoxContainer2"] 50 | margin_left = 45.0 51 | margin_right = 171.0 52 | margin_bottom = 24.0 53 | pressed = true 54 | text = "Multiplayer API" 55 | 56 | [node name="Destination" type="OptionButton" parent="Panel/VBoxContainer/HBoxContainer2"] 57 | margin_left = 175.0 58 | margin_right = 216.0 59 | margin_bottom = 24.0 60 | 61 | [node name="HBoxContainer3" type="HBoxContainer" parent="Panel/VBoxContainer"] 62 | margin_top = 56.0 63 | margin_right = 1024.0 64 | margin_bottom = 80.0 65 | 66 | [node name="LineEdit" type="LineEdit" parent="Panel/VBoxContainer/HBoxContainer3"] 67 | margin_right = 977.0 68 | margin_bottom = 24.0 69 | size_flags_horizontal = 3 70 | 71 | [node name="Send" type="Button" parent="Panel/VBoxContainer/HBoxContainer3"] 72 | margin_left = 981.0 73 | margin_right = 1024.0 74 | margin_bottom = 24.0 75 | text = "Send" 76 | 77 | [node name="RichTextLabel" type="RichTextLabel" parent="Panel/VBoxContainer"] 78 | margin_top = 84.0 79 | margin_right = 1024.0 80 | margin_bottom = 600.0 81 | size_flags_vertical = 3 82 | [connection signal="toggled" from="Panel/VBoxContainer/HBoxContainer/Listen" to="." method="_on_Listen_toggled"] 83 | [connection signal="item_selected" from="Panel/VBoxContainer/HBoxContainer2/WriteMode" to="." method="_on_WriteMode_item_selected"] 84 | [connection signal="pressed" from="Panel/VBoxContainer/HBoxContainer3/Send" to="." method="_on_Send_pressed"] 85 | -------------------------------------------------------------------------------- /websocket_chat_demo/server/server_ui.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | onready var _server = get_node("Server") 4 | onready var _port = get_node("Panel/VBoxContainer/HBoxContainer/Port") 5 | onready var _line_edit = get_node("Panel/VBoxContainer/HBoxContainer3/LineEdit") 6 | onready var _write_mode = get_node("Panel/VBoxContainer/HBoxContainer2/WriteMode") 7 | onready var _log_dest = get_node("Panel/VBoxContainer/RichTextLabel") 8 | onready var _multiplayer = get_node("Panel/VBoxContainer/HBoxContainer2/MPAPI") 9 | onready var _destination = get_node("Panel/VBoxContainer/HBoxContainer2/Destination") 10 | 11 | func _ready(): 12 | _write_mode.clear() 13 | _write_mode.add_item("BINARY") 14 | _write_mode.set_item_metadata(0, WebSocketPeer.WRITE_MODE_BINARY) 15 | _write_mode.add_item("TEXT") 16 | _write_mode.set_item_metadata(1, WebSocketPeer.WRITE_MODE_TEXT) 17 | _write_mode.select(0) 18 | 19 | _destination.add_item("Broadcast") 20 | _destination.set_item_metadata(0, 0) 21 | _destination.add_item("Last connected") 22 | _destination.set_item_metadata(1, 1) 23 | _destination.add_item("All But last connected") 24 | _destination.set_item_metadata(2, -1) 25 | _destination.select(0) 26 | 27 | func _on_Listen_toggled( pressed ): 28 | if pressed: 29 | var use_multiplayer = _multiplayer.pressed 30 | _multiplayer.disabled = true 31 | var supported_protocols = [] # Optional array of sub protocols. 32 | var port = int(_port.value) 33 | if use_multiplayer: 34 | _write_mode.disabled = true 35 | _write_mode.select(0) 36 | else: 37 | _destination.disabled = true 38 | _destination.select(0) 39 | if _server.listen(port, supported_protocols, use_multiplayer) == OK: 40 | Utils._log(_log_dest, "Listing on port %s" % port) 41 | Utils._log(_log_dest, "Supported protocols: %s" % str(supported_protocols)) 42 | else: 43 | Utils._log(_log_dest, "Error listening on port %s" % port) 44 | else: 45 | _server.stop() 46 | _multiplayer.disabled = false 47 | _write_mode.disabled = false 48 | _destination.disabled = false 49 | Utils._log(_log_dest, "Server stopped") 50 | 51 | func _on_Send_pressed(): 52 | if _line_edit.text == "": 53 | return 54 | 55 | var dest = _destination.get_selected_metadata() 56 | if dest > 0: 57 | dest = _server.last_connected_client 58 | elif dest < 0: 59 | dest = -_server.last_connected_client 60 | 61 | Utils._log(_log_dest, "Sending data %s to %s" % [_line_edit.text, dest]) 62 | _server.send_data(_line_edit.text, dest) 63 | _line_edit.text = "" 64 | 65 | func _on_WriteMode_item_selected( ID ): 66 | _server.set_write_mode(_write_mode.get_selected_metadata()) 67 | -------------------------------------------------------------------------------- /websocket_chat_demo/utils.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | func encode_data(data, mode): 4 | return data.to_utf8() if mode == WebSocketPeer.WRITE_MODE_TEXT else var2bytes(data) 5 | 6 | func decode_data(data, is_string): 7 | return data.get_string_from_utf8() if is_string else bytes2var(data) 8 | 9 | func _log(node, msg): 10 | print(msg) 11 | node.add_text(str(msg) + "\n") --------------------------------------------------------------------------------