Browse Source

initial implementation

Arnis Lielturks 5 years ago
parent
commit
e328d95bfb
100 changed files with 18034 additions and 5 deletions
  1. 7 0
      CMake/Modules/UrhoCommon.cmake
  2. 3 0
      CMakeLists.txt
  3. 4 0
      Source/CMakeLists.txt
  4. 28 5
      Source/Samples/17_SceneReplication/SceneReplication.cpp
  5. 2 0
      Source/Samples/Sample.inl
  6. 64 0
      Source/ThirdParty/libwebsockets/.gitignore
  7. 3 0
      Source/ThirdParty/libwebsockets/.mailmap
  8. 198 0
      Source/ThirdParty/libwebsockets/.sai.json
  9. 412 0
      Source/ThirdParty/libwebsockets/CMakeLists-implied-options.txt
  10. 970 0
      Source/ThirdParty/libwebsockets/CMakeLists.txt
  11. 32 0
      Source/ThirdParty/libwebsockets/Kconfig
  12. 56 0
      Source/ThirdParty/libwebsockets/LICENSE
  13. 1 0
      Source/ThirdParty/libwebsockets/Makefile.projbuild
  14. 444 0
      Source/ThirdParty/libwebsockets/README.md
  15. 100 0
      Source/ThirdParty/libwebsockets/READMEs/README.async-dns.md
  16. 77 0
      Source/ThirdParty/libwebsockets/READMEs/README.build-android.md
  17. 214 0
      Source/ThirdParty/libwebsockets/READMEs/README.build-windows.md
  18. 741 0
      Source/ThirdParty/libwebsockets/READMEs/README.build.md
  19. 88 0
      Source/ThirdParty/libwebsockets/READMEs/README.captive-portal-detection.md
  20. 29 0
      Source/ThirdParty/libwebsockets/READMEs/README.ci.md
  21. 41 0
      Source/ThirdParty/libwebsockets/READMEs/README.cmake.md
  22. 1373 0
      Source/ThirdParty/libwebsockets/READMEs/README.coding.md
  23. 148 0
      Source/ThirdParty/libwebsockets/READMEs/README.content-security-policy.md
  24. 41 0
      Source/ThirdParty/libwebsockets/READMEs/README.contributing.md
  25. 181 0
      Source/ThirdParty/libwebsockets/READMEs/README.crypto-apis.md
  26. 67 0
      Source/ThirdParty/libwebsockets/READMEs/README.ctest.md
  27. 63 0
      Source/ThirdParty/libwebsockets/READMEs/README.debugging.md
  28. 117 0
      Source/ThirdParty/libwebsockets/READMEs/README.detailed-latency.md
  29. 37 0
      Source/ThirdParty/libwebsockets/READMEs/README.esp32.md
  30. 80 0
      Source/ThirdParty/libwebsockets/READMEs/README.event-libs.md
  31. 55 0
      Source/ThirdParty/libwebsockets/READMEs/README.h2-long-poll.md
  32. 172 0
      Source/ThirdParty/libwebsockets/READMEs/README.http-fallback.md
  33. 176 0
      Source/ThirdParty/libwebsockets/READMEs/README.jwt.md
  34. 43 0
      Source/ThirdParty/libwebsockets/READMEs/README.lifecycle.md
  35. 130 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_dll.md
  36. 105 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_plugins.md
  37. 98 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_retry.md
  38. 149 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_sequencer.md
  39. 38 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_struct.md
  40. 99 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_sul.md
  41. 219 0
      Source/ThirdParty/libwebsockets/READMEs/README.lws_system.md
  42. 702 0
      Source/ThirdParty/libwebsockets/READMEs/README.lwsws.md
  43. 180 0
      Source/ThirdParty/libwebsockets/READMEs/README.plugin-acme.md
  44. 249 0
      Source/ThirdParty/libwebsockets/READMEs/README.plugin-sshd-base.md
  45. 60 0
      Source/ThirdParty/libwebsockets/READMEs/README.porting.md
  46. 66 0
      Source/ThirdParty/libwebsockets/READMEs/README.problems.md
  47. 126 0
      Source/ThirdParty/libwebsockets/READMEs/README.release-policy.md
  48. 448 0
      Source/ThirdParty/libwebsockets/READMEs/README.test-apps.md
  49. 50 0
      Source/ThirdParty/libwebsockets/READMEs/README.udp.md
  50. 101 0
      Source/ThirdParty/libwebsockets/READMEs/README.unix-domain-reverse-proxy.md
  51. 12 0
      Source/ThirdParty/libwebsockets/READMEs/README.vulnerability-reporting.md
  52. 23 0
      Source/ThirdParty/libwebsockets/READMEs/mainpage.md
  53. 65 0
      Source/ThirdParty/libwebsockets/READMEs/release-checklist
  54. 37 0
      Source/ThirdParty/libwebsockets/bug_report.md
  55. 629 0
      Source/ThirdParty/libwebsockets/changelog
  56. 105 0
      Source/ThirdParty/libwebsockets/cmake-build-debug/DartConfiguration.tcl
  57. 471 0
      Source/ThirdParty/libwebsockets/cmake-build-debug/libwebsockets.cbp
  58. 12 0
      Source/ThirdParty/libwebsockets/cmake-build-debug/libwebsockets_static.pc
  59. 197 0
      Source/ThirdParty/libwebsockets/cmake-build-debug/lws_config.h
  60. 108 0
      Source/ThirdParty/libwebsockets/cmake-build-debug/lws_config_private.h
  61. 11 0
      Source/ThirdParty/libwebsockets/cmake/libwebsockets-config-version.cmake.in
  62. 23 0
      Source/ThirdParty/libwebsockets/cmake/libwebsockets-config.cmake.in
  63. 197 0
      Source/ThirdParty/libwebsockets/cmake/lws_config.h.in
  64. 108 0
      Source/ThirdParty/libwebsockets/cmake/lws_config_private.h.in
  65. 45 0
      Source/ThirdParty/libwebsockets/component.mk
  66. 29 0
      Source/ThirdParty/libwebsockets/contrib/Android.mk
  67. 58 0
      Source/ThirdParty/libwebsockets/contrib/abi/README.md
  68. 257 0
      Source/ThirdParty/libwebsockets/contrib/abi/libwebsockets.json
  69. 17 0
      Source/ThirdParty/libwebsockets/contrib/abi/lws-abi-update.sh
  70. 97 0
      Source/ThirdParty/libwebsockets/contrib/cross-openwrt-makefile
  71. 653 0
      Source/ThirdParty/libwebsockets/include/libwebsockets.h
  72. 138 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/abstract.h
  73. 88 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/protocols.h
  74. 115 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/protocols/smtp.h
  75. 65 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports.h
  76. 29 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports/raw-skt.h
  77. 81 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports/unit-test.h
  78. 233 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-adopt.h
  79. 87 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-async-dns.h
  80. 66 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-bb-i2c.h
  81. 62 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-bb-spi.h
  82. 120 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-button.h
  83. 910 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-callbacks.h
  84. 104 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-cgi.h
  85. 343 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-client.h
  86. 1215 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-context-vhost.h
  87. 94 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dbus.h
  88. 140 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-detailed-latency.h
  89. 187 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-diskcache.h
  90. 158 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-display.h
  91. 298 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dll2.h
  92. 145 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dsh.h
  93. 61 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-eventlib-exports.h
  94. 87 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-freertos.h
  95. 215 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-fts.h
  96. 170 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genaes.h
  97. 130 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-gencrypto.h
  98. 211 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genec.h
  99. 187 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genhash.h
  100. 254 0
      Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genrsa.h

+ 7 - 0
CMake/Modules/UrhoCommon.cmake

@@ -895,6 +895,13 @@ macro (define_dependency_libs TARGET)
         endif ()
     endif ()
 
+    # ThirdParty/Civetweb external dependency
+    if (${TARGET} MATCHES Urho3D)
+        if (URHO3D_WEBSOCKETS)
+            list (APPEND LIBS websockets)
+        endif ()
+    endif ()
+
     # Urho3D/LuaJIT external dependency
     if (URHO3D_LUAJIT AND ${TARGET} MATCHES LuaJIT|Urho3D)
         if (NOT WIN32 AND NOT WEB)

+ 3 - 0
CMakeLists.txt

@@ -173,6 +173,9 @@ if (URHO3D_MACOSX_BUNDLE OR (APPLE AND ARM))
     endif ()
 endif ()
 
+set (URHO3D_WEBSOCKETS TRUE)
+set (URHO3D_PCH FALSE)
+
 # Setup SDK-like include dir in the build tree for building the Urho3D library
 if (ANDROID AND GRADLE_BUILD_DIR)
     set (THIRD_PARTY_INCLUDE_DIR ${GRADLE_BUILD_DIR}/tree/${CMAKE_BUILD_TYPE}/${ANDROID_ABI}/${DEST_INCLUDE_DIR}/ThirdParty)

+ 4 - 0
Source/CMakeLists.txt

@@ -89,6 +89,10 @@ if (URHO3D_NETWORK)
     add_subdirectory (ThirdParty/SLikeNet)
 endif ()
 
+if (URHO3D_WEBSOCKETS)
+    add_subdirectory (ThirdParty/libwebsockets)
+endif ()
+
 if (URHO3D_DATABASE_ODBC)
     add_subdirectory (ThirdParty/nanodbc)
 endif ()

+ 28 - 5
Source/Samples/17_SceneReplication/SceneReplication.cpp

@@ -20,6 +20,8 @@
 // THE SOFTWARE.
 //
 
+#define URHO3D_WEBSOCKETS
+
 #include <Urho3D/Core/CoreEvents.h>
 #include <Urho3D/Engine/Engine.h>
 #include <Urho3D/Graphics/Camera.h>
@@ -69,6 +71,8 @@ static const unsigned CTRL_RIGHT = 8;
 
 URHO3D_DEFINE_APPLICATION_MAIN(SceneReplication)
 
+bool isClient = false;
+
 SceneReplication::SceneReplication(Context* context) :
     Sample(context)
 {
@@ -93,6 +97,9 @@ void SceneReplication::Start()
 
     // Set the mouse mode to use in the sample
     Sample::InitMouseMode(MM_RELATIVE);
+
+    auto* network = GetSubsystem<Network>();
+    network->SetUpdateFps(30);
 }
 
 void SceneReplication::CreateScene()
@@ -322,6 +329,13 @@ void SceneReplication::MoveCamera()
     // Mouse sensitivity as degrees per pixel
     const float MOUSE_SENSITIVITY = 0.1f;
 
+    if (input->GetKeyPress(KEY_P)) {
+//        scene_->SetUpdateEnabled(!scene_->IsUpdateEnabled());
+//        scene_->CreateComponent<PhysicsWorld>(LOCAL);
+//        UnsubscribeFromEvent(E_PHYSICSPRESTEP);
+//        SubscribeToEvent(E_PHYSICSPRESTEP, URHO3D_HANDLER(SceneReplication, HandlePhysicsPreStep));
+    }
+
     // Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch and only move the camera
     // when the cursor is hidden
     if (!ui->GetCursor()->IsVisible())
@@ -360,8 +374,8 @@ void SceneReplication::HandlePostUpdate(StringHash eventType, VariantMap& eventD
 
     if (packetCounterTimer_.GetMSec(false) > 1000 && GetSubsystem<Network>()->GetServerConnection())
     {
-        packetsIn_->SetText("Packets  in: " + String(GetSubsystem<Network>()->GetServerConnection()->GetPacketsInPerSec()));
-        packetsOut_->SetText("Packets out: " + String(GetSubsystem<Network>()->GetServerConnection()->GetPacketsOutPerSec()));
+        packetsIn_->SetText("Packets  in (as client) : " + String(GetSubsystem<Network>()->GetServerConnection()->GetPacketsInPerSec()));
+        packetsOut_->SetText("Packets out (as client): " + String(GetSubsystem<Network>()->GetServerConnection()->GetPacketsOutPerSec()));
         packetCounterTimer_.Reset();
     }
     if (packetCounterTimer_.GetMSec(false) > 1000 && GetSubsystem<Network>()->GetClientConnections().Size())
@@ -373,8 +387,8 @@ void SceneReplication::HandlePostUpdate(StringHash eventType, VariantMap& eventD
             packetsIn += (*it)->GetPacketsInPerSec();
             packetsOut += (*it)->GetPacketsOutPerSec();
         }
-        packetsIn_->SetText("Packets  in: " + String(packetsIn));
-        packetsOut_->SetText("Packets out: " + String(packetsOut));
+        packetsIn_->SetText("Packets  in (as server)[" + String(connections.Size()) + "] : " + String(packetsIn));
+        packetsOut_->SetText("Packets out (as server)[" + String(connections.Size()) + "]: " + String(packetsOut));
         packetCounterTimer_.Reset();
     }
 }
@@ -387,6 +401,9 @@ void SceneReplication::HandlePhysicsPreStep(StringHash eventType, VariantMap& ev
     auto* network = GetSubsystem<Network>();
     Connection* serverConnection = network->GetServerConnection();
 
+    if (isClient) {
+        serverConnection;
+    }
     // Client: collect controls
     if (serverConnection)
     {
@@ -444,6 +461,8 @@ void SceneReplication::HandlePhysicsPreStep(StringHash eventType, VariantMap& ev
                 body->ApplyTorque(rotation * Vector3::FORWARD * MOVE_TORQUE);
             if (controls.buttons_ & CTRL_RIGHT)
                 body->ApplyTorque(rotation * Vector3::BACK * MOVE_TORQUE);
+
+            body->ApplyTorque(rotation * Vector3::RIGHT * MOVE_TORQUE * 0.1);
         }
     }
 }
@@ -457,8 +476,10 @@ void SceneReplication::HandleConnect(StringHash eventType, VariantMap& eventData
 
     // Connect to server, specify scene to use as a client for replication
     clientObjectID_ = 0; // Reset own object ID from possible previous connection
-    network->Connect(address, SERVER_PORT, scene_);
+//    network->Connect(address, SERVER_PORT, scene_);
+    network->ConnectWS(address, SERVER_PORT, scene_);
 
+    isClient = true;
     UpdateButtons();
 }
 
@@ -508,6 +529,7 @@ void SceneReplication::HandleClientConnected(StringHash eventType, VariantMap& e
     // Then create a controllable object for that client
     Node* newObject = CreateControllableObject();
     serverObjects_[newConnection] = newObject;
+    cameraNode_->SetPosition(newObject->GetWorldPosition());
 
     // Finally send the object's node ID using a remote event
     VariantMap remoteEventData;
@@ -531,4 +553,5 @@ void SceneReplication::HandleClientDisconnected(StringHash eventType, VariantMap
 void SceneReplication::HandleClientObjectID(StringHash eventType, VariantMap& eventData)
 {
     clientObjectID_ = eventData[P_ID].GetUInt();
+    URHO3D_LOGINFOF("Received client object ID %d", clientObjectID_);
 }

+ 2 - 0
Source/Samples/Sample.inl

@@ -62,6 +62,8 @@ void Sample::Setup()
     engineParameters_[EP_FULL_SCREEN]  = false;
     engineParameters_[EP_HEADLESS]     = false;
     engineParameters_[EP_SOUND]        = false;
+    engineParameters_[EP_WINDOW_WIDTH] = 640;
+    engineParameters_[EP_WINDOW_HEIGHT] = 480;
 
     // Construct a search path to find the resource prefix with two entries:
     // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree

+ 64 - 0
Source/ThirdParty/libwebsockets/.gitignore

@@ -0,0 +1,64 @@
+#Ignore build files
+CMakeCache.txt
+CMakeFiles
+build
+cmake_install.cmake
+lws-minimal*
+Makefile
+.cproject
+.project
+config.h
+config.log
+config.status
+libtool
+stamp-h1
+output/
+win32port/ipch/
+win32port/Debug*/
+win32port/Release*/
+win32port/server/Debug*/
+win32port/server/Release*/
+win32port/client/Debug*/
+win32port/client/Release*/
+win32port/libwebsocketswin32/Debug*/
+win32port/libwebsocketswin32/Release*/
+win32port/zlib/Debug*/
+win32port/zlib/Release*/
+*.vcxproj.user
+*.opensdf
+*.sdf
+*.suo
+*.su
+*.m4
+*.a
+missing
+depcomp
+install-sh
+configure
+compile
+config.guess
+*~
+*.orig
+autom4te.cache/
+ltmain.sh
+config.sub
+ar-lib
+libwebsockets.pc
+build/
+*.swp
+doc
+/build2/
+/build3/
+/cov-int/
+/.vs/
+/build-mtls/
+/build-mingw64/
+/n9/
+/bb/
+/openssl3/
+/bb-linkit/
+/bq/
+/cros/
+/q/
+/b1/
+/destdir/

+ 3 - 0
Source/ThirdParty/libwebsockets/.mailmap

@@ -0,0 +1,3 @@
+Andy Green <[email protected]> <[email protected]>
+Joakim Söderberg <[email protected]>
+

+ 198 - 0
Source/ThirdParty/libwebsockets/.sai.json

@@ -0,0 +1,198 @@
+{
+	"schema": "sai-1",
+
+	# We're doing separate install into destdir so that the test server
+	# has somewhere to go to find its /usr/share content like certs
+
+	"platforms": {
+		"linux-ubuntu-1804/x86_64-amd/gcc": {
+			"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G DEB\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+		"linux-ubuntu-2004/x86_64-amd/gcc": {
+			"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G DEB\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+		"linux-fedora-32/x86_64-amd/gcc": {
+			"build": "rm -rf build destdir ; mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G RPM\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+		"linux-gentoo/x86_64-amd/gcc": {
+			"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G ZIP\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+		"linux-centos-8/x86_64-amd/gcc": {
+			"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G RPM\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+		"linux-ubuntu-2004/aarch64-a72-bcm2711-rpi4/gcc": {
+			"build": "mkdir build;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G DEB\";cmake .. ${cmake} && make -j3 && make -j DESTDIR=../destdir install && ctest -j3 --output-on-failure ${cpack}",
+			"default": false
+		},
+		"linux-android/aarch64/llvm": {
+			"build": "mkdir build;cd build;cmake .. -DCMAKE_TOOLCHAIN_FILE=../libwebsockets/contrib/cross-aarch64-android.cmake ${cmake} && make -j",
+			"default": false
+		},
+		"netbsd-iOS/aarch64/llvm": {
+			"build": "mkdir build destdir; cd build; export SAI_CPACK=\"-G ZIP\";cmake .. -DCMAKE_MAKE_PROGRAM=/usr/bin/make -DCMAKE_IOS_DEVELOPER_ROOT=/opt/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer -DCMAKE_TOOLCHAIN_FILE=contrib/iOS.cmake -DIOS_PLATFORM=OS ${cmake} && make -j",
+			"default": false
+		},
+		"netbsd-OSX-catalina/x86_64-intel-i3/llvm": {
+			"build": "mkdir build destdir; cd build; export SAI_CPACK=\"-G ZIP\";export MACOSX_DEPLOYMENT_TARGET=10.14 ; cmake .. -DCMAKE_MAKE_PROGRAM=/usr/bin/make -DLWS_OPENSSL_INCLUDE_DIRS=/usr/local/opt/[email protected]/include -DLWS_OPENSSL_LIBRARIES=\"/usr/local/opt/openssl/lib/libssl.dylib;/usr/local/opt/openssl/lib/libcrypto.dylib\" ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
+		},
+
+		"freertos-linkit/arm32-m4-mt7697-usi/gcc": {
+			"build": "mkdir build;cd build;export CCACHE_DISABLE=1;cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/tmp -DCMAKE_TOOLCHAIN_FILE=../contrib/cross-linkit.cmake -DLWS_PLAT_FREERTOS=1 -DLWS_WITH_ZLIB=0 -DLWS_WITHOUT_EXTENSIONS=1 -DLWS_WITH_ZIP_FOPS=0 -DLWS_WITH_HTTP_STREAM_COMPRESSION=0 -DLWS_WITH_MBEDTLS=1 -DLWS_WITH_FILE_OPS=0 ${cmake};make -j",
+			"default": false
+		},
+		"windows-10/x86_64-amd/msvc": {
+			"build": "mkdir build && cd build && set SAI_CPACK=\"-G ZIP\" && cmake .. -DLWS_OPENSSL_LIBRARIES=\"C:\\Program Files\\OpenSSL\\lib\\libssl.lib;C:\\Program Files\\OpenSSL\\lib\\libcrypto.lib\" -DLWS_OPENSSL_INCLUDE_DIRS=\"C:\\Program Files\\OpenSSL\\include\" -DLWS_EXT_PTHREAD_INCLUDE_DIR=\"C:\\Program Files (x86)\\pthreads\\include\" -DLWS_EXT_PTHREAD_LIBRARIES=\"C:\\Program Files (x86)\\pthreads\\lib\\x64\\libpthreadGC2.a\" ${cmake} && cmake --build . --config DEBUG && set CTEST_OUTPUT_ON_FAILURE=1 && ctest . -C DEBUG -j4 --output-on-failure",
+			"default": false
+		},
+		"windows-10/x86_64-amd/mingw32": {
+			"build": "mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=../contrib/cross-w32.cmake ${cmake} && cmake --build . --config DEBUG",
+			"default": false
+		},
+		"windows-10/x86_64-amd/mingw64": {
+			"build": "mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=../contrib/cross-w64.cmake ${cmake} && cmake --build . --config DEBUG",
+			"default": false
+		},
+		"freertos-espidf/xl6-esp32/gcc": {
+			# official way to get sdkconfig.h is idf.py menuconfig, but
+			# no obvious way to do that in CI
+			"build":	"rm -rf ebuild ; mkdir ebuild; cd ebuild; cp -rp ../minimal-examples/embedded/esp32/${cpack} . ;  cd ${cpack} ; . /opt/esp/esp-idf/export.sh ; ln -sf ../.. libwebsockets ; idf.py set-target esp32 && cp libwebsockets/minimal-examples/embedded/esp32/${cpack}/sdkconfig . && cp sdkconfig.h build && idf.py ${cmake} build size size-components size-files && cd build && /usr/local/bin/sai-device ${cpack} ESPPORT=0 ctest --output-on-failure",
+			"default":	false
+		},
+		"linux-fedora-32/riscv64-virt/gcc": {
+			"build":	"mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G RPM\";cmake .. ${cmake} && make -j12 && make -j12 DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}",
+			"default":	false
+		},
+		"freebsd-12/x86_64-amd/llvm": {
+			"build":	"mkdir build destdir;cd build;export CCACHE_DISABLE=1;cmake .. ${cmake} && make -j12 && make -j12 DESTDIR=../destdir install"
+		}
+	},
+
+	"configurations": {
+		"default": {
+			"cmake":	"",
+			"platforms":	"windows-10/x86_64-amd/msvc, freertos-linkit/arm32-m4-mt7697-usi/gcc, linux-ubuntu-2004/aarch64-a72-bcm2711-rpi4/gcc, windows-10/x86_64-amd/mingw32, windows-10/x86_64-amd/mingw64"
+		},
+		"esp32-heltec": {
+			"cmake":	"",
+			"cpack":	"esp-heltec-wb32",
+			"platforms":	"none, freertos-espidf/xl6-esp32/gcc"
+		},
+		"esp32-wrover": {
+			"cmake":	"",
+			"cpack":	"esp-wrover-kit",
+			"platforms":	"none, freertos-espidf/xl6-esp32/gcc"
+		},
+		"esp32-wrover-static": {
+			"cmake":	"-DLWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY=1 ",
+			"cpack":	"esp-wrover-kit",
+			"platforms":	"none, freertos-espidf/xl6-esp32/gcc"
+		},
+
+#		"default-examples-openssl-v3": {
+#			"cmake":	"-DLWS_OPENSSL_LIBRARIES=\"/usr/local/src/openssl/v3/usr/local/lib64/libssl.a;/usr/local/src/openssl/v3/usr/local/lib64/libcrypto.a\" -DLWS_OPENSSL_INCLUDE_DIRS=\"/usr/local/src/openssl/v3/usr/local/include/\" -DLWS_WITH_MINIMAL_EXAMPLES=1 -DLWS_WITH_GENCRYPTO=1",
+#			"platforms":	"none,linux-fedora-32/x86_64-amd/gcc"
+#		},
+		"default-examples-boringssl": {
+			"cmake":	"cmake .. -DLWS_WITH_BORINGSSL=1 -DLWS_OPENSSL_INCLUDE_DIRS=\"/usr/local/src/boringssl/include\" -DLWS_OPENSSL_LIBRARIES=\"/usr/local/src/boringssl/build/ssl/libssl.so;/usr/local/src/boringssl/build/crypto/libcrypto.so\" -DLWS_WITH_MINIMAL_EXAMPLES=1",
+			"platforms":	"none,linux-fedora-32/x86_64-amd/gcc"
+		},
+		"default-wolfssl": {
+			"cmake":	"-DLWS_WITH_WOLFSSL=1 -DLWS_WOLFSSL_INCLUDE_DIRS=/usr/local/include -DLWS_WOLFSSL_LIBRARIES=/usr/local/lib/libwolfssl.so",
+			"platforms":	"none,linux-fedora-32/x86_64-amd/gcc"
+		},
+		"default-examples": {
+			"cmake":	"-DLWS_WITH_MINIMAL_EXAMPLES=1",
+			"platforms":	"windows-10/x86_64-amd/msvc, linux-ubuntu-2004/aarch64-a72-bcm2711-rpi4/gcc"
+		},
+		"unix-domain": {
+			"cmake":	"-DUNIX_SOCK=1",
+			"platforms":	"windows-10/x86_64-amd/msvc"
+		},
+		"lws_system": {
+			"cmake":	"-DLWS_WITH_ACME=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DCMAKE_BUILD_TYPE=RELEASE -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_JOSE=1 -DLWS_WITH_SYS_ASYNC_DNS=1 -DLWS_WITH_SYS_NTPCLIENT=1",
+			"platforms":	"windows-10/x86_64-amd/msvc"
+		},
+		"secure-streams": {
+			"cmake":	"-DLWS_WITH_SECURE_STREAMS=1",
+			"platforms":	"windows-10/x86_64-amd/msvc"
+		},
+		"secure-streams-proxy": {
+			"cmake":	"-DLWS_WITH_SECURE_STREAMS=1 -DLWS_WITH_SECURE_STREAMS_PROXY_API=1",
+			"platforms":	"not windows-10/x86_64-amd/msvc"
+		},
+		"distro_recommended": {
+			"cmake":	"-DLWS_WITH_DISTRO_RECOMMENDED=1",
+			"platforms":	"not freebsd-12/x86_64-amd/llvm, not linkit-cross, not windows-10/x86_64-amd/msvc, linux-ubuntu-2004/aarch64-a72-bcm2711-rpi4/gcc, linux-fedora-32/riscv64-virt/gcc",
+			"cpack":	"&& cpack $SAI_CPACK",
+			"artifacts":	"build/*.rpm, build/*.deb, build/*.zip"
+		},
+		"lwsws": {
+			"cmake":	"-DLWS_WITH_LWSWS=ON -DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_HTTP2=1 -DLWS_WITH_ACME=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DCMAKE_BUILD_TYPE=DEBUG -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_JOSE=1 -DLWS_WITH_SYS_ASYNC_DNS=1 -DLWS_WITH_SYS_NTPCLIENT=1",
+			# no distro -devel package for libuv
+			"platforms":	"not linux-centos-8/x86_64-amd/gcc"
+		},
+		"lwsws2": {
+			"cmake":	"-DLWS_WITH_LWSWS=ON -DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_HTTP2=1 -DLWS_WITH_ACME=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DCMAKE_BUILD_TYPE=DEBUG -DLWS_WITH_LWS_DSH=1",
+			# no distro -devel package for libuv
+			"platforms":	"not linux-centos-8/x86_64-amd/gcc"
+		},
+		"justmbedtls": {
+			"cmake": "-DLWS_WITH_MBEDTLS=1 -DLWS_WITHOUT_TESTAPPS=1",
+			"platforms": "none, linux-android/aarch64/llvm"
+		},
+		"mbedtls": {
+			"cmake":	"-DLWS_WITH_MBEDTLS=1 -DLWS_WITH_HTTP2=1 -DLWS_WITH_LWSWS=1 -DLWS_WITH_MINIMAL_EXAMPLES=1 -DLWS_WITH_JOSE=1 -DCMAKE_BUILD_TYPE=DEBUG",
+			# no distro -devel package for mbedtls
+			"platforms":	"not linux-centos-8/x86_64-amd/gcc"
+		},
+		"noserver": {
+			"cmake":	"-DLWS_WITHOUT_SERVER=ON -DLWS_WITH_MINIMAL_EXAMPLES=1"
+		},
+		"noclient": {
+			"cmake":	"-DLWS_WITHOUT_CLIENT=ON -DLWS_WITH_MINIMAL_EXAMPLES=1"
+		},
+		"ext": {
+			"cmake":	"-DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_MINIMAL_EXAMPLES=1"
+		},
+		"nonetwork": {
+			"cmake":	"-DLWS_WITH_NETWORK=0"
+		},
+		"libev": {
+			"cmake":	"-DLWS_WITH_LIBEV=ON"
+		},
+		"libevent": {
+			"cmake":	"-DLWS_WITH_LIBEVENT=ON"
+		},
+		"libglib": {
+			"cmake":	"-DLWS_WITH_GLIB=ON"
+		},
+		"ipv6":	{
+			"cmake":	"-DLWS_IPV6=ON",
+			"platforms":	"windows-10/x86_64-amd/mingw64, windows-10/x86_64-amd/msvc"
+		},
+		"nossl": {
+			"cmake":	"-DLWS_WITH_SSL=OFF",
+			"platforms":	"netbsd-iOS/aarch64/llvm"
+		},
+		"daemon": {
+			"cmake":	"-DLWS_WITHOUT_DAEMONIZE=OFF"
+		},
+		"cgi": {
+			"cmake":	"-DLWS_WITH_CGI=ON"
+		},
+		"nologs": {
+			"cmake":	"-DLWS_WITH_NO_LOGS=ON"
+		},
+		"smp": {
+			"cmake":	"-DLWS_MAX_SMP=32 -DLWS_WITH_MINIMAL_EXAMPLES=1"
+		},
+		"nows": {
+			"cmake":	"-DLWS_ROLE_WS=0"
+		},
+		"threadpool": {
+			"cmake":	"-DLWS_WITH_THREADPOOL=1 -DLWS_WITH_MINIMAL_EXAMPLES=1",
+			"platforms":	"windows-10/x86_64-amd/msvc"
+		}
+	}
+}
+

+ 412 - 0
Source/ThirdParty/libwebsockets/CMakeLists-implied-options.txt

@@ -0,0 +1,412 @@
+#
+# libwebsockets - small server side websockets and web server implementation
+#
+# Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# This part of the CMakeLists.txt defines internal logic between options
+
+if(IOS)
+    set(LWS_DETECTED_PLAT_IOS 1)
+endif()
+
+# Workaround for ESP-IDF
+# Detect ESP_PLATFORM environment flag, if exist, set LWS_WITH_ESP32.
+# Otherwise the user may not be able to run configuration ESP-IDF in the first time.
+if (ESP_PLATFORM)
+	message(STATUS "ESP-IDF enabled")
+	set(LWS_WITH_ESP32 ON)
+	set(LWS_WITH_ZLIB OFF)
+	set(LWS_HAVE_mbedtls_ssl_get_alpn_protocol 1)
+else()
+	set(LWS_WITH_ESP32_HELPER OFF)
+endif()
+
+if (LWS_WITH_ESP32)
+	set(LWS_PLAT_FREERTOS 1)
+endif()
+
+if (LWS_PLAT_OPTEE)
+	set(LWS_WITH_UDP 0)
+endif()
+
+if (LWS_PLAT_FREERTOS)
+	message(STATUS "No LWS_WITH_DIR or LWS_WITH_LEJP_CONF")
+	set(LWS_WITH_DIR OFF)
+	set(LWS_WITH_LEJP_CONF OFF)
+	message("LWS_WITH_DIR ${LWS_WITH_DIR}")
+else()
+	message(STATUS "Compiled with LWS_WITH_DIR and LWS_WITH_LEJP_CONF")
+	set(LWS_WITH_DIR ON)
+	set(LWS_WITH_LEJP_CONF ON)
+endif()
+
+if (LWS_FOR_GITOHASHI)
+	set(LWS_WITH_THREADPOOL 1)
+	set(LWS_WITH_HTTP2 1)
+	set(LWS_UNIX_SOCK 1)
+	set(LWS_WITH_HTTP_PROXY 1)
+	set(LWS_WITH_FTS 1)
+	set(LWS_WITH_DISKCACHE 1)
+	set(LWS_WITH_LWSAC 1)
+	set(LWS_WITH_LEJP_CONF 1)
+	set(LWS_WITH_SPAWN 1)
+	set(LWS_WITH_FSMOUNT 1)
+	set(LWS_WITH_STRUCT_JSON 1)
+	set(LWS_WITH_STRUCT_SQLITE3 1)
+endif()
+
+if(LWS_WITH_DISTRO_RECOMMENDED)
+	set(LWS_WITH_HTTP2 1)				# selfcontained
+	set(LWS_WITH_LWSWS 1)				# libuv
+	set(LWS_WITH_CGI 1)				# selfcontained
+	set(LWS_IPV6 1)					# selfcontained
+	set(LWS_WITH_ZIP_FOPS 1)			# libz
+	set(LWS_WITH_SOCKS5 1)				# selfcontained
+	set(LWS_WITH_RANGES 1)				# selfcontained
+	set(LWS_WITH_ACME 1)				# selfcontained / tls
+	set(LWS_WITH_SERVER_STATUS 1)			# selfcontained
+	set(LWS_WITH_GLIB 1)				# glib
+	set(LWS_WITH_LIBUV 1)				# libuv
+	set(LWS_WITH_LIBEV 1)				# libev
+	set(LWS_WITH_LIBEVENT 1)			# libevent
+	set(LWS_WITH_EVLIB_PLUGINS 1)			# event libraries created as plugins / individual packages
+	set(LWS_WITHOUT_EXTENSIONS 0)			# libz
+	set(LWS_ROLE_DBUS 1)				# dbus-related libs
+	set(LWS_WITH_FTS 1)				# selfcontained
+	set(LWS_WITH_THREADPOOL 1)			# pthreads
+	set(LWS_UNIX_SOCK 1)				# selfcontained
+	set(LWS_WITH_HTTP_PROXY 1)			# selfcontained
+	set(LWS_WITH_DISKCACHE 1)			# selfcontained
+	set(LWS_WITH_LWSAC 1)				# selfcontained
+	set(LWS_WITH_LEJP_CONF 1)			# selfcontained
+	set(LWS_WITH_PLUGINS 1)				# libdl
+	set(LWS_ROLE_RAW_PROXY 1)			# selfcontained
+	set(LWS_WITH_GENCRYPTO 1)			# selfcontained / tls
+	set(LWS_WITH_JOSE 1)				# selfcontained
+	set(LWS_WITH_STRUCT_JSON 1)			# selfcontained
+	set(LWS_WITH_STRUCT_SQLITE3 1)			# sqlite3
+	set(LWS_WITH_SPAWN 1)				# selfcontained
+# libmount is problematic on Centos 8 / RHEL 8
+#	set(LWS_WITH_FSMOUNT 1)
+	set(LWS_ROLE_MQTT 1)				# selfcontained
+	set(LWS_WITH_SECURE_STREAMS 1)			# selfcontained
+	set(LWS_WITH_SECURE_STREAMS_PROXY_API 1)	# selfcontained
+	set(LWS_WITH_DIR 1)				# selfcontained
+endif()
+
+# LWS_WITH_EVENT_LIBS is set if any event lib selected
+
+if (LWS_WITH_LIBEV OR
+    LWS_WITH_LIBUV OR
+    LWS_WITH_LIBEVENT OR
+    LWS_WITH_GLIB)
+	set(LWS_WITH_EVENT_LIBS 1)
+else()
+	unset(LWS_WITH_EVENT_LIBS)
+endif()
+
+if (LWS_WITH_SECURE_STREAMS_PROXY_API)
+	set(LWS_WITH_LWS_DSH 1)
+	set(LWS_WITH_UNIX_SOCK 1)
+endif()
+
+if (NOT LWS_WITH_NETWORK)
+	set(LWS_ROLE_MQTT 0)
+	set(LWS_ROLE_H1 0)
+	set(LWS_ROLE_WS 0)
+	set(LWS_ROLE_RAW 0)
+	set(LWS_WITHOUT_EXTENSIONS 1)
+	set(LWS_WITHOUT_SERVER 1)
+	set(LWS_WITHOUT_CLIENT 1)
+	set(LWS_WITH_HTTP2 0)
+	set(LWS_WITH_SOCKS5 0)
+	set(LWS_UNIX_SOCK 0)
+	set(LWS_WITH_HTTP_PROXY 0)
+	set(LWS_WITH_PLUGINS 0)
+	set(LWS_WITH_LWSWS 0)
+	set(LWS_WITH_CGI 0)
+	set(LWS_ROLE_RAW_PROXY 0)
+	set(LWS_WITH_PEER_LIMITS 0)
+	set(LWS_WITH_HTTP_STREAM_COMPRESSION 0)
+	set(LWS_WITH_HTTP_BROTLI 0)
+	set(LWS_WITH_POLL 0)
+	set(LWS_WITH_SEQUENCER 0)
+	set(LWS_ROLE_DBUS 0)
+	set(LWS_WITH_LWS_DSH 0)
+	set(LWS_WITH_THREADPOOL 0)
+	set(LWS_WITH_SYS_SMD 0)
+endif()
+
+if (LWS_WITH_CGI)
+	set(LWS_WITH_SPAWN 1)
+endif()
+
+if (LWS_WITH_STRUCT_SQLITE3)
+	set(LWS_WITH_SQLITE3 1)
+endif()
+
+if (LWS_WITH_HTTP_BASIC_AUTH)
+	# WWW_AUTHENTICATE used by basic auth is an "uncommon header"
+	set(LWS_WITH_HTTP_UNCOMMON_HEADERS 1)
+endif()
+
+if (APPLE)
+	set(LWS_ROLE_DBUS 0)
+endif()
+
+if(NOT DEFINED CMAKE_BUILD_TYPE)
+	set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
+endif()
+
+if (LWS_PLAT_FREERTOS)
+	set(LWS_UNIX_SOCK 0)
+endif()
+
+if (LWS_PLAT_FREERTOS)
+	set(LWS_WITH_FTS 0)
+endif()
+
+if (LWS_WITH_HTTP2)
+	set(LWS_ROLE_H2 1)
+endif()
+if (LWS_WITH_CGI)
+	set(LWS_ROLE_CGI 1)
+endif()
+
+if (NOT LWS_ROLE_WS)
+	set(LWS_WITHOUT_EXTENSIONS 1)
+endif()
+
+unset(LWS_WITH_LIBUV_INTERNAL)
+
+if (LWS_WITH_LWSWS)
+ message(STATUS "LWS_WITH_LWSWS --> Enabling LWS_WITH_PLUGINS and LWS_WITH_LIBUV")
+ set(LWS_WITH_PLUGINS 1)
+ set(LWS_WITH_LIBUV 1)
+ set(LWS_WITH_LIBUV_INTERNAL 1)
+ set(LWS_WITH_EVENT_LIBS 1) # implied by LIBUV_INTERNAL
+ set(LWS_WITH_ACCESS_LOG 1)
+ set(LWS_WITH_SERVER_STATUS 1)
+ set(LWS_WITH_LEJP 1)
+ set(LWS_WITH_LEJP_CONF 1)
+ set(LWS_WITH_PEER_LIMITS 1)
+ set(LWS_ROLE_RAW_PROXY 1)
+endif()
+
+# sshd plugin
+if (LWS_WITH_PLUGINS)
+ set(LWS_WITH_GENCRYPTO 1)
+endif()
+
+if (LWS_ROLE_RAW_PROXY)
+ set (LWS_WITH_CLIENT 1)
+ set (LWS_WITH_SERVER 1)
+endif()
+
+if (LWS_WITH_ACME)
+ set (LWS_WITH_CLIENT 1)
+ set (LWS_WITH_SERVER 1)
+ set (LWS_WITH_JOSE 1)
+endif()
+
+if (LWS_WITH_JOSE)
+ set(LWS_WITH_LEJP 1)
+ set(LWS_WITH_GENCRYPTO 1)
+endif()
+
+if (LWS_WITH_PLUGINS AND NOT LWS_WITH_LIBUV)
+message(STATUS "LWS_WITH_PLUGINS --> Enabling LWS_WITH_LIBUV")
+ set(LWS_WITH_LIBUV 1)
+endif()
+
+if (LWS_WITH_PLUGINS OR LWS_WITH_CGI)
+	# sshd plugin
+ set(LWS_WITH_GENCRYPTO 1)
+endif()
+
+if (LWS_PLAT_FREERTOS)
+ set(LWS_WITH_SHARED OFF)
+ if (LWS_WITH_SSL)
+  set(LWS_WITH_MBEDTLS ON)
+ endif()
+  # set(LWS_WITHOUT_CLIENT ON)
+ set(LWS_WITHOUT_TESTAPPS ON)
+ set(LWS_WITHOUT_EXTENSIONS ON)
+ set(LWS_WITH_PLUGINS OFF)
+ set(LWS_WITH_RANGES ON)
+ # this implies no pthreads in the lib
+ set(LWS_MAX_SMP 1)
+ set(LWS_HAVE_MALLOC 1)
+ set(LWS_HAVE_REALLOC 1)
+ set(LWS_HAVE_GETIFADDRS 1)
+ set(LWS_WITH_CUSTOM_HEADERS 0)
+endif()
+
+#if (LWS_WITH_ESP32)
+# set(LWS_WITH_ZIP_FOPS 1)
+#endif()
+
+if (WIN32)
+set(LWS_MAX_SMP 1)
+if (LWS_WITH_PLUGINS)
+set(LWS_WITH_LIBUV_INTERNAL 1)
+endif()
+endif()
+
+if (LWS_WITHOUT_SERVER)
+set(LWS_WITH_LWSWS OFF)
+endif()
+
+if (LWS_WITH_LEJP_CONF)
+	set(LWS_WITH_DIR 1)
+endif()
+
+# confirm H1 relationships
+
+if (NOT LWS_ROLE_H1 AND LWS_ROLE_H2)
+	message(FATAL_ERROR "H2 requires LWS_ROLE_H1")
+endif()
+
+if (NOT LWS_ROLE_H1 AND LWS_ROLE_WS)
+	message(FATAL_ERROR "WS requires LWS_ROLE_H1")
+endif()
+
+if (NOT LWS_ROLE_H1 AND LWS_ROLE_CGI)
+	message(FATAL_ERROR "CGI requires LWS_ROLE_H1")
+endif()
+
+# confirm HTTP relationships
+
+if (NOT LWS_ROLE_H1 AND NOT LWS_ROLE_H2 AND LWS_WITH_HTTP_PROXY)
+	message(FATAL_ERROR "LWS_WITH_LWSWS requires LWS_ROLE_H1")
+endif()
+
+if (NOT LWS_ROLE_H1 AND NOT LWS_ROLE_H2 AND LWS_WITH_HTTP_PROXY)
+	message(FATAL_ERROR "LWS_WITH_HTTP_PROXY requires LWS_ROLE_H1")
+endif()
+
+if (NOT LWS_ROLE_H1 AND NOT LWS_ROLE_H2 AND LWS_WITH_RANGES)
+	message(FATAL_ERROR "LWS_WITH_RANGES requires LWS_ROLE_H1")
+endif()
+
+if (NOT LWS_ROLE_H1 AND NOT LWS_ROLE_H2 AND LWS_WITH_ACCESS_LOG)
+	message(FATAL_ERROR "LWS_WITH_ACCESS_LOG requires LWS_ROLE_H1")
+endif()
+
+if (LWS_WITH_HTTP_PROXY AND (LWS_WITHOUT_CLIENT OR LWS_WITHOUT_SERVER))
+	message("You have to enable both client and server for http proxy")
+	set(LWS_WITH_HTTP_PROXY 0)
+endif()
+
+if (NOT LWS_WITHOUT_EXTENSIONS OR LWS_WITH_ZIP_FOPS)
+	set(LWS_WITH_ZLIB 1)
+endif()
+
+if (LWS_WITH_SECURE_STREAMS)
+	set(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM 1)
+endif()
+
+if (NOT (LWS_WITH_STATIC OR LWS_WITH_SHARED))
+	message(FATAL_ERROR "Makes no sense to compile with neither static nor shared libraries.")
+endif()
+
+if (LWS_WITHOUT_DAEMONIZE OR WIN32)
+	set(LWS_NO_DAEMONIZE 1)
+endif()
+
+if (LWS_WITH_LIBEV)
+	set(LWS_WITH_LIBEV 1)
+endif()
+
+if (LWS_WITH_LIBUV)
+	set(LWS_WITH_LIBUV 1)
+endif()
+
+if (LWS_WITH_LIBEVENT)
+	set(LWS_WITH_LIBEVENT 1)
+endif()
+
+if (LWS_IPV6)
+	set(LWS_WITH_IPV6 1)
+endif()
+
+if (LWS_UNIX_SOCK)
+    set(LWS_WITH_UNIX_SOCK 1)
+endif()
+
+if (NOT LWS_MAX_SMP)
+	set(LWS_MAX_SMP 1)
+endif()
+if ("${LWS_MAX_SMP}" STREQUAL "")
+	set(LWS_MAX_SMP 1)
+endif()
+
+set(LWS_WITH_CLIENT 1)
+if (LWS_WITHOUT_CLIENT)
+	set(LWS_WITH_CLIENT)
+	set(LWS_WITH_SECURE_STREAMS 0)
+endif()
+set(LWS_WITH_SERVER 1)
+if (LWS_WITHOUT_SERVER)
+	set(LWS_WITH_SERVER)
+endif()
+
+# using any abstract protocol enables LWS_WITH_ABSTRACT
+
+#if (LWS_WITH_SMTP)
+#	set(LWS_WITH_ABSTRACT 1)
+#endif()
+
+if (NOT LWS_WITH_EVLIB_PLUGINS AND (LWS_WITH_LIBEV AND LWS_WITH_LIBEVENT))
+	message(FATAL_ERROR "Sorry libev and libevent conflict with each others' namespace, you can only have one or the other")
+endif()
+
+if (LWS_SSL_SERVER_WITH_ECDH_CERT)
+	set(LWS_SSL_SERVER_WITH_ECDH_CERT 1)
+endif()
+
+# LWS_OPENSSL_SUPPORT deprecated... use LWS_WITH_TLS
+if (LWS_WITH_SSL OR LWS_WITH_MBEDTLS)
+	set(LWS_OPENSSL_SUPPORT 1)
+	set(LWS_WITH_TLS 1)
+endif()
+
+if (NOT LWS_WITH_SSL)
+	set(LWS_WITHOUT_BUILTIN_SHA1 OFF)
+endif()
+# protocol plugins dont make any sense either
+if (LWS_WITH_PLUGINS AND NOT LWS_WITH_SHARED)
+	message("Deselecting PLUGINS since building static")
+	set(LWS_WITH_PLUGINS 0)
+endif()
+
+
+# if we're only building static, we don't want event lib plugins
+#
+if (LWS_WITH_EVLIB_PLUGINS AND NOT LWS_WITH_SHARED)
+	message("Deselecting EVLIB_PLUGINS since building static")
+	set(LWS_WITH_EVLIB_PLUGINS 0)
+endif()
+
+if (LWS_WITH_PLUGINS OR (LWS_WITH_EVLIB_PLUGINS AND LWS_WITH_EVENT_LIBS))
+	set(LWS_WITH_PLUGINS_API 1)
+endif()
+

+ 970 - 0
Source/ThirdParty/libwebsockets/CMakeLists.txt

@@ -0,0 +1,970 @@
+#
+# libwebsockets - small server side websockets and web server implementation
+#
+# Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+
+cmake_minimum_required(VERSION 2.8.9)
+include(CheckFunctionExists)
+include(CheckSymbolExists)
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckLibraryExists)
+include(CheckTypeSize)
+include(CheckCSourceCompiles)
+
+if (POLICY CMP0048)
+	cmake_policy(SET CMP0048 NEW)
+endif()
+
+#if (POLICY CMP0024)
+#	cmake_policy(SET CMP0024 NEW)
+#endif()
+
+if (POLICY CMP0075)
+	cmake_policy(SET CMP0075 NEW)
+endif()
+
+# General Advice
+#
+# For selecting between DEBUG / RELEASE, use -DCMAKE_BUILD_TYPE=DEBUG or =RELEASE
+#   debug builds include source level debug info and extra logging
+
+set(LWS_WITH_BUNDLED_ZLIB_DEFAULT OFF)
+if(WIN32)
+	set(LWS_WITH_BUNDLED_ZLIB_DEFAULT ON)
+endif()
+
+set(LWS_ROLE_RAW 1)
+set(LWS_WITH_POLL 1)
+
+if (ESP_PLATFORM)
+	set(LWS_ESP_PLATFORM 1)
+	set(CMAKE_TOOLCHAIN_FILE contrib/cross-esp32.cmake)
+	set(LWIP_PROVIDE_ERRNO 1)
+endif()
+
+# it's at this point any toolchain file is brought in
+project(libwebsockets C)
+include(CTest)
+
+#
+# Select features recommended for PC distro packaging
+#
+option(LWS_WITH_DISTRO_RECOMMENDED "Enable features recommended for distro packaging" OFF)
+option(LWS_FOR_GITOHASHI "Enable features recommended for use with gitohashi" OFF)
+
+#
+# Compiler features
+#
+option(DISABLE_WERROR "Avoid treating compiler warnings as fatal errors" OFF)
+
+#
+# Major individual features
+#
+option(LWS_WITH_CLIENT "Compile with network-related code" ON)
+option(LWS_WITH_NETWORK "Compile with network-related code" ON)
+option(LWS_ROLE_H1 "Compile with support for http/1 (needed for ws)" ON)
+option(LWS_ROLE_WS "Compile with support for websockets" ON)
+option(LWS_ROLE_MQTT "Build with support for MQTT client" OFF)
+option(LWS_ROLE_DBUS "Compile with support for DBUS" OFF)
+option(LWS_ROLE_RAW_PROXY "Raw packet proxy" OFF)
+option(LWS_ROLE_RAW_FILE "Compile with support for raw files" OFF)
+option(LWS_WITH_HTTP2 "Compile with server support for HTTP/2" OFF)
+option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF)
+option(LWS_WITH_CGI "Include CGI (spawn process with network-connected stdin/out/err) APIs" OFF)
+option(LWS_IPV6 "Compile with support for ipv6" OFF)
+option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket if OS supports it" ON)
+option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions (implies LWS_WITH_PLUGINS_API)" OFF)
+option(LWS_WITH_HTTP_PROXY "Support for active HTTP proxying" OFF)
+option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" OFF)
+option(LWS_WITH_SOCKS5 "Allow use of SOCKS5 proxy on client connections" OFF)
+option(LWS_WITH_PEER_LIMITS "Track peers and restrict resources a single peer can allocate" OFF)
+option(LWS_WITH_ACCESS_LOG "Support generating Apache-compatible access logs" OFF)
+option(LWS_WITH_RANGES "Support http ranges (RFC7233)" OFF)
+option(LWS_WITH_SERVER_STATUS "Support json + jscript server monitoring" OFF)
+option(LWS_WITH_SERVER "Support json + jscript server monitoring" ON)
+option(LWS_WITH_THREADPOOL "Managed worker thread pool support (relies on pthreads)" OFF)
+option(LWS_WITH_HTTP_STREAM_COMPRESSION "Support HTTP stream compression" OFF)
+option(LWS_WITH_HTTP_BROTLI "Also offer brotli http stream compression (requires LWS_WITH_HTTP_STREAM_COMPRESSION)" OFF)
+option(LWS_WITH_ACME "Enable support for ACME automatic cert acquisition + maintenance (letsencrypt etc)" OFF)
+option(LWS_WITH_HUBBUB "Enable libhubbub rewriting support" OFF)
+option(LWS_WITH_ALSA "Enable alsa audio example" OFF)
+option(LWS_WITH_GTK "Enable gtk example" OFF)
+option(LWS_WITH_FTS "Full Text Search support" OFF)
+option(LWS_WITH_SYS_ASYNC_DNS "Nonblocking internal IPv4 + IPv6 DNS resolver" OFF)
+option(LWS_WITH_SYS_NTPCLIENT "Build in tiny ntpclient good for tls date validation and run via lws_system" OFF)
+option(LWS_WITH_SYS_DHCP_CLIENT "Build in tiny DHCP client" OFF)
+option(LWS_WITH_HTTP_BASIC_AUTH "Support Basic Auth" OFF)
+option(LWS_WITH_HTTP_UNCOMMON_HEADERS "Include less common http header support" ON)
+option(LWS_WITH_SYS_STATE "lws_system state support" ON)
+option(LWS_WITH_SYS_SMD "Lws System Message Distribution" ON)
+
+#
+# Secure Streams
+#
+option(LWS_WITH_SECURE_STREAMS "Secure Streams protocol-agnostic API" OFF)
+option(LWS_WITH_SECURE_STREAMS_PROXY_API "Secure Streams support to work across processes" OFF)
+option(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM "Auth support for api.amazon.com" OFF)
+option(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY "Secure Streams Policy is hardcoded only" OFF)
+
+#
+# CTest options
+#
+#
+# If you build with LWS_WITH_MINIMAL_EXAMPLES, you can use CTest / make test to run
+# examples that can give a pass/fail response.  By default it runs tests both against
+# a local server peer and warmcat.com, if your CI wants to do the tests but does not
+# have internet routing, then you can still run a subset of tests with CTest / make
+# test that only does local tests by disabling this option.
+#
+option(LWS_CTEST_INTERNET_AVAILABLE "CTest will performs tests that need the Internet" ON)
+
+#
+# TLS library options... all except mbedTLS are basically OpenSSL variants.
+#
+option(LWS_WITH_SSL "Include SSL support (defaults to OpenSSL or similar, mbedTLS if LWS_WITH_MBEDTLS is set)" OFF)
+option(LWS_WITH_MBEDTLS "Use mbedTLS (>=2.0) replacement for OpenSSL. When setting this, you also may need to specify LWS_MBEDTLS_LIBRARIES and LWS_MBEDTLS_INCLUDE_DIRS" OFF)
+option(LWS_WITH_BORINGSSL "Use BoringSSL replacement for OpenSSL" OFF)
+option(LWS_WITH_CYASSL "Use CyaSSL replacement for OpenSSL. When setting this, you also need to specify LWS_CYASSL_LIBRARIES and LWS_CYASSL_INCLUDE_DIRS" OFF)
+option(LWS_WITH_WOLFSSL "Use wolfSSL replacement for OpenSSL. When setting this, you also need to specify LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS" OFF)
+option(LWS_SSL_CLIENT_USE_OS_CA_CERTS "SSL support should make use of the OS-installed CA root certs" OFF)
+#
+# Event library options (may select multiple, or none for default poll()
+#
+option(LWS_WITH_LIBEV "Compile with support for libev" OFF)
+option(LWS_WITH_LIBUV "Compile with support for libuv" OFF)
+option(LWS_WITH_LIBEVENT "Compile with support for libevent" OFF)
+option(LWS_WITH_GLIB "Compile with support for glib event loop" OFF)
+
+if (UNIX)
+# since v4.1, on unix platforms default is build any event libs as runtime plugins
+option(LWS_WITH_EVLIB_PLUGINS "Compile event lib support into runtime-selected plugins" ON)
+else()
+# otherwise default to linking the event lib(s) to libwebsockets.so
+option(LWS_WITH_EVLIB_PLUGINS "Compile event lib support into runtime-selected plugins" OFF)
+endif()
+#
+# LWS Drivers
+#
+
+option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" OFF)
+
+#
+# Static / Dynamic build options
+#
+option(LWS_WITH_STATIC "Build the static version of the library" ON)
+option(LWS_WITH_SHARED "Build the shared version of the library" OFF)
+option(LWS_LINK_TESTAPPS_DYNAMIC "Link the test apps to the shared version of the library. Default is to link statically" OFF)
+option(LWS_STATIC_PIC "Build the static version of the library with position-independent code" OFF)
+#
+# Specific platforms
+#
+option(LWS_WITH_ESP32 "Build for ESP32" OFF)
+option(LWS_PLAT_OPTEE "Build for OPTEE" OFF)
+option(LWS_PLAT_FREERTOS "Build for FreeRTOS" OFF)
+option(LWS_PLAT_ANDROID "Android flavour of unix platform" OFF)
+
+#
+# Client / Server / Test Apps build control
+#
+option(LWS_WITHOUT_CLIENT "Don't build the client part of the library" OFF)
+option(LWS_WITHOUT_SERVER "Don't build the server part of the library" OFF)
+option(LWS_WITHOUT_TESTAPPS "Don't build the libwebsocket-test-apps" ON)
+option(LWS_WITHOUT_TEST_SERVER "Don't build the test server" ON)
+option(LWS_WITHOUT_TEST_SERVER_EXTPOLL "Don't build the test server version that uses external poll" ON)
+option(LWS_WITHOUT_TEST_PING "Don't build the ping test application" ON)
+option(LWS_WITHOUT_TEST_CLIENT "Don't build the client test application" ON)
+#
+# Extensions (permessage-deflate)
+#
+option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" ON)
+#
+# Helpers + misc
+#
+option(LWS_WITHOUT_BUILTIN_GETIFADDRS "Don't use the BSD getifaddrs implementation from libwebsockets if it is missing (this will result in a compilation error) ... The default is to assume that your libc provides it. On some systems such as uclibc it doesn't exist." OFF)
+option(LWS_FALLBACK_GETHOSTBYNAME "Also try to do dns resolution using gethostbyname if getaddrinfo fails" OFF)
+option(LWS_WITHOUT_BUILTIN_SHA1 "Don't build the lws sha-1 (eg, because openssl will provide it" OFF)
+option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON)
+option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH certificate" OFF)
+option(LWS_WITH_LEJP "With the Lightweight JSON Parser" ON)
+option(LWS_WITH_SQLITE3 "Require SQLITE3 support" OFF)
+option(LWS_WITH_STRUCT_JSON "Generic struct serialization to and from JSON" OFF)
+option(LWS_WITH_STRUCT_SQLITE3 "Generic struct serialization to and from SQLITE3" OFF)
+# broken atm
+#option(LWS_WITH_SMTP "Provide SMTP support" OFF)
+if (LWS_WITH_ESP32)
+option(LWS_WITH_DIR "Directory scanning api support" OFF)
+option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" OFF)
+else()
+option(LWS_WITH_DIR "Directory scanning api support" ON)
+option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" ON)
+endif()
+option(LWS_WITH_NO_LOGS "Disable all logging other than _err and _user from being compiled in" OFF)
+set(LWS_LOGGING_BITFIELD_SET 0 CACHE STRING "Bitfield describing which log levels to force included into the build")
+set(LWS_LOGGING_BITFIELD_CLEAR 0 CACHE STRING "Bitfield describing which log levels to force removed from the build")
+option(LWS_LOGS_TIMESTAMP "Timestamp at start of logs" ON)
+option(LWS_AVOID_SIGPIPE_IGN "Android 7+ reportedly needs this" OFF)
+option(LWS_WITH_STATS "Keep statistics of lws internal operations" OFF)
+option(LWS_WITH_JOSE "JSON Web Signature / Encryption / Keys (RFC7515/6/) API" OFF)
+option(LWS_WITH_GENCRYPTO "Enable support for Generic Crypto apis independent of TLS backend" OFF)
+option(LWS_WITH_SELFTESTS "Selftests run at context creation" OFF)
+option(LWS_WITH_GCOV "Build with gcc gcov coverage instrumentation" OFF)
+option(LWS_WITH_EXPORT_LWSTARGETS "Export libwebsockets CMake targets.  Disable if they conflict with an outer cmake project." ON)
+option(LWS_REPRODUCIBLE "Build libwebsockets reproducible. It removes the build user and hostname from the build" ON)
+option(LWS_WITH_MINIMAL_EXAMPLES "Also build the normally standalone minimal examples, for QA" OFF)
+option(LWS_WITH_LWSAC "lwsac Chunk Allocation api" ON)
+option(LWS_WITH_CUSTOM_HEADERS "Store and allow querying custom HTTP headers (H1 only)" ON)
+option(LWS_WITH_DISKCACHE "Hashed cache directory with lazy LRU deletion to size limit" OFF)
+option(LWS_WITH_ASAN "Build with gcc runtime sanitizer options enabled (needs libasan)" OFF)
+option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" OFF)
+option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" OFF)
+option(LWS_WITH_BUNDLED_ZLIB "Use bundled zlib version (Windows only)" ${LWS_WITH_BUNDLED_ZLIB_DEFAULT})
+option(LWS_WITH_MINIZ "Use miniz instead of zlib" OFF)
+option(LWS_WITH_DEPRECATED_THINGS "Temporary workaround for deprecated apis" OFF)
+option(LWS_WITH_SEQUENCER "lws_seq_t support" ON)
+option(LWS_WITH_EXTERNAL_POLL "Support external POLL integration using callback messages (not recommended)" OFF)
+option(LWS_WITH_LWS_DSH "Support lws_dsh_t Disordered Shared Heap" OFF)
+option(LWS_CLIENT_HTTP_PROXYING "Support external http proxies for client connections" ON)
+option(LWS_WITH_FILE_OPS "Support file operations vfs" ON)
+option(LWS_WITH_DETAILED_LATENCY "Record detailed latency stats for each read and write" OFF)
+option(LWS_WITH_UDP "Platform supports UDP" ON)
+option(LWS_WITH_SPAWN "Spawn subprocesses with piped stdin/out/stderr" OFF)
+option(LWS_WITH_FSMOUNT "Overlayfs and fallback mounting apis" OFF)
+option(LWS_WITH_FANALYZER "Enable gcc -fanalyzer if compiler supports" OFF)
+option(LWS_HTTP_HEADERS_ALL "Override header reduction optimization and include all like older lws versions" OFF)
+option(LWS_WITH_SUL_DEBUGGING "Enable zombie lws_sul checking on object deletion" OFF)
+option(LWS_WITH_PLUGINS_API "Build generic lws_plugins apis (see LWS_WITH_PLUGINS to also build protocol plugins)" OFF)
+
+#
+# to use miniz, enable both LWS_WITH_ZLIB and LWS_WITH_MINIZ
+#
+# End of user settings
+#
+
+# sets of sub-options implied by other options
+#
+set(LIB_LIST "")
+set(LIB_LIST_AT_END)
+set(LWS_LIBRARIES)
+set(LWS_OPENSSL_SUPPORT 0)
+include(CMakeLists-implied-options.txt)
+
+#
+# Structural helpers for cmake in subdirs
+#
+
+macro(add_subdir_include_directories arg1)
+	add_subdirectory(${arg1})
+	include_directories(${_CMAKE_INC_LIST})
+endmacro()
+
+macro(exports_to_parent_scope)
+	set(SOURCES ${SOURCES} PARENT_SCOPE)
+	if (LIB_LIST)
+		set(LIB_LIST ${LIB_LIST} PARENT_SCOPE)
+	endif()
+	get_property(_CURR DIRECTORY PROPERTY INCLUDE_DIRECTORIES) 
+	set(_CMAKE_INC_LIST ${_CURR} PARENT_SCOPE)
+	if (LWS_LIB_BUILD_INC_PATHS)
+		set(LWS_LIB_BUILD_INC_PATHS ${LWS_LIB_BUILD_INC_PATHS} PARENT_SCOPE)
+	endif()
+endmacro()
+
+macro(export_to_parent_intermediate)
+	set(SOURCES ${SOURCES} PARENT_SCOPE)
+	if (LIB_LIST)
+		set(LIB_LIST ${LIB_LIST} PARENT_SCOPE)
+	endif()
+	set(_CMAKE_INC_LIST ${_CMAKE_INC_LIST} PARENT_SCOPE)
+	if (LWS_LIB_BUILD_INC_PATHS)
+		set(LWS_LIB_BUILD_INC_PATHS ${LWS_LIB_BUILD_INC_PATHS} PARENT_SCOPE)
+	endif()
+endmacro()
+
+#
+# Try to find the current Git hash
+#
+
+find_package(Git)
+if(GIT_EXECUTABLE)
+	execute_process(
+		WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+		COMMAND "${GIT_EXECUTABLE}" describe --tags --always
+		OUTPUT_VARIABLE GIT_HASH
+		OUTPUT_STRIP_TRAILING_WHITESPACE
+		)
+	set(LWS_BUILD_HASH ${GIT_HASH})
+
+	# append the build user and hostname
+	if (NOT LWS_REPRODUCIBLE)
+		execute_process(
+			WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+			COMMAND "whoami"
+			OUTPUT_VARIABLE GIT_USER
+			OUTPUT_STRIP_TRAILING_WHITESPACE
+			)
+		execute_process(
+			WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+			COMMAND "hostname"
+			OUTPUT_VARIABLE GIT_HOST
+			OUTPUT_STRIP_TRAILING_WHITESPACE
+			)
+		string(REGEX REPLACE "([^\\])[\\]([^\\])" "\\1\\\\\\\\\\2" GIT_USER ${GIT_USER})
+		set(LWS_BUILD_HASH ${GIT_USER}@${GIT_HOST}-${GIT_HASH})
+	endif()
+
+	message("Git commit hash: ${LWS_BUILD_HASH}")
+endif()
+
+set(PACKAGE "libwebsockets")
+set(CPACK_RPM_PACKAGE_LICENSE "MIT")
+set(CPACK_PACKAGE_NAME "${PACKAGE}")
+set(CPACK_PACKAGE_VERSION_MAJOR "4")
+set(CPACK_PACKAGE_VERSION_MINOR "1")
+set(CPACK_PACKAGE_VERSION_PATCH_NUMBER "99")
+
+set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH_NUMBER}-${LWS_BUILD_HASH}")
+set(CPACK_PACKAGE_RELEASE 1)
+
+set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+set(CPACK_PACKAGE_VENDOR "[email protected]")
+set(CPACK_PACKAGE_CONTACT "[email protected]")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${CPACK_PACKAGE_VERSION}")
+set(SOVERSION "17")
+if(NOT CPACK_GENERATOR)
+    if(UNIX)
+        set(CPACK_GENERATOR "TGZ")
+    else()
+        set(CPACK_GENERATOR "ZIP")
+    endif()
+endif()
+set(CPACK_SOURCE_GENERATOR "TGZ")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
+set(VERSION "${CPACK_PACKAGE_VERSION}")
+
+set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
+set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
+# below makes path length problems in CI
+set(CPACK_RPM_DEBUGINFO_PACKAGE OFF)
+# below makes some kind of chimera rpm with binaries and sources
+set(CPACK_RPM_PACKAGE_SOURCES OFF)
+set(CPACK_RPM_INSTALL_WITH_EXEC ON)
+set(CPACK_RPM_COMPONENT_INSTALL ON)
+
+set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
+set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
+set(CPACK_DEBIAN_PACKAGE_SOURCE ON)
+set(CPACK_DEBIAN_COMPONENT_INSTALL ON)
+
+
+set(LWS_LIBRARY_VERSION ${CPACK_PACKAGE_VERSION})
+set(LWS_LIBRARY_VERSION_MAJOR ${CPACK_PACKAGE_VERSION_MAJOR})
+set(LWS_LIBRARY_VERSION_MINOR ${CPACK_PACKAGE_VERSION_MINOR})
+set(LWS_LIBRARY_VERSION_PATCH ${CPACK_PACKAGE_VERSION_PATCH_NUMBER})
+set(LWS_LIBRARY_VERSION_PATCH_ELABORATED ${CPACK_PACKAGE_VERSION_PATCH})
+
+if (NOT CMAKE_MODULE_PATH)
+	set(CMAKE_MODULE_PATH "")
+endif()
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
+
+
+if (CMAKE_TOOLCHAIN_FILE)
+	message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
+endif()
+
+if (NOT LIB_SUFFIX)
+	set(LIB_SUFFIX "")
+endif()
+
+if (WIN32)
+	configure_file(${CMAKE_CURRENT_SOURCE_DIR}/win32port/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/win32port/version.rc @ONLY)
+	set(RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/win32port/version.rc)
+endif()
+
+include_directories(include)
+
+# Allow the user to override installation directories.
+set(LWS_INSTALL_LIB_DIR       lib CACHE PATH "Installation directory for libraries")
+set(LWS_INSTALL_BIN_DIR       bin CACHE PATH "Installation directory for executables")
+set(LWS_INSTALL_INCLUDE_DIR   include CACHE PATH "Installation directory for header files")
+set(LWS_INSTALL_EXAMPLES_DIR  bin CACHE PATH "Installation directory for example files")
+
+# if you gave LWS_WITH_MINIZ, point to MINIZ here if not found
+# automatically
+
+set(LWS_ZLIB_LIBRARIES CACHE PATH "Path to the zlib/miniz library")
+set(LWS_ZLIB_INCLUDE_DIRS CACHE PATH "Path to the zlib/miniz include directory")
+set(LWS_SQLITE3_LIBRARIES CACHE PATH "Path to the sqlite3 library")
+set(LWS_SQLITE3_INCLUDE_DIRS CACHE PATH "Path to the sqlite3 include directory")
+set(LWS_LIBMOUNT_INCLUDE_DIRS CACHE PATH "Path to the libmount include directory")
+set(LWS_LIBMOUNT_LIBRARIES CACHE PATH "Path to the libmount library")
+# on unix, these are in the toolchain.  On win32 you have to put them somewhere
+# yourself and point to them here
+set(LWS_EXT_PTHREAD_INCLUDE_DIR CACHE PATH "Path to an external pthreads include directory")
+set(LWS_EXT_PTHREAD_LIBRARIES CACHE PATH "Path to an external pthreads library")
+
+
+if (LWS_WITH_HTTP_STREAM_COMPRESSION)
+	set(LWS_WITH_ZLIB 1)
+endif()
+
+if (LWS_WITH_ZLIB AND NOT LWS_WITH_BUNDLED_ZLIB)
+	if ("${LWS_ZLIB_LIBRARIES}" STREQUAL "" OR "${LWS_ZLIB_INCLUDE_DIRS}" STREQUAL "")
+	else()
+		set(ZLIB_LIBRARIES ${LWS_ZLIB_LIBRARIES})
+		set(ZLIB_INCLUDE_DIRS ${LWS_ZLIB_INCLUDE_DIRS})
+		set(ZLIB_FOUND 1)
+	endif()
+endif()
+
+
+if (LWS_WITH_SQLITE3)
+	if ("${LWS_SQLITE3_LIBRARIES}" STREQUAL "" OR "${LWS_SQLITE3_INCLUDE_DIRS}" STREQUAL "")
+	else()
+		set(SQLITE3_LIBRARIES ${LWS_SQLITE3_LIBRARIES})
+		set(SQLITE3_INCLUDE_DIRS ${LWS_SQLITE3_INCLUDE_DIRS})
+		set(SQLITE3_FOUND 1)
+	endif()
+endif()
+
+include_directories("${PROJECT_BINARY_DIR}")
+
+# Check for different inline keyword versions.
+foreach(KEYWORD "inline" "__inline__" "__inline")
+	set(CMAKE_REQUIRED_DEFINITIONS "-DKEYWORD=${KEYWORD}")
+	CHECK_C_SOURCE_COMPILES(
+		"
+		#include <stdio.h>
+		static KEYWORD void a() {}
+		int main(int argc, char **argv) { a(); return 0; }
+		" LWS_HAVE_${KEYWORD})
+endforeach()
+
+if (NOT LWS_HAVE_inline)
+	if (LWS_HAVE___inline__)
+		set(inline __inline__)
+	elseif(LWS_HAVE___inline)
+		set(inline __inline)
+	endif()
+endif()
+
+# Put the libraries and binaries that get built into directories at the
+# top of the build tree rather than in hard-to-find leaf directories. 
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
+SET(LWS_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}")
+
+# Put absolute path of dynamic libraries into the object code. Some
+# architectures, notably Mac OS X, need this.
+SET(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}")
+
+if (LWS_WITHOUT_BUILTIN_SHA1)
+	set(LWS_SHA1_USE_OPENSSL_NAME 1)
+endif()
+
+CHECK_C_SOURCE_COMPILES(
+	"#include <malloc.h>
+	int main(int argc, char **argv) { return malloc_trim(0); }
+	" LWS_HAVE_MALLOC_TRIM)
+CHECK_C_SOURCE_COMPILES(
+	"#include <malloc.h>
+	int main(int argc, char **argv) { return (int)malloc_usable_size((void *)0); }
+	" LWS_HAVE_MALLOC_USABLE_SIZE)
+
+CHECK_FUNCTION_EXISTS(fork LWS_HAVE_FORK)
+CHECK_FUNCTION_EXISTS(getenv LWS_HAVE_GETENV)
+CHECK_FUNCTION_EXISTS(malloc LWS_HAVE_MALLOC)
+CHECK_FUNCTION_EXISTS(memset LWS_HAVE_MEMSET)
+CHECK_FUNCTION_EXISTS(realloc LWS_HAVE_REALLOC)
+CHECK_FUNCTION_EXISTS(socket LWS_HAVE_SOCKET)
+CHECK_FUNCTION_EXISTS(strerror LWS_HAVE_STRERROR)
+CHECK_FUNCTION_EXISTS(vfork LWS_HAVE_VFORK)
+CHECK_FUNCTION_EXISTS(execvpe LWS_HAVE_EXECVPE)
+CHECK_FUNCTION_EXISTS(getifaddrs LWS_HAVE_GETIFADDRS)
+CHECK_FUNCTION_EXISTS(snprintf LWS_HAVE_SNPRINTF)
+CHECK_FUNCTION_EXISTS(_snprintf LWS_HAVE__SNPRINTF)
+CHECK_FUNCTION_EXISTS(_vsnprintf LWS_HAVE__VSNPRINTF)
+CHECK_FUNCTION_EXISTS(getloadavg LWS_HAVE_GETLOADAVG)
+CHECK_FUNCTION_EXISTS(atoll LWS_HAVE_ATOLL)
+CHECK_FUNCTION_EXISTS(_atoi64 LWS_HAVE__ATOI64)
+CHECK_FUNCTION_EXISTS(_stat32i64 LWS_HAVE__STAT32I64)
+CHECK_FUNCTION_EXISTS(clock_gettime LWS_HAVE_CLOCK_GETTIME)
+
+
+if (NOT LWS_HAVE_GETIFADDRS)
+	if (LWS_WITHOUT_BUILTIN_GETIFADDRS)
+		message(FATAL_ERROR "No getifaddrs was found on the system. Turn off the LWS_WITHOUT_BUILTIN_GETIFADDRS compile option to use the supplied BSD version.")
+	endif()
+	set(LWS_BUILTIN_GETIFADDRS 1)
+endif()
+
+if (LWS_EXT_PTHREAD_INCLUDE_DIR)
+	set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES};${LWS_EXT_PTHREAD_INCLUDE_DIR})
+	include_directories(${LWS_EXT_PTHREAD_INCLUDE_DIR})
+
+	list(APPEND LIB_LIST_AT_END ${LWS_EXT_PTHREAD_LIBRARIES})
+	set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} " -DHAVE_STRUCT_TIMESPEC=1")
+endif()
+
+#
+# add libs here that need to be at the end of the link order
+#
+
+if (LWS_EXT_PTHREAD_INCLUDE_DIR)
+	list(APPEND LIB_LIST_AT_END ${LWS_EXT_PTHREAD_LIBRARIES})
+endif()
+
+if (LWS_WITH_ZLIB AND NOT LWS_WITH_BUNDLED_ZLIB)
+	list(APPEND LIB_LIST_AT_END "${ZLIB_LIBRARIES}")
+endif()
+
+if (LWS_WITH_PLUGINS_API AND UNIX AND NOT (${CMAKE_SYSTEM_NAME} MATCHES "QNX"))
+	list(APPEND LIB_LIST_AT_END "dl")
+endif()
+
+
+CHECK_INCLUDE_FILE(in6addr.h LWS_HAVE_IN6ADDR_H)
+CHECK_INCLUDE_FILE(memory.h LWS_HAVE_MEMORY_H)
+CHECK_INCLUDE_FILE(netinet/in.h LWS_HAVE_NETINET_IN_H)
+CHECK_INCLUDE_FILE(stdint.h LWS_HAVE_STDINT_H)
+CHECK_INCLUDE_FILE(stdlib.h LWS_HAVE_STDLIB_H)
+CHECK_INCLUDE_FILE(strings.h LWS_HAVE_STRINGS_H)
+CHECK_INCLUDE_FILE(string.h LWS_HAVE_STRING_H)
+CHECK_INCLUDE_FILE(sys/prctl.h LWS_HAVE_SYS_PRCTL_H)
+CHECK_INCLUDE_FILE(sys/socket.h LWS_HAVE_SYS_SOCKET_H)
+CHECK_INCLUDE_FILE(sys/sockio.h LWS_HAVE_SYS_SOCKIO_H)
+CHECK_INCLUDE_FILE(sys/stat.h LWS_HAVE_SYS_STAT_H)
+CHECK_INCLUDE_FILE(sys/types.h LWS_HAVE_SYS_TYPES_H)
+CHECK_INCLUDE_FILE(unistd.h LWS_HAVE_UNISTD_H)
+CHECK_INCLUDE_FILE(vfork.h LWS_HAVE_VFORK_H)
+CHECK_INCLUDE_FILE(sys/capability.h LWS_HAVE_SYS_CAPABILITY_H)
+CHECK_INCLUDE_FILE(malloc.h LWS_HAVE_MALLOC_H)
+CHECK_INCLUDE_FILE(pthread.h LWS_HAVE_PTHREAD_H)
+CHECK_INCLUDE_FILE(inttypes.h LWS_HAVE_INTTYPES_H)
+
+if (WIN32 OR MSVC)
+	CHECK_C_SOURCE_COMPILES("#include <winsock2.h>
+				 #include <afunix.h>
+				 int main() { return 0; }" LWS_HAVE_WIN32_AFUNIX_H)
+
+	if (LWS_UNIX_SOCK AND NOT LWS_HAVE_WIN32_AFUNIX_H)
+		message("No afunix.h found. Disabling LWS_UNIX_SOCK.")
+		set(LWS_WITH_UNIX_SOCK OFF)
+	endif()
+endif()
+
+CHECK_LIBRARY_EXISTS(cap cap_set_flag "" LWS_HAVE_LIBCAP)
+
+
+if (LWS_WITH_ZLIB AND NOT LWS_WITH_BUNDLED_ZLIB)
+	if (LWS_WITH_MINIZ)
+		CHECK_INCLUDE_FILE(miniz.h LWS_HAVE_ZLIB_H)
+	else()
+		CHECK_INCLUDE_FILE(zlib.h LWS_HAVE_ZLIB_H)
+	endif()
+endif()
+
+CHECK_INCLUDE_FILES("stdlib.h;stdarg.h;string.h" STDC_HEADERS)
+
+if (NOT CMAKE_REQUIRED_FLAGS)
+	set(CMAKE_REQUIRED_FLAGS "")
+endif()
+if (NOT CMAKE_REQUIRED_INCLUDES)
+	set(CMAKE_REQUIRED_INCLUDES "")
+endif()
+if (NOT CMAKE_REQUIRED_LIBRARIES)
+	set(CMAKE_REQUIRED_LIBRARIES "")
+endif()
+
+CHECK_C_SOURCE_COMPILES("#include <stdint.h> 
+	int main(void) {
+		intptr_t test = 1;
+		return 0;
+	}" LWS_HAS_INTPTR_T)
+
+if ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR
+    (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
+	set(COMPILER_IS_CLANG ON)
+endif()
+
+if (LWS_HAVE_PTHREAD_H AND NOT LWS_PLAT_FREERTOS)
+	CHECK_C_SOURCE_COMPILES("#define _GNU_SOURCE
+		#include <pthread.h>
+		int main(void) {
+			pthread_t th = 0;
+			pthread_setname_np(th, NULL);
+			return 0;
+		}" LWS_HAS_PTHREAD_SETNAME_NP)
+endif()
+
+CHECK_C_SOURCE_COMPILES("#include <stddef.h>
+	#include <getopt.h>
+	int main(void) {
+		void *p = (void *)getopt_long;
+		return p != NULL;
+	}" LWS_HAS_GETOPT_LONG)
+
+
+if (NOT PID_T_SIZE)
+	set(pid_t int)
+endif()
+
+if (NOT SIZE_T_SIZE)
+	set(size_t "unsigned int")
+endif()
+
+if (NOT LWS_HAVE_MALLOC)
+	set(malloc rpl_malloc)
+endif()
+
+if (NOT LWS_HAVE_REALLOC)
+	set(realloc rpl_realloc)
+endif()
+
+
+
+
+if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG)
+    include (CheckCCompilerFlag)
+    CHECK_C_COMPILER_FLAG(-fvisibility=hidden LWS_HAVE_VISIBILITY)
+    if (LWS_WITH_FANALYZER)
+	    CHECK_C_COMPILER_FLAG(-fanalyzer LWS_HAVE_FANALYZER)
+    endif()
+    if (LWS_HAVE_VISIBILITY)
+                set(VISIBILITY_FLAG -fvisibility=hidden)
+    endif()
+    if (LWS_WITH_GCOV)
+	    set (GCOV_FLAGS "-fprofile-arcs -ftest-coverage ")
+    else()
+	    set(GCOV_FLAGS "")
+    endif()
+
+	if (LWS_WITH_ASAN)
+		set (ASAN_FLAGS "-fsanitize=address -fsanitize=undefined -fsanitize-address-use-after-scope -fsanitize-undefined-trap-on-error")
+		if (NOT COMPILER_IS_CLANG)
+			set (ASAN_FLAGS "${ASAN_FLAGS} -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=leak")
+		endif()
+		message("Enabling ASAN")
+	else()
+		set(ASAN_FLAGS "")
+	endif()
+
+	check_c_compiler_flag("-Wignored-qualifiers" LWS_GCC_HAS_IGNORED_QUALIFIERS)
+	check_c_compiler_flag("-Wtype-limits" LWS_GCC_HAS_TYPE_LIMITS)
+
+	if (LWS_GCC_HAS_IGNORED_QUALIFIERS)
+		set(CMAKE_C_FLAGS "-Wignored-qualifiers ${CMAKE_C_FLAGS}" )
+	endif()
+
+	if (LWS_GCC_HAS_TYPE_LIMITS)
+		set(CMAKE_C_FLAGS "-Wtype-limits ${CMAKE_C_FLAGS}" )
+	endif()
+
+	if (LWS_WITH_FANALYZER AND LWS_HAVE_FANALYZER)
+		set(CMAKE_C_FLAGS "-fanalyzer ${CMAKE_C_FLAGS}" )
+	endif()
+
+	if (CMAKE_COMPILER_IS_CLANG OR CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
+		set(CMAKE_C_FLAGS "-Wuninitialized ${CMAKE_C_FLAGS}")
+	endif()
+
+	# always warn all and generate debug info
+	if (UNIX AND NOT LWS_PLAT_FREERTOS)
+		set(CMAKE_C_FLAGS "-g -Wall -Wsign-compare -Wstrict-aliasing ${VISIBILITY_FLAG} -Wundef ${GCOV_FLAGS} ${CMAKE_C_FLAGS} ${ASAN_FLAGS}" )
+	else()
+		set(CMAKE_C_FLAGS "-g -Wall -Wsign-compare ${VISIBILITY_FLAG} ${GCOV_FLAGS} ${CMAKE_C_FLAGS}" )
+	endif()
+
+	if ("${DISABLE_WERROR}" STREQUAL "OFF")
+		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+	endif()
+endif ()
+
+if ((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT LWS_WITHOUT_TESTAPPS)
+	if (UNIX AND LWS_HAVE_PTHREAD_H AND NOT (${CMAKE_SYSTEM_NAME} MATCHES "QNX"))
+	# jeez clang understands -pthread but dies if he sees it at link time!
+	# http://stackoverflow.com/questions/2391194/what-is-gs-pthread-equiv-in-clang
+	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread" )
+    endif()
+endif()
+
+if (COMPILER_IS_CLANG)
+
+	# otherwise osx blows a bunch of openssl deprecated api errors
+	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations" )
+	if (UNIX AND LWS_HAVE_PTHREAD_H)
+		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wno-error=unused-command-line-argument" )
+	endif()
+endif()
+
+if (WINCE)
+	list(APPEND LIB_LIST_AT_END ws2.lib)
+elseif (WIN32)
+	list(APPEND LIB_LIST_AT_END ws2_32.lib userenv.lib psapi.lib iphlpapi.lib crypt32.lib)
+endif()
+
+if (MSVC)
+	# Turn off pointless microsoft security warnings.
+	add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+	# Fail the build if any warnings
+	add_compile_options(/W3 /WX)
+endif(MSVC)
+
+if (MINGW)
+	set(LWS_MINGW_SUPPORT 1)
+	set(CMAKE_C_FLAGS "-D__USE_MINGW_ANSI_STDIO ${CMAKE_C_FLAGS}")
+	add_definitions(-DWINVER=0x0601 -D_WIN32_WINNT=0x0601)
+endif()
+
+if (HDR_PRIVATE)
+	source_group("Headers Private"  FILES ${HDR_PRIVATE})
+endif()
+if (HDR_PUBLIC)
+	source_group("Headers Public"   FILES ${HDR_PUBLIC})
+endif()
+if (SOURCES)
+	source_group("Sources"          FILES ${SOURCES})
+endif()
+if (RESOURCES)
+	source_group("Resources"        FILES ${RESOURCES})
+endif()
+
+
+#
+# ZLIB (needed for deflate extension and if LWS_WITH_HTTP_STREAM_COMPRESSION)
+#
+if (LWS_WITH_ZLIB)
+	if (NOT ZLIB_FOUND)
+		if (LWS_WITH_MINIZ)
+			find_package(Miniz REQUIRED)
+			set(ZLIB_INCLUDE_DIRS ${MINIZ_INCLUDE_DIRS})
+			set(ZLIB_LIBRARIES ${MINIZ_LIBRARIES})
+		else()
+			find_package(ZLIB REQUIRED)
+		endif()
+	endif()
+	message("zlib/miniz include dirs: ${ZLIB_INCLUDE_DIRS}")
+	message("zlib/miniz libraries: ${ZLIB_LIBRARIES}")
+	include_directories(${ZLIB_INCLUDE_DIRS})
+	# done later at end of link list
+	# list(APPEND LIB_LIST ${ZLIB_LIBRARIES})
+	set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${ZLIB_LIBRARIES})
+	list(APPEND LIB_LIST_AT_END ${ZLIB_LIBRARIES})
+endif()
+
+
+if (LWS_WITH_FSMOUNT AND ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+	if (NOT LWS_LIBMOUNT_INCLUDE_DIRS STREQUAL "")
+		include_directories(${LWS_LIBMOUNT_INCLUDE_DIRS})
+		message("libmount include dir: ${LWS_LIBMOUNT_INCLUDE_DIRS}")
+	endif()
+	if (NOT LWS_LIBMOUNT_LIBRARIES STREQUAL "")
+		message("libmount libraries: ${LWS_LIBMOUNT_LIBRARIES}")
+		list(APPEND LIB_LIST ${LWS_LIBMOUNT_LIBRARIES})
+	else()
+		list(APPEND LIB_LIST mount)
+	endif()
+endif()
+
+
+if (LWS_WITH_SQLITE3)
+	if (NOT SQLITE3_FOUND)
+		find_path(SQLITE3_INCLUDE_DIRS NAMES sqlite3.h)
+		find_library(SQLITE3_LIBRARIES NAMES sqlite3)
+		if(SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES)
+			set(SQLITE3_FOUND 1)
+		endif()
+	endif()
+	message("sqlite3 include dir: ${SQLITE3_INCLUDE_DIRS}")
+	message("sqlite3 libraries: ${SQLITE3_LIBRARIES}")
+	include_directories("${SQLITE3_INCLUDE_DIRS}")
+	list(APPEND LIB_LIST ${SQLITE3_LIBRARIES})
+endif()
+
+
+if (LWS_WITH_HUBBUB)
+	find_library(LIBHUBBUB_LIBRARIES NAMES hubbub)
+	list(APPEND LIB_LIST ${LIBHUBBUB_LIBRARIES} )
+endif()
+
+if (LWS_HAVE_LIBCAP)
+	find_library(LIBCAP_LIBRARIES NAMES cap)
+	list(APPEND LIB_LIST ${LIBCAP_LIBRARIES} )
+endif()
+
+
+#
+# Append the "at end" pieces to the lib list
+#
+list(APPEND LIB_LIST ${LIB_LIST_AT_END})
+
+#
+# Second-level CMakeLists
+#
+
+include_directories("${PROJECT_SOURCE_DIR}/lib")
+add_subdirectory(lib)
+
+
+
+if(WIN32 AND NOT CYGWIN)
+  set(DEF_INSTALL_CMAKE_DIR cmake)
+else()
+  set(DEF_INSTALL_CMAKE_DIR lib${LIB_SUFFIX}/cmake/libwebsockets)
+endif()
+
+if (DEFINED REL_INCLUDE_DIR)
+    set(LWS__INCLUDE_DIRS "\${LWS_CMAKE_DIR}/${REL_INCLUDE_DIR}")
+endif() 
+
+configure_file(${PROJECT_SOURCE_DIR}/cmake/libwebsockets-config.cmake.in
+                ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libwebsockets-config.cmake 
+                @ONLY)
+
+# Generate version info for both build-tree and install-tree.
+configure_file(${PROJECT_SOURCE_DIR}/cmake/libwebsockets-config-version.cmake.in
+                ${PROJECT_BINARY_DIR}/libwebsockets-config-version.cmake 
+                @ONLY)
+
+# Generate the config file for the build-tree.
+set(LWS__INCLUDE_DIRS 
+    "${PROJECT_SOURCE_DIR}/lib"
+    "${PROJECT_BINARY_DIR}")
+set(LIBWEBSOCKETS_INCLUDE_DIRS ${LWS__INCLUDE_DIRS} CACHE PATH "Libwebsockets include directories")
+configure_file(${PROJECT_SOURCE_DIR}/cmake/libwebsockets-config.cmake.in
+                ${PROJECT_BINARY_DIR}/libwebsockets-config.cmake 
+                @ONLY)
+set(LWS_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
+
+# Export targets (This is used for other CMake projects to easily find the libraries and include files).
+if (LWS_WITH_EXPORT_LWSTARGETS)
+    export(TARGETS ${LWS_LIBRARIES}
+            FILE "${PROJECT_BINARY_DIR}/LibwebsocketsTargets.cmake")
+endif()
+
+
+
+set(libwebsockets_DIR ${PROJECT_BINARY_DIR})
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
+message("DIR ${libwebsockets_DIR} CMP ${CMAKE_MODULE_PATH}")
+
+if (LWS_WITH_MINIMAL_EXAMPLES)
+	add_subdirectory(minimal-examples)
+endif()
+
+if (NOT LWS_WITHOUT_TESTAPPS)
+	add_subdirectory(test-apps)
+endif()
+
+add_subdirectory(plugins)
+add_subdirectory(lwsws)
+
+# Generate the lws_config.h that includes all the public compilation settings.
+configure_file(
+       "${PROJECT_SOURCE_DIR}/cmake/lws_config.h.in"
+       "${PROJECT_BINARY_DIR}/lws_config.h")
+       
+add_custom_command(
+		OUTPUT ${PROJECT_BINARY_DIR}/include/lws_config.h
+			${PROJECT_BINARY_DIR}/include/libwebsockets
+			${PROJECT_BINARY_DIR}/include/libwebsockets.h
+		COMMENT "Creating build include dir"
+		COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/include/libwebsockets.h
+     			${CMAKE_CURRENT_BINARY_DIR}/include/libwebsockets.h
+		COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/include/libwebsockets/
+			${CMAKE_CURRENT_BINARY_DIR}/include/libwebsockets
+		COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/lws_config.h
+     			${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h
+		MAIN_DEPENDENCY ${PROJECT_BINARY_DIR}/lws_config.h
+)
+
+add_custom_target(GENHDR DEPENDS  ${PROJECT_BINARY_DIR}/include/lws_config.h)
+
+file(GLOB HDR_PUBLIC1 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/libwebsockets/*.h)
+file(GLOB HDR_PUBLIC2 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/libwebsockets.h)
+file(GLOB HDR_PUBLIC3 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h)
+list(APPEND HDR_PUBLIC ${HDR_PUBLIC1} ${HDR_PUBLIC2} ${HDR_PUBLIC3})
+
+set_source_files_properties(${HDR_PUBLIC} PROPERTIES GENERATED 1)
+
+if (LWS_WITH_STATIC)
+	add_dependencies(websockets GENHDR)
+endif()
+if (LWS_WITH_SHARED)
+	add_dependencies(websockets_shared GENHDR)
+endif()
+
+
+
+#
+#
+# Installation preparations.
+#
+
+export(PACKAGE libwebsockets)
+
+install(DIRECTORY include/libwebsockets
+	DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
+install(FILES ${PROJECT_BINARY_DIR}/include/libwebsockets.h ${PROJECT_BINARY_DIR}/include/lws_config.h
+	DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
+
+# Generate the config file for the installation tree.
+get_filename_component(LWS_ABSOLUTE_INSTALL_CMAKE_DIR ${LWS_INSTALL_CMAKE_DIR} ABSOLUTE)
+get_filename_component(LWS_ABSOLUTE_INSTALL_INCLUDE_DIR ${LWS_INSTALL_INCLUDE_DIR} ABSOLUTE)
+file(RELATIVE_PATH 
+    REL_INCLUDE_DIR 
+    "${LWS_ABSOLUTE_INSTALL_CMAKE_DIR}"
+    "${LWS_ABSOLUTE_INSTALL_INCLUDE_DIR}") # Calculate the relative directory from the cmake dir.
+
+set_target_properties(${LWS_LIBRARIES}
+		PROPERTIES PUBLIC_HEADER "${HDR_PUBLIC}")
+
+# Install the LibwebsocketsConfig.cmake and LibwebsocketsConfigVersion.cmake
+install(FILES
+               "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libwebsockets-config.cmake"
+               "${PROJECT_BINARY_DIR}/libwebsockets-config-version.cmake"
+               "${PROJECT_SOURCE_DIR}/cmake/LwsCheckRequirements.cmake"
+               DESTINATION "${LWS_INSTALL_CMAKE_DIR}" COMPONENT dev)
+
+# Install exports for the install-tree.
+if (LWS_WITH_EXPORT_LWSTARGETS)
+    install(EXPORT LibwebsocketsTargets
+            DESTINATION "${LWS_INSTALL_CMAKE_DIR}" COMPONENT dev)
+endif()
+
+# build subdir is not part of sources
+set(CPACK_SOURCE_IGNORE_FILES $(CPACK_SOURCE_IGNORE_FILES) "/.git/" "/build/" "\\\\.tgz$" "\\\\.tar\\\\.gz$")
+
+# Most people are more used to "make dist" compared to "make package_source"
+add_custom_target(dist COMMAND "${CMAKE_MAKE_PROGRAM}" package_source)
+
+
+#
+## This must always be last!
+#include(CPack)
+
+# Install headers for building the Urho3D library
+#install_header_files (DIRECTORY ./include/ DESTINATION ${DEST_INCLUDE_DIR}/ThirdParty/libwebsockets FILES_MATCHING PATTERN *.h BUILD_TREE_ONLY)  # Note: the trailing slash is significant

+ 32 - 0
Source/ThirdParty/libwebsockets/Kconfig

@@ -0,0 +1,32 @@
+menu "Libwebsockets"
+
+config LWS_MODEL_NAME
+	string "Model name of device firmware is for"
+	default "lws"
+
+config LWS_IS_FACTORY_APPLICATION
+	bool "Is this application is designed for the FACTORY flash slot"
+	default "n"
+
+config LWS_OTA_SERVER_FQDN
+	depends on LWS_IS_FACTORY_APPLICATION
+	string "Domain name of OTA update server, eg, warmcat.com"
+	default ""
+
+config LWS_OTA_SERVER_BASE_URL
+	depends on LWS_IS_FACTORY_APPLICATION
+	string "Base URL on OTA update server, eg, /esp32-ota (model is added)"
+	default "/esp32-ota"
+
+config LWS_OTA_SERVER_UPLOAD_USER
+	depends on LWS_IS_FACTORY_APPLICATION
+	string "User to scp to upload server with"
+	default "root"
+
+config LWS_OTA_SERVER_UPLOAD_PATH
+	depends on LWS_IS_FACTORY_APPLICATION
+	string "Path served in upload server (eg, \"/var/www/libwebsockets.org\""
+	default "/var/www/libwebsockets.org"
+
+endmenu
+

+ 56 - 0
Source/ThirdParty/libwebsockets/LICENSE

@@ -0,0 +1,56 @@
+Libwebsockets and included programs are provided under the terms of the
+MIT license shown below, with the exception that some sources are under
+a similar permissive license like BSD, or are explicitly CC0 / public
+domain to remove any obstacles from basing differently-licensed code on
+them.
+
+Original liberal license retained:
+
+  - lib/misc/sha-1.c          - 3-clause BSD license retained, link to original
+  - win32port/zlib            - ZLIB license (see zlib.h)
+  - lib/tls/mbedtls/wrapper   - Apache 2.0 (only built if linked against mbedtls)
+  - lib/misc/base64-decode.c  - already MIT
+
+Relicensed to MIT:
+
+  - lib/misc/daemonize.c               - relicensed from Public Domain to MIT,
+                                         link to original Public Domain version
+  - lib/plat/windows/windows-resolv.c  - relicensed from "Beerware v42" to MIT
+
+Public Domain (CC-zero) to simplify reuse:
+
+  - test-apps/*.c
+  - test-apps/*.h
+  - minimal-examples/*
+  - lwsws/*
+
+Although libwebsockets is available under a permissive license, it does not
+change the reality of dealing with large lumps of external code... if your
+copy diverges it is guaranteed to contain security problems after a while
+and can be very painful to pick backports (especially since historically,
+we are very hot on cleaning and refactoring the codebase).  The least
+painful and lowest risk way remains sending your changes and fixes upstream
+to us so you can easily use later releases and fixes.
+
+MIT License applied to libwebsockets:
+
+https://opensource.org/licenses/MIT 
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to
+ deal in the Software without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
+

+ 1 - 0
Source/ThirdParty/libwebsockets/Makefile.projbuild

@@ -0,0 +1 @@
+CPPFLAGS += -I$(BUILD_DIR_BASE)/libwebsockets/include

+ 444 - 0
Source/ThirdParty/libwebsockets/README.md

@@ -0,0 +1,444 @@
+[![CI status](https://libwebsockets.org/sai/status/libwebsockets)](https://libwebsockets.org/git/libwebsockets) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3576/badge.svg)](https://scan.coverity.com/projects/3576) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2266/badge)](https://bestpractices.coreinfrastructure.org/projects/2266) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/144fb195a83046e484a75c8b4c6cfc99)](https://www.codacy.com/app/lws-team/libwebsockets?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=warmcat/libwebsockets&amp;utm_campaign=Badge_Grade) [![Total alerts](https://img.shields.io/lgtm/alerts/g/warmcat/libwebsockets.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/warmcat/libwebsockets/alerts/) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/warmcat/libwebsockets.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/warmcat/libwebsockets/context:cpp) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/warmcat/libwebsockets.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/warmcat/libwebsockets/context:javascript)
+
+# Libwebsockets
+
+Libwebsockets is a simple-to-use, MIT-license, pure C library providing client and server
+for **http/1**, **http/2**, **websockets**, **MQTT** and other protocols in a security-minded,
+lightweight, configurable, scalable and flexible way.  It's easy to build and
+cross-build via cmake and is suitable for tasks from embedded RTOS through mass
+cloud serving.
+
+[80 independent minimal examples](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples) for
+various scenarios, CC0-licensed (public domain) for cut-and-paste, allow you to get started quickly.
+
+![overview](./doc-assets/lws-overview.png)
+
+News
+----
+
+## v4.1.0 and v4.1-stable are released
+
+See the [changelog](https://libwebsockets.org/git/libwebsockets/tree/changelog), summary
+
+ - NEW: travis / appveyor / bintray are replaced by Sai
+   https://libwebsockets.org/sai/ which for lws currently does 167 builds per
+   git push on 16 platforms, all self-hosted.  The homebrew bash scripts used
+   to select Minimal examples are replaced by CTest.  Platforms currently
+   include Fedora/AMD/GCC, Windows/AMD/mingw32, Windows/AMD/mingw64, Android/
+   aarch64/LLVM, esp-idf (on WROVER-KIT and HELTEC physical boards), Fedora/
+   RISCV (on QEMU)/GCC, CentOS8/AMD/GCC, Gentoo/AMD/GCC, Bionic/AMD/GCC,
+   Linkit 7697, Focal/AMD/GCC, Windows (on QEMU)/AMD/MSVC,
+   Focal/aarch64-RPI4/GCC, iOS/aarch64/LLVM and OSX/AMD/LLVM.
+
+ - NEW: The single CMakeLists.txt has been refactored and modernized into smaller
+ CMakeLists.txt in the subdirectory along with the code that is being managed
+ for build by it.  Build options are still listed in the top level as before
+ but the new way is much more maintainable.
+
+ - NEW: Captive Portal Detection.  Lws can determine if the active default
+ route is able to connect to the internet, or is in a captive portal type
+ situation, by trying to connect to a remote server that will respond in an
+ unusual way, like provide a 204.
+
+ - NEW: Secure streams: Support system trust store if it exists
+                        Build on Windows
+			Support lws raw socket protocol in SS
+			Support Unix Domain Socket transport
+
+ - NEW: Windows: Support Unix Domain Sockets same as other platforms
+
+ - NEW: Windows: Build using native pthreads, async dns, ipv6 on MSVC
+
+ - NEW: lws_struct: BLOB support
+
+ - NEW: lws_sul: Now provides two sorted timer domains, a default one as
+ before, and another whose scheduled events are capable to wake the system from suspend
+
+ - NEW: System Message Distribution: lws_smd provides a very lightweight way
+ to pass short messages between subsystems both in RTOS type case where the
+ subsystems are all on the lws event loop, and in the case participants are in
+ different processes, using Secure Streams proxying.   Participants register a bitmap
+ of message classes they care about; if no particpant cares about a particular message,
+ it is rejected at allocation time for the sender, making it cheap to provide messages
+ speculatively.  See lib/system/smd/README.md for full details.
+
+ - NEW: lws_drivers: wrappers for SDK driver abstractions (or actual drivers)
+		 See lib/drivers/README.md, example implementations
+		 minimal-examples/embedded/esp32/esp-wrover-kit
+                     - generic gpio
+		     - generic LED (by name)    lib/drivers/led/README.md
+		     - generic PWM, sophisticated interpolated table
+		                    sequencers with crossfade  
+		     - generic button (by name), with debounce and press classification
+		                       emitting rich SMD click, long-click, double-click,
+				       down, repeat, up JSON messages
+				       lib/drivers/button/README.md
+		     - bitbang i2c on generic gpio (hw support can use same
+		                       abstract API)
+		     - bitbang spi on generic gpio (hw support can use same
+		                       abstract API)
+		     - generic display object, can be wired up to controller
+		                  drivers that hook up by generic i2c or spi,
+				  generic backlight PWM sequencing and
+				  blanking timer support
+		     - generic settings storage: get and set blobs by name
+		     - generic network device: netdev abstract class with
+	                                       WIFI / Ethernet implementations
+					       using underlying SDK APIs;
+					       generic 80211 Scan managements
+					       and credentials handling via
+					       lws_settings
+		     This is the new way to provide embedded platform
+		     functionality that was in the past done like
+		     esp32-factory.  Unlike the old way, the new way has no
+		     native apis in it and can be built on other SDK / SoCs
+		     the same.
+
+ - NEW: Security-aware JWS JWT (JSON Web Tokens) apis are provided on top of the existing
+ JOSE / JWS apis.  All the common algorithms are available along with some
+ high level apis like lws http cookie -> JWT struct -> lws http cookie.
+
+ - REMOVED: esp32-helper and friends used by esp32-factory now lws_drivers
+ exists
+
+ - REMOVED: generic sessions and friends now JWT is provided
+
+## v4.0 is released
+
+Users wanting a stable branch should follow v4.0-stable to get the most stable version
+at any given time.
+
+See the [changelog](https://libwebsockets.org/git/libwebsockets/tree/changelog) for
+information on the huge amount of new features in this release, and additional information
+below.
+
+```
+ - NEW: Lws is now under the MIT license, see ./LICENSE for details
+ 
+ - NEW: GLIB native event loop support, lws + gtk example
+
+ - NEW: native lws MQTT client... supports client stream binding like h2 when
+   multiple logical connections are going to the same endpoint over MQTT, they
+   transparently and independently share the one connection + tls tunnel
+ 
+ - NEW: "Secure Streams"... if you are making a device with client connections
+   to the internet or cloud, this allows separation of the communications
+   policy (endpoints, tls cert validation, protocols, etc) from the code, with
+   the goal you can combine streams, change protocols and cloud provision, and
+   reflect that in the device's JSON policy document without having to change
+   any code.
+
+ - NEW: lws_system: New lightweight and efficient Asynchronous DNS resolver
+   implementation for both A and AAAA records, supports recursive (without
+   recursion in code) lookups, caching, and getaddrinfo() compatible results
+   scheme (from cache directly without per-consumer allocation).  Able to
+   perform DNS lookups without introducing latency in the event loop.
+
+ - NEW: lws_system: ntpclient implementation with interface for setting system
+   time via lws_system ops
+ 
+ - NEW: lws_system: dhcpclient implementation
+ 
+ - NEW: Connection validity tracking, autoproduce PING/PONG for protocols that
+   support it if not informed that the connection has passed data in both
+   directions recently enough
+
+ - NEW: lws_retry: standardized exponential backoff and retry timing based
+   around backoff table and lws_sul
+
+ - NEW: there are official public helpers for unaligned de/serialization of all
+   common types, see eh, lws_ser_wu16be() in include/libwebsockets/lws-misc.h
+
+ - NEW: lws_tls_client_vhost_extra_cert_mem() api allows attaching extra certs
+   to a client vhost from DER in memory
+   
+ - NEW: lws_system: generic blobs support passing auth tokens, per-connection
+   client certs etc from platform into lws
+
+ - NEW: public helpers to consume and produce ipv4/6 addresses in a clean way,
+   along with lws_sockaddr46 type now public.  See eg, lws_sockaddr46-based
+   lws_sa46_parse_numeric_address(), lws_write_numeric_address()
+   in include/libwebsockets/lws-network-helper.h
+
+ - Improved client redirect handling, h2 compatibility
+ 
+ - NEW: lwsac: additional features for constant folding support (strings that
+   already are in the lwsac can be pointed to without copying again), backfill
+   (look for gaps in previous chunks that could take a new use size), and
+   lwsac_extend() so last use() can attempt to use more unallocated chunk space
+
+ - NEW: lws_humanize: apis for reporting scalar quanties like 1234 as "1.234KB"
+   with the scaled symbol strings passed in by caller
+
+ - NEW: freertos: support lws_cancel_service() by using UDP pair bound to lo,
+   since it doesn't have logical pipes
+
+ - NEW: "esp32" plat, which implemented freertos plat compatibility on esp32, is
+   renamed to "freertos" plat, targeting esp32 and other freertos platforms
+
+ - NEW: base64 has an additional api supporting stateful decode, where the input
+   is not all in the same place at the same time and can be processed
+   incrementally
+
+ - NEW: lws ws proxy: support RFC8441
+   
+ - NEW: lws_spawn_piped apis: generic support for vforking a process with child
+   wsis attached to its stdin, stdout and stderr via pipes.  When processes are
+   reaped, a specified callback is triggered.  Currently Linux + OSX.
+   
+ - NEW: lws_fsmount apis: Linux-only overlayfs mount and unmount management for
+   aggregating read-only layers with disposable, changeable upper layer fs
+
+ - Improvements for RTOS / small build case bring the footprint of lws v4 below
+   that of v3.1 on ARM 
+   
+ - lws_tokenize: flag specifying # should mark rest of line as comment
+
+ - NEW: minimal example for integrating libasound / alsa via raw file
+
+ - lws_struct: sqlite and json / lejp translation now usable
+
+
+```
+
+## Introducing Secure Streams client support
+
+Secure Streams is an optional layer above lws (`-DLWS_WITH_SECURE_STREAMS=1`) that
+separates connectivity policy into a JSON document, which can be part of the
+firmware or fetched at boot time.
+
+Code no longer deals with details like endpoint specification or tls cert stack used
+to validate the remote server, it's all specified in JSON, eg, see
+[this example](https://warmcat.com/policy/minimal-proxy.json).  Even the protocol to use to talk to the
+server, between h1, h2, ws or MQTT, is specified in the policy JSON and the code
+itself just deals with payloads and optionally metadata, making it possible to
+switch endpoints, update certs and even switch communication protocols by just
+editing the JSON policy and leaving the code alone.
+
+Logical Secure Stream connections outlive any underlying lws connection, and support
+"nailed-up" connection reacquisition and exponential backoff management.
+
+See [./lib/secure-streams/README.md](https://libwebsockets.org/git/libwebsockets/tree/lib/secure-streams/README.md) and the related minimal examples
+for more details.
+
+## mqtt client support
+
+If you enable `-DLWS_ROLE_MQTT=1`, lws can now support QoS0 and QoS1 MQTT client
+connections.  See the examples at ./minimal-examples/mqtt-client
+
+## libglib native event loop support
+
+glib's event loop joins libuv, libevent and libev support in lws for both the
+`lws_context` creating and owning the loop object for its lifetime, and for
+an already-existing "foreign loop" where the `lws_context` is created, attaches,
+detaches, and is destroyed without affecting the loop.
+
+This allows direct, lock-free integration of lws functionality with, eg, a GTK app's
+existing `GMainLoop` / glib `g_main_loop`.  Just select `-DLWS_WITH_GLIB=1` at cmake
+time to enable.  The -eventlib minimal examples also support --glib option to
+select using the glib loop at runtime.
+
+There's also a gtk example that is built if lws cmake has `-DLWS_WITH_GTK=1`.
+
+## `lws_system` helper for attaching code to a single event loop from another thread
+
+`lws_system` ops struct now has a member that enables other threads (in the
+same process) to request a callback they define from the lws event loop thread
+context as soon as possible.  From here, in the event loop thread context,
+they can set up their lws functionality before returning and letting it
+operate wholly from the lws event loop.  The original thread calling the
+api to request the callback returns immediately.
+
+## Improvements on tx credit
+
+H2 clients and servers can now modulate RX flow control on streams precisely,
+ie, define the size of the first incoming data and hand out more tx credit
+at timing of its choosing to throttle or completely quench the remote server
+sending as it likes.
+
+The only RFC-compatible way to acheive this is set the initial tx credit to
+0 and set it explicitly when sending the headers... client code can elect to
+do this rather than automatically manage the credit by setting a new flag
+LCCSCF_H2_MANUAL_RXFLOW and indicating the initial tx credit for that stream
+in client connection info member manual_initial_tx_credit.  A new public api
+lws_wsi_tx_credit() allows dynamic get and add to local and estimated remote
+peer credit for a connection.  This api can be used without knowing if the
+underlying connection is h2 or not.
+
+## `lws_system`: DHCP client
+
+DHCP client is now another network service that can be integrated into lws, with
+`LWS_WITH_SYS_DHCP_CLIENT` at CMake.  When enabled, the `lws_system` state
+is held at `DHCP` until at least one registered network interface acquires a
+usable set of DHCP information including ip, subnet mask, router / gateway
+address and at least one DNS server.
+
+See the [api-test-dhcp](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-dhcpc) Minimal Example for how to use.
+
+## UDP integration with `lws_retry`
+
+UDP support in lws has new helper that allow `lws_retry` to be applied for retry,
+and the ability to synthesize rx and tx udp packetloss systemwide to confirm
+retry strategies.  Since multiple transactions may be in flight on one UDP
+socket, the support relies on an `lws_sul` in the transaction object to manage
+the transaction retries individually.
+
+See `READMEs/README.udp.md` for details.
+
+## `lws_system`: system state and notification handlers
+
+Lws now has the concept of systemwide state held in the context... this is to
+manage that there may be multiple steps that need the network before it's possible
+for the user code to operate normally.  The steps defined are
+
+`CONTEXT_CREATED`, `INITIALIZED`, `IFACE_COLDPLUG`, `DHCP`, `TIME_VALID`, `POLICY_VALID`,
+`REGISTERED`, `AUTH1`, `AUTH2`, `OPERATIONAL` and `POLICY_INVALID`.  OPERATIONAL is the
+state where user code can run normally.
+
+User and other parts of lws can hook notifier callbacks to receive and be able to
+veto system state changes, either definitively or because they have been triggered
+to perform a step asynchronously and will move the state on themselves when it
+completes.
+
+By default just after context creation, lws attempts to move straight to OPERATIONAL.
+If no notifier interecepts it, it will succeed to do that and operate in a
+backwards-compatible way.  Enabling various features like lws ntpclient also enable
+notifiers that hold progress at the related state until their operation completes
+successfully, eg, not able to enter `TIME_VALID` until ntpclient has the time.
+
+See `READMEs/README.lws_system.md` for details.
+
+## `lws_system`: HAL ops struct
+
+Lws allows you to define a standardized ops struct at context creation time so your
+user code can get various information like device serial number without embedding
+system-specific code throughout the user code.  It can also perform some generic
+functions like requesting a device reboot.
+
+See `READMEs/README.lws_system.md` for details.
+
+## `lws_system`: ntpclient
+
+Optional lws system service enabled by cmake `-DLWS_WITH_SYS_NTPCLIENT` intercepts
+the `lws_system` `TIME_VALID` state and performs ntpclient to get the date and time
+before entering `TIME_VALID`.  This allows user code to validate tls certificates
+correctly knowing the current date and time by the time it reached OPERATIONAL.
+
+## Connection Validity tracking
+
+Lws now allows you to apply a policy for how long a network connection may go
+without seeing something on it that confirms it's still valid in the sense of
+passing traffic cohernetly both ways.  There's a global policy in the context
+which defaults to 5m before it produces a PING if possible, and 5m10 before
+the connection will be hung up, user code can override this in the context,
+vhost (for server) and client connection info (for client).
+
+An api `lws_validity_confirmed(wsi)` is provided so user code can indicate
+that it observed traffic that must mean the connection is passing traffic in
+both directions to and from the peer.  In the absence of these confirmations
+lws will generate PINGs and take PONGs as the indication of validity.
+
+## `lws_system`: Async DNS support
+
+Master now provides optional Asynchronous (ie, nonblocking) recursive DNS resolving.
+Enable with `-DLWS_WITH_SYS_ASYNC_DNS=1` at cmake.  This provides a quite
+sophisticated ipv4 + ipv6 capable resolver that autodetects the dns server on
+several platforms and operates a UDP socket to its port 53 to produce and parse DNS
+packets from the event loop.  And of course, it's extremely compact.
+
+It broadly follows the getaddrinfo style api, but instead of creating the results
+on the heap for each caller, it caches a single result according to the TTL and
+then provides refcounted const pointers to the cached result to callers.  While
+there are references on the cached result it can't be reaped.
+
+See `READMEs/README.async-dns.md` for detailed information on how it works, along
+with `api-tests/api-test-async-dns` minimal example.
+
+## Detailed Latency
+
+You can now opt to measure and store us-resolution statistics on effective
+latencies for client operations, and easily spool them to a file in a
+format suitable for gnuplot, or handle in your own callback.  Enable
+`-DLWS_WITH_DETAILED_LATENCY=1` in cmake to build it into lws.
+
+If you are concerned about operation latency or potential blocking from
+user code, or behaviour under load, or latency variability on specific
+platforms, you can get real numbers on your platform using this.
+
+Timings for all aspects of events on connections are recorded, including
+the time needed for name resolution, setting up the connection, tls
+negotiation on both client and server sides, and each read and write.
+
+See `READMEs/README.detailed-latency.md` for how to use it.
+
+## Client connection logic rewrite
+
+Lws master now makes much better use of the DNS results for ipv4 and ipv6... it
+will iterate through them automatically making the best use it can of what's
+provided and attempting new connections for each potentially usable one in turn
+before giving up on the whole client connection attempt.
+
+If ipv6 is disabled at cmake it can only use A / ipv4 records, but if ipv6 is
+enabled, it tries both; if only ipv6 is enabled it promotes ipv4 to
+::ffff:1.2.3.4 IPv4-in-IPv6 addresses.
+
+## New network helpers for ipv4 and ipv6
+
+An internal union `lws_sockaddr46` that combines `struct sockaddr_in` and
+`struct sockaddr_in6` is now public, and there are helpers that can parse (using
+`lws_tokenize`) any valid numeric representation for ipv4 and ipv6 either
+into byte arrays and lengths, or directly to and from `lws_sockaddr46`.
+
+## h2 long poll support
+
+Lws now supports the convention that half-closing an h2 http stream may make
+the stream 'immortal', in terms of not being bound by normal timeouts.  For
+the client side, there's an api that can be applied to the client stream to
+make it transition to this "read-only" long poll mode.
+
+See `READMEs/README.h2-long-poll.md` for full details, including how to test
+it with the minimal examples.
+
+## h1 client parser improvements
+
+H1 is not so simple to parse because the header length is not known until it
+has been fully parsed.  The next header, or http body may be directly coalesced
+with the header as well.  Lws has supported bulk h1 parsing from a buffer for a
+long time, but on clientside due to interactions with http proxying it had
+been stuck parsing the header bytewise out of the tls buffer.  In master,
+everything now bulk parses from a buffer and uses a buflist to pass leftovers
+through the event loop cleanly.
+
+## `lws_sul` time refactor
+
+Just before v3.2 there was a big refactor about how lws handles time.  It now
+explicitly schedules anything that may happen in the future on a single, sorted
+linked-list, at us resolution.  When entering a poll wait (or returning to an
+event lib loop) it checks the interval between now and the earliest event on the
+list to figure out how long to wait if there are no network events.  For the
+event loop case, it sets a native event lib timer to enforce it.
+
+See `READMEs/README.lws_sul.md` for more details and a handy api where you can
+schedule your own arbitrary callbacks using this system.
+
+## Master is now MIT-licensed
+
+Libwebsockets master is now under the MIT license. See ./LICENSE.
+
+## Support
+
+This is the libwebsockets C library for lightweight websocket clients and
+servers.  For support, visit
+
+ https://libwebsockets.org
+
+and consider joining the project mailing list at
+
+ https://libwebsockets.org/mailman/listinfo/libwebsockets
+
+You can get the latest version of the library from git:
+
+- https://libwebsockets.org/git
+
+Doxygen API docs for master: https://libwebsockets.org/lws-api-doc-master/html/index.html
+

+ 100 - 0
Source/ThirdParty/libwebsockets/READMEs/README.async-dns.md

@@ -0,0 +1,100 @@
+# Asynchronous DNS
+
+## Introduction
+
+Lws now features optional asynchronous, ie, nonblocking recursive DNS
+resolution done on the event loop, enable `-DLWS_WITH_SYS_ASYNC_DNS=1`
+at cmake to build it in.
+
+## Description
+
+The default libc name resolution is via libc `getaddrinfo()`, which is
+blocking, possibly for quite long periods (seconds).  If you are
+taking care about latency, but want to create outgoing connections,
+you can't tolerate this exception from the rule that everything in
+lws is nonblocking.
+
+Lws' asynchronous DNS resolver creates a caching name resolver
+that directly queries the configured nameserver itself over UDP,
+from the event loop.
+
+It supports both ipv4 / A records and ipv6 / AAAA records (see later
+for a description about how).  One server supported over UDP :53,
+and the nameserver is autodicovered on linux, windows, and freertos.
+    
+Other features
+
+ - lws-style paranoid response parsing
+ - random unique tid generation to increase difficulty of poisoning
+ - it's really integrated with the lws event loop, it does not spawn
+   threads or use the libc resolver, and of course no blocking at all
+ - platform-specific server address capturing (from /etc/resolv.conf
+   on linux, windows apis on windows)
+ - LRU caching
+ - piggybacking (multiple requests before the first completes go on
+    a list on the first request, not spawn multiple requests)
+ - observes TTL in cache
+ - TTL and timeout use `lws_sul` timers on the event loop
+ - Uses CNAME resolution inside the same response if present, otherwise
+   recurses to resolve the CNAME (up to 3 deep)
+ - ipv6 pieces only built if cmake `LWS_IPV6` enabled
+
+## Api
+
+If enabled at cmake, the async DNS implementation is used automatically
+for lws client connections.  It's also possible to call it directly, see
+the api-test-async-dns example for how.
+
+The Api follows that of `getaddrinfo()` but results are not created on
+the heap.  Instead a single, const cached copy of the addrinfo struct
+chain is reference-counted, with `lws_async_dns_freeaddrinfo()` provided
+to deduct from the reference count.  Cached items with a nonzero
+reference count can't be destroyed from the cache, so it's safe to keep
+a pointer to the results and iterate through them.
+
+## Dealing with IPv4 and IPv6
+
+DNS is a very old standard that has some quirks... one of them is that
+multiple queries are not supported in one packet, even though the protocol
+suggests it is.  This creates problems on ipv6 enabled systems, where
+it may prefer to have AAAA results, but the server may only have A records.
+
+To square the circle, for ipv4 only systems (`LWS_IPV6=0`) the resolver
+requests only A records.  For ipv6-capable systems, it always requests
+first A and then immediately afterwards AAAA records.
+
+To simplify the implementation, the tid b0 is used to differentiate
+between A (b0 = 0) and AAAA (b0 = 1) requests and responses using the
+same query body.
+
+The first response to come back is parsed, and a cache entry made...
+it leaves a note in the query about the address of the last `struct addrinfo`
+record.  When the second response comes, a second allocation is made,
+but not added to the logical cache... instead it's chained on to the
+first cache entry and the `struct addrinfo` linked-list from the
+first cache entry is extended into the second one.  At the time the
+second result arrives, the query is destroyed and the cached results
+provided on the result callback.
+
+## Recursion
+
+Where CNAMEs are returned, DNS servers may take two approaches... if the
+CNAME is also resolved by the same server and so it knows what it should
+resolve to, it may provide the CNAME resolution in the same response
+packet.
+
+In the case the CNAME is actually resolved by a different name server,
+the server with the CNAME does not have the information to hand to also
+resolve the CNAME in the same response.  So it just leaves it for the
+client to sort out.
+
+The lws implementation can deal with both of these, first it "recurses"
+(it does not recurse on the process stack but uses its own manual stack)
+to look for results in the same packet that told it about the CNAME.  If
+there are no results, it resets the query to look instead for the CNAME,
+and restarts it.  It allows this to happen for 3 CNAME deep.
+
+At the end, either way, the cached result is set using the original
+query name and the results from the last CNAME in the chain.
+
+

+ 77 - 0
Source/ThirdParty/libwebsockets/READMEs/README.build-android.md

@@ -0,0 +1,77 @@
+# Building for Android NDK
+
+If you have the ndk and prebuilt toolchains with that, you can simply build
+lws library for your android app from one cmake and one make command.
+
+However if you want a tls lib, you have to take care of building and pointing
+to that first.  But if it's a cmake project like mbedtls, that also is just a
+matter of one cmake and one make.
+
+## Installing NDK pieces
+
+There's probably a more direct way but the official way is install the whole
+Android Studio and then run `sdkmanager` to install a recent NDK.
+
+I installed the sdk and ndk pieces into /opt/android/ and that's how the
+`./contrib/cross-aarch64-android.cmake` toolchain file is shipped.  You can
+adapt some settings at the top of that file including the path if needed.
+
+## Fetching lws (needed first for cross toolchain file)
+
+It doesn't care where you put these projects, but for simplicity they should
+be in the same parent dir, like
+
+```
+ - /home/someone
+  - /home/someone/libwebsockets
+  - /home/someone/mbedtls
+```
+
+The reason is that building mbedtls need the cross toolchain file from
+libwebsockets, that's also why we have to get libwebsockets first now but
+build it later.
+
+```
+$ git clone https://libwebsockets.org/repo/libwebsockets
+```
+
+## Building mbedtls
+
+```
+$ git clone https://github.com/ARMmbed/mbedtls.git
+$ cd mbedtls
+$ mkdir build
+$ cd build
+$ rm -f CMakeCache.txt && \
+  cmake .. -DCMAKE_TOOLCHAIN_FILE=../libwebsockets/contrib/cross-aarch64-android.cmake \
+  -DUSE_SHARED_MBEDTLS_LIBRARY=1 \
+  -DENABLE_PROGRAMS=0 \
+  -Wno-dev && \
+  make -j && \
+  cmake --install .
+```
+
+The lws toolchain file sets the path to install into as the cross root path, so
+despite it looks like the destination dir is missing for the install, it will
+go into, eg `/opt/android/ndk/21.1.6352462/platforms/android-24/arch-arm64/lib/libmbedcrypto.a`
+where lws will look for it
+
+## Building lws
+
+You don't need to explain where mbedtls can be found... lws will build with the
+same toolchain file that sets the cross root to the same place as mbedtls, it
+will easily find them there without any further hints.
+
+```
+$ mkdir build
+$ cd build
+$ rm -f CMakeCache.txt && \
+  cmake .. -DCMAKE_TOOLCHAIN_FILE=../libwebsockets/contrib/cross-aarch64-android.cmake \
+  -DLWS_WITH_MBEDTLS=1 \
+  -DLWS_WITHOUT_TESTAPPS=1 && \
+  make && \
+  cmake --install .
+```
+
+That's it, both mbedtls and lws library and header files are installed into the
+ndk cross root.

+ 214 - 0
Source/ThirdParty/libwebsockets/READMEs/README.build-windows.md

@@ -0,0 +1,214 @@
+# Some notes for the windows jungle
+
+This was how I compiled libwebsockets starting from a blank windows install
+in March - April 2020.  Doing this on a linux distro is way simpler and quicker
+than all this!
+
+## Notes on vm installation
+
+### Disk size
+
+For building you'll need 40GB+ available for the guest storage.
+
+### Required: Windows product key
+
+Assuming like me the first thing you do with a new laptop is install Linux over
+the windows it came with, you can recover your 'windows tax' windows product key
+from your device typically using `sudo strings /sys/firmware/acpi/tables/MSDM`,
+and use that for your VM install.
+
+### Required: Spice guest 
+
+To have shared clipboard, and for windows video driver to match your vm window
+resolution, you must install spice guest tools inside the windows VM.  It also
+installs some virtio pieces you will want.
+
+https://www.spice-space.org/download/windows/spice-guest-tools/spice-guest-tools-latest.exe
+
+### Blood-pressure reduction: Firefox
+
+https://www.mozilla.org/en-US/exp/firefox/
+
+When it's up, add-ons: ublock origin, privacy badger, noscript, disable search
+bar prediction
+
+### Blood-pressure reduction: Clink
+
+This is a hack on cmd.exe that lets it understand Ctrl-R and fixup unix-style
+slashes automagically.
+
+https://github.com/mridgers/clink/releases/download/0.4.9/clink_0.4.9_setup.exe
+
+If you're usually using *nix, you definitely need this to keep your sanity.
+
+### Required: cmake
+
+CMake have a windows installer thing downloadable from here
+
+[cmake](https://cmake.org/download/)
+
+after that you can use `cmake` from the terminal OK.
+
+### Required: git
+
+Visit the canonical git site to download their windows installer thing
+
+[git](https://git-scm.com/download/win)
+
+**Select the install option for "extra unix commands"** so you can get `ls -l`,
+`cp`, `mv` and suchlike working in cmd.exe... that's awesome, thanks git!
+
+Afterwards you can just use `git` as normal from cmd.exe as well.
+
+### Required: Install the "free" "community" visual studio
+
+You can do this through "windows store" by searching for "visual studio"
+
+I installed as little as possible, we just want the C "C++" tools... 7GB :-)
+
+It still wouldn't link without the "mt" helper tool from the
+huge windows SDK, so you have to install GB of that as well.
+
+They don't mention it during the install, but after 30 days this "free"
+"community" edition demands you open a microsoft account or it stops working.
+In the install they give you the option to add a microsoft account and the
+alternative is, "not now, maybe later".  Compare and contrast to gcc or git or
+the other FOSS projects.
+
+### Required: OpenSSL
+
+Ugh... I tried using prebuilts but it's unreliable and needs an unfeasible
+amount of trust.  So I recommend bite the bullet and build your own... that's
+trivial on Linux but of course windows makes everything nasty.
+
+At least hopefully all the "research" is done and listed out here.
+
+#### OpenSSL build Prerequisite: install perl binary
+
+Move the git version of perl out of the way, it won't work for OpenSSL build
+
+```
+mv /usr/bin/perl /usr/bin/perl-git
+```
+
+For windows, OpenSSL "recommends" ActiveState perl but it doesn't work for me,
+complaining about stuff needed from cpan and then dying when it was installed.
+"Strawberry Perl" is installed in `C:\Strawberry` and worked out the box.
+
+http://strawberryperl.com/download/5.30.2.1/strawberry-perl-5.30.2.1-64bit.msi
+
+The installer sets up `%PATH%` if you open a new cmd window.  
+
+#### OpenSSL build Prerequisite: NASM
+
+Go here and click on the latest stable, download the win32 .exe
+
+https://nasm.us/
+
+Just install via the defaults.  Then add it to the PATH temporarily...
+
+```
+$ set PATH=%PATH%;C:\Program Files (x86)\NASM
+```
+
+#### OpenSSL build setup: source VC env vars
+
+These fix up the PATH and include dirs etc necessary for VC build in the cmd
+window.
+
+```
+$ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
+```
+
+### OpenSSL build:
+
+Grab openssl from git... assuming the prerequisites above went well it will
+just sit there building for 30 minutes or whatever.
+
+```
+$ git clone https://github.com/openssl/openssl
+$ cd openssl
+$ perl Configure VC-WIN64A
+$ nmake
+```
+
+Afterwards, open an Administrator mode cmd.exe, redo the msvc path and then
+install the build.
+
+```
+$ cd openssl
+$ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
+$ nmake install
+```
+
+Oh another grindingly slow windows build action.  Finally it's in there in
+`C:\Program Files\OpenSSL`.
+
+libraries are looking for a cert bundle at "C:\Program Files\Common Files\SSL\cert.pem"...
+it's not documented or included in the zip file from the above, so...
+
+#### Installing a cert bundle
+
+You can get a trusted cert bundle from here
+
+[drwetter/testssl cert bundle](https://raw.githubusercontent.com/drwetter/testssl.sh/3.1dev/etc/Microsoft.pem)
+
+Save it into `C:\Program Files\Common Files\SSL\cert.pem` where openssl will be able to see it.
+
+## Required: pthreads
+
+It's amazing but after all these years windows doesn't offer pthreads compatibility
+itself.  Just like the many other missing POSIX bits like fork().
+
+I downloaded the latest (2012) zip release of pthreads-win32 from here
+
+ftp://sourceware.org/pub/pthreads-win32
+
+Then I created a dir "C:\Program Files (x86)\pthreads", and copied the `dll`,
+`include` and `lib` subdirs from the `prebuilt` folder in the zip there.
+
+The cmake incantation to build against pthreads set up like that is
+
+```
+ $ cmake .. -DLWS_HAVE_PTHREAD_H=1 -DLWS_EXT_PTHREAD_INCLUDE_DIR="C:\Program Files (x86)\pthreads\include" -DLWS_EXT_PTHREAD_LIBRARIES="C:\Program Files (x86)\pthreads\lib\x64\libpthreadGC2.a" -DLWS_WITH_MINIMAL_EXAMPLES=1
+```
+
+## Building libwebsockets
+
+We'll clone libwebsockets then use cmake to build via vs tools
+
+```
+> git clone https://libwebsockets.org/repo/libwebsockets
+> cd libwebsockets
+> mkdir build
+> cd build
+> cmake ..
+> cmake --build . --config DEBUG
+```
+
+Installing requires admin privs, I opened a second cmd window as admin and did it
+there.
+
+```
+> cmake --install . --config DEBUG
+```
+
+### Hack the libs into view
+
+The libs we built against aren't visible in the system, I don't know what
+Real Windows Programmers are supposed to do about that, but I used an Admin cmd
+prompt to copy them into C:\windows\system32
+
+```
+$ cp "C:\Program Files (x86)\pthreads\dll\x64\pthreadGC2.dll" "C:\Program Files\OpenSSL\bin\libcrypto-3.dll"  "C:\Program Files\OpenSSL\bin\libssl-3.dll" C:\Windows\system32
+```
+
+After that you can run the test apps OK, eg
+
+```
+$ libwebsockets-test-server.exe -s
+```
+
+## Note about using paths with spaces in with cmake
+
+

+ 741 - 0
Source/ThirdParty/libwebsockets/READMEs/README.build.md

@@ -0,0 +1,741 @@
+Notes about building lws
+========================
+
+You can download and install lws using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
+```
+git clone https://github.com/microsoft/vcpkg.git
+cd vcpkg
+./bootstrap-vcpkg.sh
+./vcpkg integrate install
+vcpkg install libwebsockets
+```
+The lws port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg/) on the vcpkg repository.
+
+@section cm Introduction to CMake
+
+CMake is a multi-platform build tool that can generate build files for many
+different target platforms. See more info at http://www.cmake.org
+
+CMake also allows/recommends you to do "out of source"-builds, that is,
+the build files are separated from your sources, so there is no need to
+create elaborate clean scripts to get a clean source tree, instead you
+simply remove your build directory.
+
+Libwebsockets has been tested to build successfully on the following platforms
+with SSL support (for OpenSSL/wolfSSL/BoringSSL):
+
+- Windows (Visual Studio)
+- Windows (MinGW)
+- Linux (x86 and ARM)
+- OSX
+- NetBSD
+
+
+@section build1 Building the library and test apps
+
+The project settings used by CMake to generate the platform specific build
+files is called [CMakeLists.txt](../CMakeLists.txt). CMake then uses one of its "Generators" to
+output a Visual Studio project or Make file for instance. To see a list of
+the available generators for your platform, simply run the "cmake" command.
+
+Note that by default OpenSSL will be linked, if you don't want SSL support
+see below on how to toggle compile options.
+
+
+@section bu Building on Unix:
+
+1. Install CMake 2.8 or greater: http://cmake.org/cmake/resources/software.html
+   (Most Unix distributions comes with a packaged version also)
+
+2. Install OpenSSL.
+
+3. Generate the build files (default is Make files):
+```
+        $ cd /path/to/src
+        $ mkdir build
+        $ cd build
+        $ cmake ..
+```
+
+4. Finally you can build using the generated Makefile:
+```
+    $ make && sudo make install
+```
+**NOTE**: The `build/`` directory can have any name and be located anywhere
+ on your filesystem, and that the argument `..` given to cmake is simply
+ the source directory of **libwebsockets** containing the [CMakeLists.txt](../CMakeLists.txt)
+ project file. All examples in this file assumes you use ".."
+
+**NOTE2**:
+A common option you may want to give is to set the install path, same
+as --prefix= with autotools.  It defaults to /usr/local.
+You can do this by, eg
+```
+    $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .
+```
+
+**NOTE3**:
+On machines that want libraries in lib64, you can also add the
+following to the cmake line
+```
+    -DLIB_SUFFIX=64
+```
+
+**NOTE4**:
+If you are building against a non-distro OpenSSL (eg, in order to get
+access to ALPN support only in newer OpenSSL versions) the nice way to
+express that in one cmake command is eg,
+```
+    $ cmake .. -DOPENSSL_ROOT_DIR=/usr/local/ssl \
+         -DCMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE=/usr/local/ssl \
+         -DLWS_WITH_HTTP2=1
+```
+
+When you run the test apps using non-distro SSL, you have to force them
+to use your libs, not the distro ones
+```
+    $ LD_LIBRARY_PATH=/usr/local/ssl/lib libwebsockets-test-server --ssl
+```
+
+To get it to build on latest openssl (2016-04-10) it needed this approach
+```
+    cmake .. -DLWS_WITH_HTTP2=1 -DLWS_OPENSSL_INCLUDE_DIRS=/usr/local/include/openssl -DLWS_OPENSSL_LIBRARIES="/usr/local/lib64/libssl.so;/usr/local/lib64/libcrypto.so"
+```
+
+Mac users have reported
+
+```
+ $ export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2k; cmake ..; make -j4
+```
+
+worked for them when using "homebrew" OpenSSL
+
+**NOTE5**:
+To build with debug info and _DEBUG for lower priority debug messages
+compiled in, use
+```
+    $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
+```
+
+**NOTE6**
+To build on Solaris the linker needs to be informed to use lib socket
+and libnsl, and only builds in 64bit mode.
+
+```bash
+    $ cmake .. -DCMAKE_C_FLAGS=-m64 -DCMAKE_EXE_LINKER_FLAGS="-lsocket -lnsl"
+```
+
+**NOTE7**
+
+Build and test flow against boringssl.  Notice `LWS_WITH_GENHASH` is currently
+unavailable with boringssl due to their removing the necessary apis.
+
+Build current HEAD boringssl
+
+```
+ $ cd /projects
+ $ git clone https://boringssl.googlesource.com/boringssl
+ $ cd boringssl
+ $ mkdir build
+ $ cd build
+ $ cmake ..  -DBUILD_SHARED_LIBS=1
+ $ make -j8
+```
+
+Build and test lws against it
+
+```
+ $ cd /projects/libwebsockets/build
+ $ cmake .. -DOPENSSL_LIBRARIES="/projects/boringssl/build/ssl/libssl.so;\
+   /projects/boringssl/build/crypto/libcrypto.so" \
+   -DOPENSSL_INCLUDE_DIRS=/projects/boringssl/include \
+   -DLWS_WITH_BORINGSSL=1 -DCMAKE_BUILD_TYPE=DEBUG
+ $ make -j8 && sudo make install
+ $ LD_PRELOAD="/projects/boringssl/build/ssl/libssl.so \
+   /projects/boringssl/build/crypto/libcrypto.so" \
+   /usr/local/bin/libwebsockets-test-server -s
+```
+
+4. Finally you can build using the generated Makefile:
+
+```bash
+    $ make
+ ```
+
+@section lcap Linux Capabilities
+
+On Linux, lws now lets you retain selected root capabilities when dropping
+privileges.  If libcap-dev or similar package is installed providing
+sys/capabilities.h, and libcap or similar package is installed providing
+libcap.so, CMake will enable the capability features.
+
+The context creation info struct .caps[] and .count_caps members can then
+be set by user code to enable selected root capabilities to survive the
+transition to running under an unprivileged user.
+
+@section cmq Quirk of cmake
+
+When changing cmake options, for some reason the only way to get it to see the
+changes sometimes is delete the contents of your build directory and do the
+cmake from scratch.
+
+deleting build/CMakeCache.txt may be enough.
+
+
+@section cmw Building on Windows (Visual Studio)
+
+1. Install CMake 2.6 or greater: http://cmake.org/cmake/resources/software.html
+
+2. Install OpenSSL binaries. https://wiki.openssl.org/index.php/Binaries
+
+   (**NOTE**: Preferably in the default location to make it easier for CMake to find them)
+
+   **NOTE2**: 
+   Be sure that OPENSSL_CONF environment variable is defined and points at 
+   <OpenSSL install location>\bin\openssl.cfg
+
+3. Generate the Visual studio project by opening the Visual Studio cmd prompt:
+
+```
+    cd <path to src>
+    md build
+    cd build
+    cmake -G "Visual Studio 10" ..
+```
+
+   (**NOTE**: There is also a cmake-gui available on Windows if you prefer that)
+   
+   **NOTE2**:
+   See this link to find out the version number corresponding to your Visual Studio edition:
+   http://superuser.com/a/194065
+
+4. Now you should have a generated Visual Studio Solution in  your
+   `<path to src>/build` directory, which can be used to build.
+
+5. Some additional deps may be needed
+
+ - iphlpapi.lib
+ - psapi.lib
+ - userenv.lib
+
+6. If you're using libuv, you must make sure to compile libuv with the same multithread-dll / Mtd attributes as libwebsockets itself
+
+
+@section cmwmgw Building on Windows (MinGW)
+
+1. Install MinGW
+
+    For Fedora, it's, eg, `dnf install mingw64-gcc`
+
+2. Install current CMake package
+
+    For Fedora, it's `dnf install cmake`
+
+3. Instal mingw-built OpenSSL pieces
+
+    For Fedora, it's `mingw64-openssl.noarch mingw64-openssl-static.noarch`
+
+    mingw64-cmake as described below will auto-find the libs and includes
+    for build.  But to execute the apps, they either need to go into the same
+    `/usr/x86_64-w64-mingw32/sys-root/mingw/bin/` as the dlls are installed to,
+    or the dlls have to be copied into the same dir as your app executable.
+
+4. Generate the build files (default is Make files) using MSYS shell.
+
+   For Fedora, they provide a `mingw64-cmake` wrapper in the package
+   `mingw64-filesystem`, with this you can run that instead of cmake directly
+   and don't have to get involved with setting the cmake generator.
+
+   Otherwise doing it by hand is like this:
+
+```
+    $ cd /drive/path/to/src
+    $ mkdir build
+    $ cd build
+    $ cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW ..
+```
+
+   To generate build files allowing to create libwebsockets binaries with debug information
+   set the CMAKE_BUILD_TYPE flag to DEBUG:
+```
+    $ cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DCMAKE_BUILD_TYPE=DEBUG ..
+```
+5. Finally you can build using the generated Makefile and get the results deployed into your MinGW installation:
+
+```
+    $ make && make install
+```
+
+@section distro Selecting CMake options useful for distros
+
+Distro packagers should select the CMake option "LWS_WITH_DISTRO_RECOMMENDED",
+which selects common additional options like support for various event libraries,
+plugins and lwsws.
+
+@section ssllib Choosing Your TLS Poison
+
+ - If you are really restricted on memory, code size, or don't care about TLS
+   speed, mbedTLS is a good choice: `cmake .. -DLWS_WITH_MBEDTLS=1`
+ 
+ - If cpu and memory is not super restricted and you care about TLS speed,
+   OpenSSL or a directly compatible variant like Boring SSL is a good choice.
+ 
+Just building lws against stock Fedora OpenSSL or stock Fedora mbedTLS, for
+SSL handhake mbedTLS takes ~36ms and OpenSSL takes ~1ms on the same x86_64
+build machine here, with everything else the same.  Over the 144 connections of
+h2spec compliance testing for example, this ends up completing in 400ms for
+OpenSSL and 5.5sec for mbedTLS on x86_64.  In other words mbedTLS is very slow
+compared to OpenSSL under the (fairly typical) conditions I tested it.
+
+This isn't an inefficiency in the mbedtls interface implementation, it's just
+mbedTLS doing the crypto much slower than OpenSSL, which has accelerated
+versions of common crypto operations it automatically uses for platforms
+supporting it.  As of Oct 2017 mbedTLS itself has no such optimizations for any
+platform that I could find.  It's just pure C running on the CPU.
+
+Lws supports both almost the same, so instead of taking my word for it you are
+invited to try it both ways and see which the results (including, eg, binary
+size and memory usage as well as speed) suggest you use.
+
+NOTE: one major difference with mbedTLS is it does not load the system trust
+store by default.  That has advantages and disadvantages, but the disadvantage
+is you must provide the CA cert to lws built against mbedTLS for it to be able
+to validate it, ie, use -A with the test client.  The minimal test clients
+have the CA cert for warmcat.com and libwebsockets.org and use it if they see
+they were built with mbedTLS.
+
+@section optee Building for OP-TEE
+
+OP-TEE is a "Secure World" Trusted Execution Environment.
+
+Although lws is only part of the necessary picture to have an https-enabled
+TA, it does support OP-TEE as a platform and if you provide the other
+pieces, does work very well.
+
+Select it in cmake with `-DLWS_PLAT_OPTEE=1`
+
+
+@section cmco Setting compile options
+
+To set compile time flags you can either use one of the CMake gui applications
+or do it via the command line.
+
+@subsection cmcocl Command line
+
+To list available options (omit the H if you don't want the help text):
+
+    cmake -LH ..
+
+Then to set an option and build (for example turn off SSL support):
+
+    cmake -DLWS_WITH_SSL=0 ..
+or
+    cmake -DLWS_WITH_SSL:BOOL=OFF ..
+
+@subsection cmcoug Unix GUI
+
+If you have a curses-enabled build you simply type:
+(not all packages include this, my debian install does not for example).
+
+    ccmake
+
+@subsection cmcowg Windows GUI
+
+On windows CMake comes with a gui application:
+    Start -> Programs -> CMake -> CMake (cmake-gui)
+
+
+@section wolf wolfSSL/CyaSSL replacement for OpenSSL
+
+wolfSSL/CyaSSL is a lightweight SSL library targeted at embedded systems:
+https://www.wolfssl.com/wolfSSL/Products-wolfssl.html
+
+It contains a OpenSSL compatibility layer which makes it possible to pretty
+much link to it instead of OpenSSL, giving a much smaller footprint.
+
+**NOTE**: wolfssl needs to be compiled using the `--enable-opensslextra` flag for
+this to work.
+
+@section wolf1 Compiling libwebsockets with wolfSSL
+
+```
+    cmake .. -DLWS_WITH_WOLFSSL=1 \
+         -DLWS_WOLFSSL_INCLUDE_DIRS=/path/to/wolfssl \
+         -DLWS_WOLFSSL_LIBRARIES=/path/to/wolfssl/wolfssl.a ..
+```
+
+**NOTE**: On windows use the .lib file extension for `LWS_WOLFSSL_LIBRARIES` instead.
+
+@section cya Compiling libwebsockets with CyaSSL
+
+```
+    cmake .. -DLWS_WITH_CYASSL=1 \
+         -DLWS_CYASSL_INCLUDE_DIRS=/path/to/cyassl \
+         -DLWS_CYASSL_LIBRARIES=/path/to/wolfssl/cyassl.a ..
+```
+
+**NOTE**: On windows use the .lib file extension for `LWS_CYASSL_LIBRARIES` instead.
+
+@section gzip Selecting GZIP or MINIZ
+
+By default lws supports gzip when compression is needed.  But you can tell it to use
+MINIZ instead by using `-DLWS_WITH_MINIZ=1`.
+
+For native build cmake will try to find an existing libminiz.so or .a and build
+against that and the found includes automatically.
+
+For cross-build or building against local miniz, you need the following kind of
+cmake to tell it where to get miniz
+
+```
+cmake .. -DLWS_WITH_MINIZ=1 -DLWS_WITH_ZIP_FOPS=1 -DMINIZ_INCLUDE_DIRS="/projects/miniz;/projects/miniz/build" -DMINIZ_LIBRARIES=/projects/miniz/build/libminiz.so.2.1.0  
+```
+
+@section esp32 Building for ESP32
+
+Building for ESP32 requires the ESP-IDF framework. It can be built under Linux, OSX or Windows (MSYS2).
+
+1. Install ESP-IDF, follow the getting started guide here - http://esp-idf.readthedocs.io/en/latest/get-started/
+2. Set ESP-IDF to last known working version (assuming ESP-IDF is in `~/esp/esp-idf`) :
+```
+    cd ~/esp/esp-idf
+    git checkout 0c50b65a34cd6b3954f7435193411a88adb49cb0
+    git submodule update --recursive
+```
+3. Add `libwebsockets` as a submodule in the `components` folder of your ESP-IDF project:
+```
+    git submodule add https://github.com/warmcat/libwebsockets.git components/libwebsockets
+```
+4. If on Windows (MSYS2) you will need to install CMake in the MSYS2 environment:
+```
+    pacman -S mingw-w64-i686-cmake
+```
+If you're on Linux or OSX ensure CMake version is at least 3.7.
+
+@section extplugins Building plugins outside of lws itself
+
+The directory ./plugin-standalone/ shows how easy it is to create plugins
+outside of lws itself.  First build lws itself with -DLWS_WITH_PLUGINS,
+then use the same flow to build the standalone plugin
+```
+    cd ./plugin-standalone
+    mkdir build
+    cd build
+    cmake ..
+    make && sudo make install
+```
+
+if you changed the default plugin directory when you built lws, you must
+also give the same arguments to cmake here (eg,
+` -DCMAKE_INSTALL_PREFIX:PATH=/usr/something/else...` )
+
+Otherwise if you run lwsws or libwebsockets-test-server-v2.0, it will now
+find the additional plugin "libprotocol_example_standalone.so"
+```
+    lwsts[21257]:   Plugins:
+    lwsts[21257]:    libprotocol_dumb_increment.so
+    lwsts[21257]:    libprotocol_example_standalone.so
+    lwsts[21257]:    libprotocol_lws_mirror.so
+    lwsts[21257]:    libprotocol_lws_server_status.so
+    lwsts[21257]:    libprotocol_lws_status.so
+```
+If you have multiple vhosts, you must enable plugins at the vhost
+additionally, discovered plugins are not enabled automatically for security
+reasons.  You do this using info->pvo or for lwsws, in the JSON config.
+
+
+@section http2rp Reproducing HTTP/2 tests
+
+Enable `-DLWS_WITH_HTTP2=1` in cmake to build with http/2 support enabled.
+
+You must have built and be running lws against a version of openssl that has
+ALPN.  At the time of writing, recent distros have started upgrading to OpenSSL
+1.1+ that supports this already.  You'll know it's right by seeing
+
+```
+    lwsts[4752]:  Compiled with OpenSSL support
+    lwsts[4752]:  Using SSL mode
+    lwsts[4752]:  HTTP2 / ALPN enabled
+```
+at lws startup.
+
+Recent Firefox and Chrome also support HTTP/2 by ALPN, so these should just work
+with the test server running in -s / ssl mode.
+
+For testing with nghttp client:
+
+```
+    $ nghttp -nvas https://localhost:7681/test.html
+```
+
+Testing with h2spec (https://github.com/summerwind/h2spec)
+
+```
+        $ h2spec  -h 127.0.0.1 -p 7681 -t -k -v -o 1
+```
+
+```
+145 tests, 145 passed, 0 skipped, 0 failed
+
+```
+
+@section coverage Automated Coverage Testing
+
+./test-apps/attack.sh contains scripted tests that are the basis
+of the automated test coverage assessment available for gcc and clang.
+
+To reproduce
+
+ $ cd build
+ $ cmake .. -DLWS_WITH_GCOV=1 -DCMAKE_BUILD_TYPE=DEBUG
+ $ ../scripts/build-gcov.sh
+ $ ../test-apps/attack.sh
+ $ ../scripts/gcov.sh
+...
+Lines executed:51.24% of 8279
+
+@section windowsprebuilt Using Windows binary builds on Appveyor
+
+The CI builds on Appveyor now produce usable binary outputs.  Visit
+
+[lws on Appveyor](https://ci.appveyor.com/project/lws-team/libwebsockets)
+
+and select one of the builds, then click on ARTIFACTS at the top right.  The zip file
+want to be unpacked into `C:\Program Files (x86)/libwebsockets`, after that, you should be able to run the test server, by running it from `bin/Release/libwebsockets-test-server.exe` and opening a browser on http://127.0.0.1:7681
+
+@section cross Cross compiling
+
+To enable cross-compiling **libwebsockets** using CMake you need to create
+a "Toolchain file" that you supply to CMake when generating your build files.
+CMake will then use the cross compilers and build paths specified in this file
+to look for dependencies and such.
+
+**Libwebsockets** includes an example toolchain file [cross-arm-linux-gnueabihf.cmake](../contrib/cross-arm-linux-gnueabihf.cmake)
+you can use as a starting point.
+
+The commandline to configure for cross with this would look like
+```
+    $ cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr/lib/my-cross-root \
+         -DCMAKE_TOOLCHAIN_FILE=../contrib/cross-arm-linux-gnueabihf.cmake \
+         -DLWS_WITHOUT_EXTENSIONS=1 -DLWS_WITH_SSL=0 \
+         -DLWS_WITH_ZIP_FOPS=0 -DLWS_WITH_ZLIB=0
+```
+The example shows how to build with no external cross lib dependencies, you
+need to provide the cross libraries otherwise.
+
+**NOTE**: start from an EMPTY build directory if you had a non-cross build in there
+    before the settings will be cached and your changes ignored.
+    Delete `build/CMakeCache.txt` at least before trying a new cmake config
+    to ensure you are really building the options you think you are.
+
+Additional information on cross compilation with CMake:
+    http://www.vtk.org/Wiki/CMake_Cross_Compiling
+
+@section cross_example Complex Cross compiling example
+
+Here are step by step instructions for cross-building the external projects needed for lws with lwsws + mbedtls as an example.
+
+In the example, my toolchain lives in `/projects/aist-tb/arm-tc` and is named `arm-linux-gnueabihf`.  So you will need to adapt those to where your toolchain lives and its name where you see them here.
+
+Likewise I do all this in /tmp but it has no special meaning, you can adapt that to somewhere else.
+
+All "foreign" cross-built binaries are sent into `/tmp/cross` so they cannot be confused for 'native' x86_64 stuff on your host machine in /usr/[local/]....
+
+## Prepare the cmake toolchain file
+
+1) `cd /tmp`
+
+2) `wget -O mytoolchainfile https://raw.githubusercontent.com/warmcat/libwebsockets/master/contrib/cross-arm-linux-gnueabihf.cmake` 
+
+3) Edit `/tmp/mytoolchainfile` adapting `CROSS_PATH`, `CMAKE_C_COMPILER` and `CMAKE_CXX_COMPILER` to reflect your toolchain install dir and path to your toolchain C and C++ compilers respectively.  For my case:
+
+```
+set(CROSS_PATH /projects/aist-tb/arm-tc/)
+set(CMAKE_C_COMPILER "${CROSS_PATH}/bin/arm-linux-gnueabihf-gcc")
+set(CMAKE_CXX_COMPILER "${CROSS_PATH}/bin/arm-linux-gnueabihf-g++")
+```
+
+## 1/4: Building libuv cross:
+
+1) `export PATH=/projects/aist-tb/arm-tc/bin:$PATH`  Notice there is a **/bin** on the end of the toolchain path
+
+2) `cd /tmp ; mkdir cross` we will put the cross-built libs in /tmp/cross
+
+3) `git clone https://github.com/libuv/libuv.git` get libuv
+
+4) `cd libuv`
+
+5) `./autogen.sh`
+
+```
++ libtoolize --copy
+libtoolize: putting auxiliary files in '.'.
+libtoolize: copying file './ltmain.sh'
+libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
+libtoolize: copying file 'm4/libtool.m4'
+libtoolize: copying file 'm4/ltoptions.m4'
+libtoolize: copying file 'm4/ltsugar.m4'
+libtoolize: copying file 'm4/ltversion.m4'
+libtoolize: copying file 'm4/lt~obsolete.m4'
++ aclocal -I m4
++ autoconf
++ automake --add-missing --copy
+configure.ac:38: installing './ar-lib'
+configure.ac:25: installing './compile'
+configure.ac:22: installing './config.guess'
+configure.ac:22: installing './config.sub'
+configure.ac:21: installing './install-sh'
+configure.ac:21: installing './missing'
+Makefile.am: installing './depcomp'
+```
+If it has problems, you will need to install `automake`, `libtool` etc.
+
+6) `./configure  --host=arm-linux-gnueabihf --prefix=/tmp/cross`
+
+7) `make && make install` this will install to `/tmp/cross/...`
+
+8) `file /tmp/cross/lib/libuv.so.1.0.0`  Check it's really built for ARM
+```
+/tmp/cross/lib/libuv.so.1.0.0: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=cdde0bc945e51db6001a9485349c035baaec2b46, with debug_info, not stripped
+```
+
+## 2/4: Building zlib cross
+
+1) `cd /tmp`
+
+2) `git clone https://github.com/madler/zlib.git`
+
+3) `CC=arm-linux-gnueabihf-gcc ./configure --prefix=/tmp/cross`
+```
+Checking for shared library support...
+Building shared library libz.so.1.2.11 with arm-linux-gnueabihf-gcc.
+Checking for size_t... Yes.
+Checking for off64_t... Yes.
+Checking for fseeko... Yes.
+Checking for strerror... Yes.
+Checking for unistd.h... Yes.
+Checking for stdarg.h... Yes.
+Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf().
+Checking for vsnprintf() in stdio.h... Yes.
+Checking for return value of vsnprintf()... Yes.
+Checking for attribute(visibility) support... Yes.
+```
+
+4)  `make && make install`
+```
+arm-linux-gnueabihf-gcc -O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
+...
+rm -f /tmp/cross/include/zlib.h /tmp/cross/include/zconf.h
+cp zlib.h zconf.h /tmp/cross/include
+chmod 644 /tmp/cross/include/zlib.h /tmp/cross/include/zconf.h
+```
+
+5) `file /tmp/cross/lib/libz.so.1.2.11`  This is just to confirm we built an ARM lib as expected
+```
+/tmp/cross/lib/libz.so.1.2.11: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=6f8ffef84389b1417d2fd1da1bd0c90f748f300d, with debug_info, not stripped
+```
+
+## 3/4: Building mbedtls cross
+
+1) `cd /tmp`
+
+2) `git clone https://github.com/ARMmbed/mbedtls.git`
+
+3) `cd mbedtls ; mkdir build ; cd build`
+
+3) `cmake .. -DCMAKE_TOOLCHAIN_FILE=/tmp/mytoolchainfile -DCMAKE_INSTALL_PREFIX:PATH=/tmp/cross -DCMAKE_BUILD_TYPE=RELEASE -DUSE_SHARED_MBEDTLS_LIBRARY=1`  mbedtls also uses cmake, so you can simply reuse the toolchain file you used for libwebsockets.  That is why you shouldn't put project-specific options in the toolchain file, it should just describe the toolchain.
+
+4) `make && make install`
+
+5) `file /tmp/cross/lib/libmbedcrypto.so.2.6.0`
+```
+/tmp/cross/lib/libmbedcrypto.so.2.6.0: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=bcca195e78bd4fd2fb37f36ab7d72d477d609d87, with debug_info, not stripped
+```
+
+## 4/4: Building libwebsockets with everything
+
+1) `cd /tmp`
+
+2) `git clone ssh://[email protected]/warmcat/libwebsockets`
+
+3) `cd libwebsockets ; mkdir build ; cd build`
+
+4)  (this is all one line on the commandline)
+```
+cmake .. -DCMAKE_TOOLCHAIN_FILE=/tmp/mytoolchainfile \
+-DCMAKE_INSTALL_PREFIX:PATH=/tmp/cross \
+-DLWS_WITH_LWSWS=1 \
+-DLWS_WITH_MBEDTLS=1 \
+-DLWS_MBEDTLS_LIBRARIES="/tmp/cross/lib/libmbedcrypto.so;/tmp/cross/lib/libmbedtls.so;/tmp/cross/lib/libmbedx509.so" \
+-DLWS_MBEDTLS_INCLUDE_DIRS=/tmp/cross/include \
+-DLWS_LIBUV_LIBRARIES=/tmp/cross/lib/libuv.so \
+-DLWS_LIBUV_INCLUDE_DIRS=/tmp/cross/include \
+-DLWS_ZLIB_LIBRARIES=/tmp/cross/lib/libz.so \
+-DLWS_ZLIB_INCLUDE_DIRS=/tmp/cross/include
+```
+
+3) `make && make install`
+
+4) `file /tmp/cross/lib/libwebsockets.so.11`
+```
+/tmp/cross/lib/libwebsockets.so.11: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=81e59c6534f8e9629a9fc9065c6e955ce96ca690, with debug_info, not stripped
+```
+
+5) `arm-linux-gnueabihf-objdump -p /tmp/cross/lib/libwebsockets.so.11 | grep NEEDED`  Confirm that the lws library was linked against everything we expect (libm / libc are provided by your toolchain)
+```
+  NEEDED               libz.so.1
+  NEEDED               libmbedcrypto.so.0
+  NEEDED               libmbedtls.so.10
+  NEEDED               libmbedx509.so.0
+  NEEDED               libuv.so.1
+  NEEDED               libm.so.6
+  NEEDED               libc.so.6
+```
+
+You will also find the lws test apps in `/tmp/cross/bin`... to run lws on the target you will need to copy the related things from /tmp/cross... all the .so from /tmp/cross/lib and anything from /tmp/cross/bin you want.
+
+@section mem Memory efficiency
+
+Embedded server-only configuration without extensions (ie, no compression
+on websocket connections), but with full v13 websocket features and http
+server, built on ARM Cortex-A9:
+
+Update at 8dac94d (2013-02-18)
+```
+    $ ./configure --without-client --without-extensions --disable-debug --without-daemonize
+
+    Context Creation, 1024 fd limit[2]:   16720 (includes 12 bytes per fd)
+    Per-connection [3]:                      72 bytes, +1328 during headers
+
+    .text	.rodata	.data	.bss
+    11512	2784	288	4
+```
+This shows the impact of the major configuration with/without options at
+13ba5bbc633ea962d46d using Ubuntu ARM on a PandaBoard ES.
+
+These are accounting for static allocations from the library elf, there are
+additional dynamic allocations via malloc.  These are a bit old now but give
+the right idea for relative "expense" of features.
+
+Static allocations, ARM9
+
+|                                | .text   | .rodata | .data | .bss |
+|--------------------------------|---------|---------|-------|------|
+| All (no without)               | 35024   | 9940    | 336   | 4104 |
+| without client                 | 25684   | 7144    | 336   | 4104 |
+| without client, exts           | 21652   | 6288    | 288   | 4104 |
+| without client, exts, debug[1] | 19756   | 3768    | 288   | 4104 |
+| without server                 | 30304   | 8160    | 336   | 4104 |
+| without server, exts           | 25382   | 7204    | 288   | 4104 |
+| without server, exts, debug[1] | 23712   | 4256    | 288   | 4104 |
+
+[1] `--disable-debug` only removes messages below `lwsl_notice`.  Since that is
+the default logging level the impact is not noticeable, error, warn and notice
+logs are all still there.
+
+[2] `1024` fd per process is the default limit (set by ulimit) in at least Fedora
+and Ubuntu.  You can make significant savings tailoring this to actual expected
+peak fds, ie, at a limit of `20`, context creation allocation reduces to `4432 +
+240 = 4672`)
+
+[3] known header content is freed after connection establishment

+ 88 - 0
Source/ThirdParty/libwebsockets/READMEs/README.captive-portal-detection.md

@@ -0,0 +1,88 @@
+# Captive Portal Detection
+
+## Background
+
+Wifi devices may face some interception of their connection to the
+internet, it's very common for, eg, coffee shop wifi to present some
+kind of login or other clickthrough before access to the Internet is
+granted.  Devices may need to understand that they are in this
+situation, and there are several different techniques for trying to
+gague it.
+
+Sequence-wise the device has been granted a DHCP lease and has been
+configured with DNS, but the DNS may be wrongly resolving everything
+to an address on the LAN or a portal on the net.
+
+Whether there is a captive portal active should be a sticky state for a given
+connection if there is not going to be any attempt to login or pass the landing
+page, it only needs checking for after DHCP acquisition then.  If there will be
+an attempt to satisfy the landing page, the test should be repeated after the
+attempt.
+
+## Detection schemes
+
+The most popular detection scheme by numbers is Android's method,
+which is to make an HTTP client GET to `http://connectivitycheck.android.com/generate_204`
+and see if a 204 is coming back... if intercepted, typically there'll be a
+3xx redirect to the portal, perhaps on https.  Or, it may reply on http with
+a 200 and show the portal directly... either way it won't deliver a 204
+like the real remote server does.
+
+Variations include expecting a 200 but with specific http body content, and
+doing a DNS lookup for a static IP that the device knows; if it's resolved to
+something else, it knows there's monkey business implying a captive portal.
+
+Other schemes involve https connections going out and detecting that the cert
+of the server it's actually talking to doesn't check out, although this is
+potentially ambiguous.
+
+Yet more methods are possible outside of tcp or http.
+
+## lws captive portal detect support
+
+lws provides a generic api to start captive portal detection...
+
+```
+LWS_EXTERN LWS_VISIBLE int
+lws_system_cpd_start(struct lws_context *context);
+```
+
+and two states in `lws_system` states to trigger it from, either
+`LWS_SYSTATE_CPD_PRE_TIME` which happens after DHCP acquisition but before
+ntpclient and is suitable for non https-based scheme where the time doesn't
+need to be known, or the alternative `LWS_SYSTATE_CPD_POST_TIME` state which
+happens after ntpclient has completed and we know the time.
+
+The actual platform implementation is set using `lws_system_ops_t` function
+pointer `captive_portal_detect_request`, ie
+
+```
+	int (*captive_portal_detect_request)(struct lws_context *context);
+	/**< Check if we can go out on the internet cleanly, or if we are being
+	 * redirected or intercepted by a captive portal.
+	 * Start the check that proceeds asynchronously, and report the results
+	 * by calling lws_captive_portal_detect_result() api
+	 */
+```
+
+User platform code can provide this to implement whatever scheme they want, when
+it has arrived at a result, it can call the lws api `lws_system_cpd_result()` to
+inform lws.  If there isn't any captive portal, this will also try to advance the
+system state towards OPERATIONAL.
+
+```
+/**
+ * lws_system_cpd_result() - report the result of the captive portal detection
+ *
+ * \param context: the lws_context
+ * \param result: one of the LWS_CPD_ constants representing captive portal state
+ * \param redirect_url: NULL, or the url we were redirected to if result is
+ *     LWS_CPD_HTTP_REDIRECT
+ *
+ * Sets the context's captive portal detection state to result.  User captive
+ * portal detection code would call this once it had a result from its test.
+ */
+LWS_EXTERN LWS_VISIBLE int
+lws_system_cpd_result(struct lws_context *context, int result, const char *redirect_url);
+```
+

+ 29 - 0
Source/ThirdParty/libwebsockets/READMEs/README.ci.md

@@ -0,0 +1,29 @@
+## Need for CI
+
+Generally if we're adding something that's supposed to work ongoing, the stuff
+should be exercised in CI (at least Travis).
+
+If there are few users for a particular feature, experience has shown that
+refactors or other upheaval can easily break it into a state of uselessness
+without anyone noticing until later.
+
+Therefore here's a description of how to add something to the CI tests... this
+is certainly a nonproductive PITA and I have never been thanked for the work
+involved.  But if the promise of the various features working is going to
+remain alive, it's necessary to include CI test where possible with new
+nontrivial code.
+
+## Integration points
+
+### cmake
+
+`.travis.yml` maps the various test activities to CMake options needed.
+
+### including dependent packages into travis
+
+See `./scripts/travis_install.sh`
+
+### performing prepared test actions
+
+See `./scripts/travis_control.sh`
+

+ 41 - 0
Source/ThirdParty/libwebsockets/READMEs/README.cmake.md

@@ -0,0 +1,41 @@
+# Tips about CMake
+
+## Don't be afraid to nuke your build dir
+
+CMake likes to cache options and other things in the build dir... if you stop
+asserting the state of something like `-DMY_OPTION=1`, then the last way it was
+set it cached.  On order to keep track of what you have set and not set, it's
+very advisable to explicitly keep all your options and set them all on one cmake
+line.
+
+Then, when you meet a situation you changed something but somehow cmake is
+sticking with what it knew before, you can fearlessly delete your build dir
+and create a new one with your explicit config.
+
+On Linux, it's usually enough to delete `CMakeCache.txt` to trigger it to config
+from the start again, but on, eg, windows, it isn't, for whatever reason it
+literally needs the build dir removing.
+
+## CMake presence tests that fail
+
+Lws makes use of various CMake features to figure out what apis your libraries
+offer, eg, OpenSSL has many different apis based on version, lws knows how to
+work around most of the changes, but to do it it must find out what apis are
+available first on your build environment.
+
+CMake basically builds little throwaway test programs using each api in turn, and
+if it builds, it understands that the api was available and sets a preprocessor
+symbol that's available in the main build accordingly.  Then we can do `#if xxx`
+to figure out if we can use `xxx` or need to do a workaround at build-time.
+
+This works very well, but unfortunately if the program didn't build, there are
+many possible ways for the build to break even if the api being tested is
+really available... for example, some library in your toolchain isn't being
+linked for the throwaway test program.
+
+When this happens, cmake indicates that apis that must be available are not available...
+CMake keeps a log of what happened with the failed test programs in
+`./build/CMakeFiles/CMakeError.log`.  This is appeneded to, so the best way is blow
+away the build dir and reconfig a new one from scratch, and go look in there to
+find out what the compiler or linker was complaining about.
+

+ 1373 - 0
Source/ThirdParty/libwebsockets/READMEs/README.coding.md

@@ -0,0 +1,1373 @@
+Notes about coding with lws
+===========================
+
+@section era Old lws and lws v2.0+
+
+Originally lws only supported the "manual" method of handling everything in the
+user callback found in test-server.c / test-server-http.c.
+
+Since v2.0, the need for most or all of this manual boilerplate has been
+eliminated: the protocols[0] http stuff is provided by a generic lib export
+`lws_callback_http_dummy()`.  You can serve parts of your filesystem at part of
+the URL space using mounts, the dummy http callback will do the right thing.
+
+It's much preferred to use the "automated" v2.0 type scheme, because it's less
+code and it's easier to support.
+
+The minimal examples all use the modern, recommended way.
+
+If you just need generic serving capability, without the need to integrate lws
+to some other app, consider not writing any server code at all, and instead use
+the generic server `lwsws`, and writing your special user code in a standalone
+"plugin".  The server is configured for mounts etc using JSON, see
+./READMEs/README.lwsws.md.
+
+Although the "plugins" are dynamically loaded if you use lwsws or lws built
+with libuv, actually they may perfectly well be statically included if that
+suits your situation better, eg, ESP32 test server, where the platform does
+not support processes or dynamic loading, just #includes the plugins
+one after the other and gets the same benefit from the same code.
+
+Isolating and collating the protocol code in one place also makes it very easy
+to maintain and understand.
+
+So it if highly recommended you put your protocol-specific code into the
+form of a "plugin" at the source level, even if you have no immediate plan to
+use it dynamically-loaded.
+
+@section writeable Only send data when socket writeable
+
+You should only send data on a websocket connection from the user callback
+`LWS_CALLBACK_SERVER_WRITEABLE` (or `LWS_CALLBACK_CLIENT_WRITEABLE` for
+clients).
+
+If you want to send something, do NOT just send it but request a callback
+when the socket is writeable using
+
+ - `lws_callback_on_writable(wsi)` for a specific `wsi`, or
+ 
+ - `lws_callback_on_writable_all_protocol(protocol)` for all connections
+using that protocol to get a callback when next writeable.
+
+Usually you will get called back immediately next time around the service
+loop, but if your peer is slow or temporarily inactive the callback will be
+delayed accordingly.  Generating what to write and sending it should be done
+in the ...WRITEABLE callback.
+
+See the test server code for an example of how to do this.
+
+Otherwise evolved libs like libuv get this wrong, they will allow you to "send"
+anything you want but it only uses up your local memory (and costs you
+memcpys) until the socket can actually accept it.  It is much better to regulate
+your send action by the downstream peer readiness to take new data in the first
+place, avoiding all the wasted buffering.
+
+Libwebsockets' concept is that the downstream peer is truly the boss, if he,
+or our connection to him, cannot handle anything new, we should not generate
+anything new for him.  This is how unix shell piping works, you may have
+`cat a.txt | grep xyz > remote", but actually that does not cat anything from
+a.txt while remote cannot accept anything new. 
+
+@section oneper Only one lws_write per WRITEABLE callback
+
+From v2.5, lws strictly enforces only one lws_write() per WRITEABLE callback.
+
+You will receive a message about "Illegal back-to-back write of ... detected"
+if there is a second lws_write() before returning to the event loop.
+
+This is because with http/2, the state of the network connection carrying a
+wsi is unrelated to any state of the wsi.  The situation on http/1 where a
+new request implied a new tcp connection and new SSL buffer, so you could
+assume some window for writes is no longer true.  Any lws_write() can fail
+and be buffered for completion by lws; it will be auto-completed by the
+event loop.
+
+Note that if you are handling your own http responses, writing the headers
+needs to be done with a separate lws_write() from writing any payload.  That
+means after writing the headers you must call `lws_callback_on_writable(wsi)`
+and send any payload from the writable callback.
+
+@section otherwr Do not rely on only your own WRITEABLE requests appearing
+
+Libwebsockets may generate additional `LWS_CALLBACK_CLIENT_WRITEABLE` events
+if it met network conditions where it had to buffer your send data internally.
+
+So your code for `LWS_CALLBACK_CLIENT_WRITEABLE` needs to own the decision
+about what to send, it can't assume that just because the writeable callback
+came something is ready to send.
+
+It's quite possible you get an 'extra' writeable callback at any time and
+just need to `return 0` and wait for the expected callback later.
+
+@section dae Daemonization
+
+There's a helper api `lws_daemonize` built by default that does everything you
+need to daemonize well, including creating a lock file.  If you're making
+what's basically a daemon, just call this early in your init to fork to a
+headless background process and exit the starting process.
+
+Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your
+daemon is headless, so you'll need to sort out alternative logging, by, eg,
+syslog via `lws_set_log_level(..., lwsl_emit_syslog)`.
+
+@section conns Maximum number of connections
+
+The maximum number of connections the library can deal with is decided when
+it starts by querying the OS to find out how many file descriptors it is
+allowed to open (1024 on Fedora for example).  It then allocates arrays that
+allow up to that many connections, minus whatever other file descriptors are
+in use by the user code.
+
+If you want to restrict that allocation, or increase it, you can use ulimit or
+similar to change the available number of file descriptors, and when restarted
+**libwebsockets** will adapt accordingly.
+
+@section peer_limits optional LWS_WITH_PEER_LIMITS
+
+If you select `LWS_WITH_PEER_LIMITS` at cmake, then lws will track peer IPs
+and monitor how many connections and ah resources they are trying to use
+at one time.  You can choose to limit these at context creation time, using
+`info.ip_limit_ah` and `info.ip_limit_wsi`.
+
+Note that although the ah limit is 'soft', ie, the connection will just wait
+until the IP is under the ah limit again before attaching a new ah, the
+wsi limit is 'hard', lws will drop any additional connections from the
+IP until it's under the limit again.
+
+If you use these limits, you should consider multiple clients may simultaneously
+try to access the site through NAT, etc.  So the limits should err on the side
+of being generous, while still making it impossible for one IP to exhaust
+all the server resources.
+
+@section evtloop Libwebsockets is singlethreaded
+
+Libwebsockets works in a serialized event loop, in a single thread.  It supports
+the default poll() backend, and libuv, libev, and libevent event loop
+libraries that also take this locking-free, nonblocking event loop approach that
+is not threadsafe.  There are several advantages to this technique, but one
+disadvantage, it doesn't integrate easily if there are multiple threads that
+want to use libwebsockets.
+
+However integration to multithreaded apps is possible if you follow some guidelines.
+
+1) Aside from two APIs, directly calling lws apis from other threads is not allowed.
+
+2) If you want to keep a list of live wsi, you need to use lifecycle callbacks on
+the protocol in the service thread to manage the list, with your own locking.
+Typically you use an ESTABLISHED callback to add ws wsi to your list and a CLOSED
+callback to remove them.
+
+3) LWS regulates your write activity by being able to let you know when you may
+write more on a connection.  That reflects the reality that you cannot succeed to
+send data to a peer that has no room for it, so you should not generate or buffer
+write data until you know the peer connection can take more.
+
+Other libraries pretend that the guy doing the writing is the boss who decides
+what happens, and absorb as much as you want to write to local buffering.  That does
+not scale to a lot of connections, because it will exhaust your memory and waste
+time copying data around in memory needlessly.
+
+The truth is the receiver, along with the network between you, is the boss who
+decides what will happen.  If he stops accepting data, no data will move.  LWS is
+designed to reflect that.
+
+If you have something to send, you call `lws_callback_on_writable()` on the
+connection, and when it is writeable, you will get a `LWS_CALLBACK_SERVER_WRITEABLE`
+callback, where you should generate the data to send and send it with `lws_write()`.
+
+You cannot send data using `lws_write()` outside of the WRITEABLE callback.
+
+4) For multithreaded apps, this corresponds to a need to be able to provoke the
+`lws_callback_on_writable()` action and to wake the service thread from its event
+loop wait (sleeping in `poll()` or `epoll()` or whatever).  The rules above
+mean directly sending data on the connection from another thread is out of the
+question.
+
+Therefore the two apis mentioned above that may be used from another thread are
+
+ - For LWS using the default poll() event loop, `lws_callback_on_writable()`
+
+ - For LWS using libuv/libev/libevent event loop, `lws_cancel_service()`
+
+If you are using the default poll() event loop, one "foreign thread" at a time may
+call `lws_callback_on_writable()` directly for a wsi.  You need to use your own
+locking around that to serialize multiple thread access to it.
+
+If you implement LWS_CALLBACK_GET_THREAD_ID in protocols[0], then LWS will detect
+when it has been called from a foreign thread and automatically use
+`lws_cancel_service()` to additionally wake the service loop from its wait.
+
+For libuv/libev/libevent event loop, they cannot handle being called from other
+threads.  So there is a slightly different scheme, you may call `lws_cancel_service()` 
+to force the event loop to end immediately.  This then broadcasts a callback (in the
+service thread context) `LWS_CALLBACK_EVENT_WAIT_CANCELLED`, to all protocols on all
+vhosts, where you can perform your own locking and walk a list of wsi that need
+`lws_callback_on_writable()` calling on them.
+
+`lws_cancel_service()` is very cheap to call.
+
+5) The obverse of this truism about the receiver being the boss is the case where
+we are receiving.  If we get into a situation we actually can't usefully
+receive any more, perhaps because we are passing the data on and the guy we want
+to send to can't receive any more, then we should "turn off RX" by using the
+RX flow control API, `lws_rx_flow_control(wsi, 0)`.  When something happens where we
+can accept more RX, (eg, we learn our onward connection is writeable) we can call
+it again to re-enable it on the incoming wsi.
+
+LWS stops calling back about RX immediately you use flow control to disable RX, it
+buffers the data internally if necessary.  So you will only see RX when you can
+handle it.  When flow control is disabled, LWS stops taking new data in... this makes
+the situation known to the sender by TCP "backpressure", the tx window fills and the
+sender finds he cannot write any more to the connection.
+
+See the mirror protocol implementations for example code.
+
+If you need to service other socket or file descriptors as well as the
+websocket ones, you can combine them together with the websocket ones
+in one poll loop, see "External Polling Loop support" below, and
+still do it all in one thread / process context.  If the need is less
+architectural, you can also create RAW mode client and serving sockets; this
+is how the lws plugin for the ssh server works.
+
+@section anonprot Working without a protocol name
+
+Websockets allows connections to negotiate without a protocol name...
+in that case by default it will bind to the first protocol in your
+vhost protocols[] array.
+
+You can tell the vhost to use a different protocol by attaching a
+pvo (per-vhost option) to the 
+
+```
+/*
+ * this sets a per-vhost, per-protocol option name:value pair
+ * the effect is to set this protocol to be the default one for the vhost,
+ * ie, selected if no Protocol: header is sent with the ws upgrade.
+ */
+
+static const struct lws_protocol_vhost_options pvo_opt = {
+	NULL,
+	NULL,
+	"default",
+	"1"
+};
+
+static const struct lws_protocol_vhost_options pvo = {
+	NULL,
+	&pvo_opt,
+	"my-protocol",
+	""
+};
+
+...
+
+	context_info.pvo = &pvo;
+...
+
+```
+
+Will select "my-protocol" from your protocol list (even if it came
+in by plugin) as being the target of client connections that don't
+specify a protocol.
+
+@section closing Closing connections from the user side
+
+When you want to close a connection, you do it by returning `-1` from a
+callback for that connection.
+
+You can provoke a callback by calling `lws_callback_on_writable` on
+the wsi, then notice in the callback you want to close it and just return -1.
+But usually, the decision to close is made in a callback already and returning
+-1 is simple.
+
+If the socket knows the connection is dead, because the peer closed or there
+was an affirmitive network error like a FIN coming, then **libwebsockets**  will
+take care of closing the connection automatically.
+
+If you have a silently dead connection, it's possible to enter a state where
+the send pipe on the connection is choked but no ack will ever come, so the
+dead connection will never become writeable.  To cover that, you can use TCP
+keepalives (see later in this document) or pings.
+
+@section gzip Serving from inside a zip file
+
+Lws now supports serving gzipped files from inside a zip container.  Thanks to
+Per Bothner for contributing the code.
+
+This has the advtantage that if the client can accept GZIP encoding, lws can
+simply send the gzip-compressed file from inside the zip file with no further
+processing, saving time and bandwidth.
+
+In the case the client can't understand gzip compression, lws automatically
+decompressed the file and sends it normally.
+
+Clients with limited storage and RAM will find this useful; the memory needed
+for the inflate case is constrained so that only one input buffer at a time
+is ever in memory.
+
+To use this feature, ensure LWS_WITH_ZIP_FOPS is enabled at CMake.
+
+`libwebsockets-test-server-v2.0` includes a mount using this technology
+already, run that test server and navigate to http://localhost:7681/ziptest/candide.html
+
+This will serve the book Candide in html, together with two jpgs, all from
+inside a .zip file in /usr/[local/]share-libwebsockets-test-server/candide.zip
+
+Usage is otherwise automatic, if you arrange a mount that points to the zipfile,
+eg, "/ziptest" -> "mypath/test.zip", then URLs like `/ziptest/index.html` will be
+servied from `index.html` inside `mypath/test.zip`
+
+@section frags Fragmented messages
+
+To support fragmented messages you need to check for the final
+frame of a message with `lws_is_final_fragment`. This
+check can be combined with `libwebsockets_remaining_packet_payload`
+to gather the whole contents of a message, eg:
+
+```
+	    case LWS_CALLBACK_RECEIVE:
+	    {
+	        Client * const client = (Client *)user;
+	        const size_t remaining = lws_remaining_packet_payload(wsi);
+	
+	        if (!remaining && lws_is_final_fragment(wsi)) {
+	            if (client->HasFragments()) {
+	                client->AppendMessageFragment(in, len, 0);
+	                in = (void *)client->GetMessage();
+	                len = client->GetMessageLength();
+	            }
+	
+	            client->ProcessMessage((char *)in, len, wsi);
+	            client->ResetMessage();
+	        } else
+	            client->AppendMessageFragment(in, len, remaining);
+	    }
+	    break;
+```
+
+The test app libwebsockets-test-fraggle sources also show how to
+deal with fragmented messages.
+
+
+@section debuglog Debug Logging
+
+Also using `lws_set_log_level` api you may provide a custom callback to actually
+emit the log string.  By default, this points to an internal emit function
+that sends to stderr.  Setting it to `NULL` leaves it as it is instead.
+
+A helper function `lwsl_emit_syslog()` is exported from the library to simplify
+logging to syslog.  You still need to use `setlogmask`, `openlog` and `closelog`
+in your user code.
+
+The logging apis are made available for user code.
+
+- `lwsl_err(...)`
+- `lwsl_warn(...)`
+- `lwsl_notice(...)`
+- `lwsl_info(...)`
+- `lwsl_debug(...)`
+
+The difference between notice and info is that notice will be logged by default
+whereas info is ignored by default.
+
+If you are not building with _DEBUG defined, ie, without this
+
+```
+	$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
+```
+
+then log levels below notice do not actually get compiled in.
+
+@section asan Building with ASAN
+
+Under GCC you can select for the build to be instrumented with the Address
+Sanitizer, using `cmake .. -DCMAKE_BUILD_TYPE=DEBUG -DLWS_WITH_ASAN=1`.  LWS is routinely run during development with valgrind, but ASAN is capable of finding different issues at runtime, like operations which are not strictly defined in the C
+standard and depend on platform behaviours.
+
+Run your application like this
+
+```
+	$ sudo ASAN_OPTIONS=verbosity=2:halt_on_error=1  /usr/local/bin/lwsws
+```
+
+and attach gdb to catch the place it halts.
+
+@section extpoll External Polling Loop support
+
+**libwebsockets** maintains an internal `poll()` array for all of its
+sockets, but you can instead integrate the sockets into an
+external polling array.  That's needed if **libwebsockets** will
+cooperate with an existing poll array maintained by another
+server.
+
+Three callbacks `LWS_CALLBACK_ADD_POLL_FD`, `LWS_CALLBACK_DEL_POLL_FD`
+and `LWS_CALLBACK_CHANGE_MODE_POLL_FD` appear in the callback for protocol 0
+and allow interface code to manage socket descriptors in other poll loops.
+
+You can pass all pollfds that need service to `lws_service_fd()`, even
+if the socket or file does not belong to **libwebsockets** it is safe.
+
+If **libwebsocket** handled it, it zeros the pollfd `revents` field before returning.
+So you can let **libwebsockets** try and if `pollfd->revents` is nonzero on return,
+you know it needs handling by your code.
+
+Also note that when integrating a foreign event loop like libev or libuv where
+it doesn't natively use poll() semantics, and you must return a fake pollfd
+reflecting the real event:
+
+ - be sure you set .events to .revents value as well in the synthesized pollfd
+
+ - check the built-in support for the event loop if possible (eg, ./lib/libuv.c)
+   to see how it interfaces to lws
+   
+ - use LWS_POLLHUP / LWS_POLLIN / LWS_POLLOUT from libwebsockets.h to avoid
+   losing windows compatibility
+
+You also need to take care about "forced service" somehow... these are cases
+where the network event was consumed, incoming data was all read, for example,
+but the work arising from it was not completed.  There will not be any more
+network event to trigger the remaining work, Eg, we read compressed data, but
+we did not use up all the decompressed data before returning to the event loop
+because we had to write some of it.
+
+Lws provides an API to determine if anyone is waiting for forced service,
+`lws_service_adjust_timeout(context, 1, tsi)`, normally tsi is 0.  If it returns
+0, then at least one connection has pending work you can get done by calling
+`lws_service_tsi(context, -1, tsi)`, again normally tsi is 0.
+
+For eg, the default poll() event loop, or libuv/ev/event, lws does this
+checking for you and handles it automatically.  But in the external polling
+loop case, you must do it explicitly.  Handling it after every normal service
+triggered by the external poll fd should be enough, since the situations needing
+it are initially triggered by actual network events.
+
+An example of handling it is shown in the test-server code specific to
+external polling.
+
+@section cpp Using with in c++ apps
+
+The library is ready for use by C++ apps.  You can get started quickly by
+copying the test server
+
+```
+	$ cp test-apps/test-server.c test.cpp
+```
+
+and building it in C++ like this
+
+```
+	$ g++ -DINSTALL_DATADIR=\"/usr/share\" -ocpptest test.cpp -lwebsockets
+```
+
+`INSTALL_DATADIR` is only needed because the test server uses it as shipped, if
+you remove the references to it in your app you don't need to define it on
+the g++ line either.
+
+
+@section headerinfo Availability of header information
+
+HTTP Header information is managed by a pool of "ah" structs.  These are a
+limited resource so there is pressure to free the headers and return the ah to
+the pool for reuse.
+
+For that reason header information on HTTP connections that get upgraded to
+websockets is lost after the ESTABLISHED callback.  Anything important that
+isn't processed by user code before then should be copied out for later.
+
+For HTTP connections that don't upgrade, header info remains available the
+whole time.
+
+@section http2compat Code Requirements for HTTP/2 compatibility
+
+Websocket connections only work over http/1, so there is nothing special to do
+when you want to enable -DLWS_WITH_HTTP2=1.
+
+The internal http apis already follow these requirements and are compatible with
+http/2 already.  So if you use stuff like mounts and serve stuff out of the
+filesystem, there's also nothing special to do.
+
+However if you are getting your hands dirty with writing response headers, or
+writing bulk data over http/2, you need to observe these rules so that it will
+work over both http/1.x and http/2 the same.
+
+1) LWS_PRE requirement applies on ALL lws_write().  For http/1, you don't have
+to take care of LWS_PRE for http data, since it is just sent straight out.
+For http/2, it will write up to LWS_PRE bytes behind the buffer start to create
+the http/2 frame header.
+
+This has implications if you treated the input buffer to lws_write() as const...
+it isn't any more with http/2, up to 9 bytes behind the buffer will be trashed.
+
+2) Headers are encoded using a sophisticated scheme in http/2.  The existing
+header access apis are already made compatible for incoming headers,
+for outgoing headers you must:
+
+ - observe the LWS_PRE buffer requirement mentioned above
+ 
+ - Use `lws_add_http_header_status()` to add the transaction status (200 etc)
+ 
+ - use lws apis `lws_add_http_header_by_name()` and `lws_add_http_header_by_token()`
+   to put the headers into the buffer (these will translate what is actually
+   written to the buffer depending on if the connection is in http/2 mode or not)
+   
+ - use the `lws api lws_finalize_http_header()` api after adding the last
+   response header
+   
+ - write the header using lws_write(..., `LWS_WRITE_HTTP_HEADERS`);
+ 
+ 3) http/2 introduces per-stream transmit credit... how much more you can send
+ on a stream is decided by the peer.  You start off with some amount, as the
+ stream sends stuff lws will reduce your credit accordingly, when it reaches
+ zero, you must not send anything further until lws receives "more credit" for
+ that stream the peer.  Lws will suppress writable callbacks if you hit 0 until
+ more credit for the stream appears, and lws built-in file serving (via mounts
+ etc) already takes care of observing the tx credit restrictions.  However if
+ you write your own code that wants to send http data, you must consult the
+ `lws_get_peer_write_allowance()` api to find out the state of your tx credit.
+ For http/1, it will always return (size_t)-1, ie, no limit.
+ 
+ This is orthogonal to the question of how much space your local side's kernel
+ will make to buffer your send data on that connection.  So although the result
+ from `lws_get_peer_write_allowance()` is "how much you can send" logically,
+ and may be megabytes if the peer allows it, you should restrict what you send
+ at one time to whatever your machine will generally accept in one go, and
+ further reduce that amount if `lws_get_peer_write_allowance()` returns
+ something smaller.  If it returns 0, you should not consume or send anything
+ and return having asked for callback on writable, it will only come back when
+ more tx credit has arrived for your stream.
+ 
+ 4) Header names with captital letters are illegal in http/2.  Header names in
+ http/1 are case insensitive.  So if you generate headers by name, change all
+ your header name strings to lower-case to be compatible both ways.
+ 
+ 5) Chunked Transfer-encoding is illegal in http/2, http/2 peers will actively
+ reject it.  Lws takes care of removing the header and converting CGIs that
+ emit chunked into unchunked automatically for http/2 connections.
+ 
+If you follow these rules, your code will automatically work with both http/1.x
+and http/2.
+
+@section ka TCP Keepalive
+
+It is possible for a connection which is not being used to send to die
+silently somewhere between the peer and the side not sending.  In this case
+by default TCP will just not report anything and you will never get any more
+incoming data or sign the link is dead until you try to send.
+
+To deal with getting a notification of that situation, you can choose to
+enable TCP keepalives on all **libwebsockets** sockets, when you create the
+context.
+
+To enable keepalive, set the ka_time member of the context creation parameter
+struct to a nonzero value (in seconds) at context creation time.  You should
+also fill ka_probes and ka_interval in that case.
+
+With keepalive enabled, the TCP layer will send control packets that should
+stimulate a response from the peer without affecting link traffic.  If the
+response is not coming, the socket will announce an error at `poll()` forcing
+a close.
+
+Note that BSDs don't support keepalive time / probes / interval per-socket
+like Linux does.  On those systems you can enable keepalive by a nonzero
+value in `ka_time`, but the systemwide kernel settings for the time / probes/
+interval are used, regardless of what nonzero value is in `ka_time`.
+
+
+@section sslopt Optimizing SSL connections
+
+There's a member `ssl_cipher_list` in the `lws_context_creation_info` struct
+which allows the user code to restrict the possible cipher selection at
+context-creation time.
+
+You might want to look into that to stop the ssl peers selecting a cipher which
+is too computationally expensive.  To use it, point it to a string like
+
+	`"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"`
+
+if left `NULL`, then the "DEFAULT" set of ciphers are all possible to select.
+
+You can also set it to `"ALL"` to allow everything (including insecure ciphers).
+
+
+@section sslcerts Passing your own cert information direct to SSL_CTX
+
+For most users it's enough to pass the SSL certificate and key information by
+giving filepaths to the info.ssl_cert_filepath and info.ssl_private_key_filepath
+members when creating the vhost.
+
+If you want to control that from your own code instead, you can do so by leaving
+the related info members NULL, and setting the info.options flag
+LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX at vhost creation time.  That will create
+the vhost SSL_CTX without any certificate, and allow you to use the callback
+LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS to add your certificate to
+the SSL_CTX directly.  The vhost SSL_CTX * is in the user parameter in that
+callback.
+
+@section clientasync Async nature of client connections
+
+When you call `lws_client_connect_info(..)` and get a `wsi` back, it does not
+mean your connection is active.  It just means it started trying to connect.
+
+Your client connection is actually active only when you receive
+`LWS_CALLBACK_CLIENT_ESTABLISHED` for it.
+
+There's a 5 second timeout for the connection, and it may give up or die for
+other reasons, if any of that happens you'll get a
+`LWS_CALLBACK_CLIENT_CONNECTION_ERROR` callback on protocol 0 instead for the
+`wsi`.
+
+After attempting the connection and getting back a non-`NULL` `wsi` you should
+loop calling `lws_service()` until one of the above callbacks occurs.
+
+As usual, see [test-client.c](../test-apps/test-client.c) for example code.
+
+Notice that the client connection api tries to progress the connection
+somewhat before returning.  That means it's possible to get callbacks like
+CONNECTION_ERROR on the new connection before your user code had a chance to
+get the wsi returned to identify it (in fact if the connection did fail early,
+NULL will be returned instead of the wsi anyway).
+
+To avoid that problem, you can fill in `pwsi` in the client connection info
+struct to point to a struct lws that get filled in early by the client
+connection api with the related wsi.  You can then check for that in the
+callback to confirm the identity of the failing client connection.
+
+
+@section fileapi Lws platform-independent file access apis
+
+lws now exposes his internal platform file abstraction in a way that can be
+both used by user code to make it platform-agnostic, and be overridden or
+subclassed by user code.  This allows things like handling the URI "directory
+space" as a virtual filesystem that may or may not be backed by a regular
+filesystem.  One example use is serving files from inside large compressed
+archive storage without having to unpack anything except the file being
+requested.
+
+The test server shows how to use it, basically the platform-specific part of
+lws prepares a file operations structure that lives in the lws context.
+
+The user code can get a pointer to the file operations struct
+
+```
+	LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops *
+		`lws_get_fops`(struct lws_context *context);
+```
+
+and then can use helpers to also leverage these platform-independent
+file handling apis
+
+```
+	lws_fop_fd_t
+	`lws_plat_file_open`(struct lws_plat_file_ops *fops, const char *filename,
+			   lws_fop_flags_t *flags)
+	int
+	`lws_plat_file_close`(lws_fop_fd_t fop_fd)
+
+	unsigned long
+	`lws_plat_file_seek_cur`(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
+
+	int
+	`lws_plat_file_read`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		   uint8_t *buf, lws_filepos_t len)
+
+	int
+	`lws_plat_file_write`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		   uint8_t *buf, lws_filepos_t len )
+```
+
+Generic helpers are provided which provide access to generic fops information or
+call through to the above fops
+
+```
+lws_filepos_t
+lws_vfs_tell(lws_fop_fd_t fop_fd);
+
+lws_filepos_t
+lws_vfs_get_length(lws_fop_fd_t fop_fd);
+
+uint32_t
+lws_vfs_get_mod_time(lws_fop_fd_t fop_fd);
+
+lws_fileofs_t
+lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
+
+lws_fileofs_t
+lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
+```
+
+
+The user code can also override or subclass the file operations, to either
+wrap or replace them.  An example is shown in test server.
+
+### Changes from v2.1 and before fops
+
+There are several changes:
+
+1) Pre-2.2 fops directly used platform file descriptors.  Current fops returns and accepts a wrapper type lws_fop_fd_t which is a pointer to a malloc'd struct containing information specific to the filesystem implementation.
+
+2) Pre-2.2 fops bound the fops to a wsi.  This is completely removed, you just give a pointer to the fops struct that applies to this file when you open it.  Afterwards, the operations in the fops just need the lws_fop_fd_t returned from the open.
+
+3) Everything is wrapped in typedefs.  See lws-plat-unix.c for examples of how to implement.
+
+4) Position in the file, File Length, and a copy of Flags left after open are now generically held in the fop_fd.
+VFS implementation must set and manage this generic information now.  See the implementations in lws-plat-unix.c for
+examples.
+
+5) The file length is no longer set at a pointer provided by the open() fop.  The api `lws_vfs_get_length()` is provided to
+get the file length after open.
+
+6) If your file namespace is virtual, ie, is not reachable by platform fops directly, you must set LWS_FOP_FLAG_VIRTUAL
+on the flags during open.
+
+7) There is an optional `mod_time` uint32_t member in the generic fop_fd.  If you are able to set it during open, you
+should indicate it by setting `LWS_FOP_FLAG_MOD_TIME_VALID` on the flags.
+
+@section rawfd RAW file descriptor polling
+
+LWS allows you to include generic platform file descriptors in the lws service / poll / event loop.
+
+Open your fd normally and then
+
+```
+	lws_sock_file_fd_type u;
+
+	u.filefd = your_open_file_fd;
+
+	if (!lws_adopt_descriptor_vhost(vhost, 0, u,
+					"protocol-name-to-bind-to",
+					optional_wsi_parent_or_NULL)) {
+		// failed
+	}
+
+	// OK
+```
+
+A wsi is created for the file fd that acts like other wsi, you will get these
+callbacks on the named protocol
+
+```
+	LWS_CALLBACK_RAW_ADOPT_FILE
+	LWS_CALLBACK_RAW_RX_FILE
+	LWS_CALLBACK_RAW_WRITEABLE_FILE
+	LWS_CALLBACK_RAW_CLOSE_FILE
+```
+
+starting with LWS_CALLBACK_RAW_ADOPT_FILE.
+
+The minimal example `raw/minimal-raw-file` demonstrates how to use it.
+
+`protocol-lws-raw-test` plugin also provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+The plugin creates a FIFO on your system called "/tmp/lws-test-raw"
+
+You can feed it data through the FIFO like this
+
+```
+  $ sudo sh -c "echo hello > /tmp/lws-test-raw"
+```
+
+This plugin simply prints the data.  But it does it through the lws event
+loop / service poll.
+
+@section rawsrvsocket RAW server socket descriptor polling
+
+You can also enable your vhost to accept RAW socket connections, in addition to
+HTTP[s] and WS[s].  If the first bytes written on the connection are not a
+valid HTTP method, then the connection switches to RAW mode.
+
+This is disabled by default, you enable it by setting the `.options` flag
+LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG, and setting
+`.listen_accept_role` to `"raw-skt"` when creating the vhost.
+
+RAW mode socket connections receive the following callbacks
+
+```
+	LWS_CALLBACK_RAW_ADOPT
+	LWS_CALLBACK_RAW_RX
+	LWS_CALLBACK_RAW_WRITEABLE
+	LWS_CALLBACK_RAW_CLOSE
+```
+
+You can control which protocol on your vhost handles these RAW mode
+incoming connections by setting the vhost info struct's `.listen_accept_protocol`
+to the vhost protocol name to use.
+
+`protocol-lws-raw-test` plugin provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+Run libwebsockets-test-server-v2.0 and connect to it by telnet, eg
+
+```
+    $ telnet 127.0.0.1 7681
+```
+
+type something that isn't a valid HTTP method and enter, before the
+connection times out.  The connection will switch to RAW mode using this
+protocol, and pass the unused rx as a raw RX callback.
+    
+The test protocol echos back what was typed on telnet to telnet.
+
+@section rawclientsocket RAW client socket descriptor polling
+
+You can now also open RAW socket connections in client mode.
+
+Follow the usual method for creating a client connection, but set the
+`info.method` to "RAW".  When the connection is made, the wsi will be
+converted to RAW mode and operate using the same callbacks as the
+server RAW sockets described above.
+
+The libwebsockets-test-client supports this using raw:// URLS.  To
+test, open a netcat listener in one window
+
+```
+ $ nc -l 9999
+```
+
+and in another window, connect to it using the test client
+
+```
+ $ libwebsockets-test-client raw://127.0.0.1:9999
+```
+
+The connection should succeed, and text typed in the netcat window (including a CRLF)
+will be received in the client.
+
+@section rawudp RAW UDP socket integration
+
+Lws provides an api to create, optionally bind, and adopt a RAW UDP
+socket (RAW here means an uninterpreted normal UDP socket, not a
+"raw socket").
+
+```
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags,
+		     const char *protocol_name, struct lws *parent_wsi);
+```
+
+`flags` should be `LWS_CAUDP_BIND` if the socket will receive packets.
+
+The callbacks `LWS_CALLBACK_RAW_ADOPT`, `LWS_CALLBACK_RAW_CLOSE`,
+`LWS_CALLBACK_RAW_RX` and `LWS_CALLBACK_RAW_WRITEABLE` apply to the
+wsi.  But UDP is different than TCP in some fundamental ways.
+
+For receiving on a UDP connection, data becomes available at
+`LWS_CALLBACK_RAW_RX` as usual, but because there is no specific
+connection with UDP, it is necessary to also get the source address of
+the data separately, using `struct lws_udp * lws_get_udp(wsi)`.
+You should take a copy of the `struct lws_udp` itself (not the
+pointer) and save it for when you want to write back to that peer.
+
+Writing is also a bit different for UDP.  By default, the system has no
+idea about the receiver state and so asking for a `callback_on_writable()`
+always believes that the socket is writeable... the callback will
+happen next time around the event loop.
+
+With UDP, there is no single "connection".  You need to write with sendto() and
+direct the packets to a specific destination.  To return packets to a
+peer who sent something earlier and you copied his `struct lws_udp`, you
+use the .sa and .salen members as the last two parameters of the sendto().
+
+The kernel may not accept to buffer / write everything you wanted to send.
+So you are responsible to watch the result of sendto() and resend the
+unsent part next time (which may involve adding new protocol headers to
+the remainder depending on what you are doing).
+
+@section ecdh ECDH Support
+
+ECDH Certs are now supported.  Enable the CMake option
+
+	cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 
+
+**and** the info->options flag
+
+	LWS_SERVER_OPTION_SSL_ECDH
+
+to build in support and select it at runtime.
+
+@section sslinfo SSL info callbacks
+
+OpenSSL allows you to receive callbacks for various events defined in a
+bitmask in openssl/ssl.h.  The events include stuff like TLS Alerts.
+
+By default, lws doesn't register for these callbacks.
+
+However if you set the info.ssl_info_event_mask to nonzero (ie, set some
+of the bits in it like `SSL_CB_ALERT` at vhost creation time, then
+connections to that vhost will call back using LWS_CALLBACK_SSL_INFO
+for the wsi, and the `in` parameter will be pointing to a struct of
+related args:
+
+```
+struct lws_ssl_info {
+	int where;
+	int ret;
+};
+```
+
+The default callback handler in lws has a handler for LWS_CALLBACK_SSL_INFO
+which prints the related information,  You can test it using the switch
+-S -s  on `libwebsockets-test-server-v2.0`.
+
+Returning nonzero from the callback will close the wsi.
+
+@section smp SMP / Multithreaded service
+
+SMP support is integrated into LWS without any internal threading.  It's
+very simple to use, libwebsockets-test-server-pthread shows how to do it,
+use -j n argument there to control the number of service threads up to 32.
+
+Two new members are added to the info struct
+
+	unsigned int count_threads;
+	unsigned int fd_limit_per_thread;
+	
+leave them at the default 0 to get the normal singlethreaded service loop.
+
+Set count_threads to n to tell lws you will have n simultaneous service threads
+operating on the context.
+
+There is still a single listen socket on one port, no matter how many
+service threads.
+
+When a connection is made, it is accepted by the service thread with the least
+connections active to perform load balancing.
+
+The user code is responsible for spawning n threads running the service loop
+associated to a specific tsi (Thread Service Index, 0 .. n - 1).  See
+the libwebsockets-test-server-pthread for how to do.
+
+If you leave fd_limit_per_thread at 0, then the process limit of fds is shared
+between the service threads; if you process was allowed 1024 fds overall then
+each thread is limited to 1024 / n.
+
+You can set fd_limit_per_thread to a nonzero number to control this manually, eg
+the overall supported fd limit is less than the process allowance.
+
+You can control the context basic data allocation for multithreading from Cmake
+using -DLWS_MAX_SMP=, if not given it's set to 1.  The serv_buf allocation
+for the threads (currently 4096) is made at runtime only for active threads.
+
+Because lws will limit the requested number of actual threads supported
+according to LWS_MAX_SMP, there is an api lws_get_count_threads(context) to
+discover how many threads were actually allowed when the context was created.
+
+See the test-server-pthreads.c sample for how to use.
+
+@section smplocking SMP Locking Helpers
+
+Lws provide a set of pthread mutex helpers that reduce to no code or
+variable footprint in the case that LWS_MAX_SMP == 1.
+
+Define your user mutex like this
+
+```
+	lws_pthread_mutex(name);
+```
+
+If LWS_MAX_SMP > 1, this produces `pthread_mutex_t name;`.  In the case
+LWS_MAX_SMP == 1, it produces nothing.
+
+Likewise these helpers for init, destroy, lock and unlock
+
+
+```
+	void lws_pthread_mutex_init(pthread_mutex_t *lock)
+	void lws_pthread_mutex_destroy(pthread_mutex_t *lock)
+	void lws_pthread_mutex_lock(pthread_mutex_t *lock)
+	void lws_pthread_mutex_unlock(pthread_mutex_t *lock)
+```
+
+resolve to nothing if LWS_MAX_SMP == 1, otherwise produce the equivalent
+pthread api.
+
+pthreads is required in lws only if LWS_MAX_SMP > 1.
+
+
+@section libevuv libev / libuv / libevent support
+
+You can select either or both
+
+	-DLWS_WITH_LIBEV=1
+	-DLWS_WITH_LIBUV=1
+	-DLWS_WITH_LIBEVENT=1
+
+at cmake configure-time.  The user application may use one of the
+context init options flags
+
+	LWS_SERVER_OPTION_LIBEV
+	LWS_SERVER_OPTION_LIBUV
+	LWS_SERVER_OPTION_LIBEVENT
+
+to indicate it will use one of the event libraries at runtime.
+
+libev and libevent headers conflict, they both define critical constants like
+EV_READ to different values.  Attempts to discuss clearing that up with both
+libevent and libev did not get anywhere useful.  Therefore CMakeLists.txt will
+error out if you enable both LWS_WITH_LIBEV and LWS_WITH_LIBEVENT.
+
+In addition depending on libev / compiler version, building anything with libev
+apis using gcc may blow strict alias warnings (which are elevated to errors in
+lws).  I did some googling at found these threads related to it, the issue goes
+back at least to 2010 on and off
+
+https://github.com/redis/hiredis/issues/434
+https://bugs.gentoo.org/show_bug.cgi?id=615532
+http://lists.schmorp.de/pipermail/libev/2010q1/000916.html
+http://lists.schmorp.de/pipermail/libev/2010q1/000920.html
+http://lists.schmorp.de/pipermail/libev/2010q1/000923.html
+
+We worked around this problem by disabling -Werror on the parts of lws that
+use libev.  FWIW as of Dec 2019 using Fedora 31 libev 4.27.1 and its gcc 9.2.1
+doesn't seem to trigger the problem even without the workaround.
+
+For these reasons and the response I got trying to raise these issues with
+them, if you have a choice about event loop, I would gently encourage you
+to avoid libev.  Where lws uses an event loop itself, eg in lwsws, we use
+libuv.
+
+@section extopts Extension option control from user code
+
+User code may set per-connection extension options now, using a new api
+`lws_set_extension_option()`.
+
+This should be called from the ESTABLISHED callback like this
+```
+	 lws_set_extension_option(wsi, "permessage-deflate",
+	                          "rx_buf_size", "12"); /* 1 << 12 */
+```
+
+If the extension is not active (missing or not negotiated for the
+connection, or extensions are disabled on the library) the call is
+just returns -1.  Otherwise the connection's extension has its
+named option changed.
+
+The extension may decide to alter or disallow the change, in the
+example above permessage-deflate restricts the size of his rx
+output buffer also considering the protocol's rx_buf_size member.
+
+
+@section httpsclient Client connections as HTTP[S] rather than WS[S]
+
+You may open a generic http client connection using the same
+struct lws_client_connect_info used to create client ws[s]
+connections.
+
+To stay in http[s], set the optional info member "method" to
+point to the string "GET" instead of the default NULL.
+
+After the server headers are processed, when payload from the
+server is available the callback LWS_CALLBACK_RECEIVE_CLIENT_HTTP
+will be made.
+
+You can choose whether to process the data immediately, or
+queue a callback when an outgoing socket is writeable to provide
+flow control, and process the data in the writable callback.
+
+Either way you use the api `lws_http_client_read()` to access the
+data, eg
+
+```
+	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
+		{
+			char buffer[1024 + LWS_PRE];
+			char *px = buffer + LWS_PRE;
+			int lenx = sizeof(buffer) - LWS_PRE;
+
+			lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n");
+
+			/*
+			 * Often you need to flow control this by something
+			 * else being writable.  In that case call the api
+			 * to get a callback when writable here, and do the
+			 * pending client read in the writeable callback of
+			 * the output.
+			 */
+			if (lws_http_client_read(wsi, &px, &lenx) < 0)
+				return -1;
+			while (lenx--)
+				putchar(*px++);
+		}
+		break;
+```
+
+Notice that if you will use SSL client connections on a vhost, you must
+prepare the client SSL context for the vhost after creating the vhost, since
+this is not normally done if the vhost was set up to listen / serve.  Call
+the api lws_init_vhost_client_ssl() to also allow client SSL on the vhost.
+
+@section clipipe Pipelining Client Requests to same host
+
+If you are opening more client requests to the same host and port, you
+can give the flag LCCSCF_PIPELINE on `info.ssl_connection` to indicate
+you wish to pipeline them.
+
+Without the flag, the client connections will occur concurrently using a
+socket and tls wrapper if requested for each connection individually.
+That is fast, but resource-intensive.
+
+With the flag, lws will queue subsequent client connections on the first
+connection to the same host and port.  When it has confirmed from the
+first connection that pipelining / keep-alive is supported by the server,
+it lets the queued client pipeline connections send their headers ahead
+of time to create a pipeline of requests on the server side.
+
+In this way only one tcp connection and tls wrapper is required to transfer
+all the transactions sequentially.  It takes a little longer but it
+can make a significant difference to resources on both sides.
+
+If lws learns from the first response header that keepalive is not possible,
+then it marks itself with that information and detaches any queued clients
+to make their own individual connections as a fallback.
+
+Lws can also intelligently combine multiple ongoing client connections to
+the same host and port into a single http/2 connection with multiple
+streams if the server supports it.
+
+Unlike http/1 pipelining, with http/2 the client connections all occur
+simultaneously using h2 stream multiplexing inside the one tcp + tls
+connection.
+
+You can turn off the h2 client support either by not building lws with
+`-DLWS_WITH_HTTP2=1` or giving the `LCCSCF_NOT_H2` flag in the client
+connection info struct `ssl_connection` member.
+
+@section vhosts Using lws vhosts
+
+If you set LWS_SERVER_OPTION_EXPLICIT_VHOSTS options flag when you create
+your context, it won't create a default vhost using the info struct
+members for compatibility.  Instead you can call lws_create_vhost()
+afterwards to attach one or more vhosts manually.
+
+```
+	LWS_VISIBLE struct lws_vhost *
+	lws_create_vhost(struct lws_context *context,
+			 struct lws_context_creation_info *info);
+```
+
+lws_create_vhost() uses the same info struct as lws_create_context(),
+it ignores members related to context and uses the ones meaningful
+for vhost (marked with VH in libwebsockets.h).
+
+```
+	struct lws_context_creation_info {
+		int port;					/* VH */
+		const char *iface;				/* VH */
+		const struct lws_protocols *protocols;		/* VH */
+		const struct lws_extension *extensions;		/* VH */
+	...
+```
+
+When you attach the vhost, if the vhost's port already has a listen socket
+then both vhosts share it and use SNI (is SSL in use) or the Host: header
+from the client to select the right one.  Or if no other vhost already
+listening the a new listen socket is created.
+
+There are some new members but mainly it's stuff you used to set at
+context creation time.
+
+
+@section sni How lws matches hostname or SNI to a vhost
+
+LWS first strips any trailing :port number.
+
+Then it tries to find an exact name match for a vhost listening on the correct
+port, ie, if SNI or the Host: header provided abc.com:1234, it will match on a
+vhost named abc.com that is listening on port 1234.
+
+If there is no exact match, lws will consider wildcard matches, for example
+if cats.abc.com:1234 is provided by the client by SNI or Host: header, it will
+accept a vhost "abc.com" listening on port 1234.  If there was a better, exact,
+match, it will have been chosen in preference to this.
+
+Connections with SSL will still have the client go on to check the
+certificate allows wildcards and error out if not.
+ 
+
+
+@section mounts Using lws mounts on a vhost
+
+The last argument to lws_create_vhost() lets you associate a linked
+list of lws_http_mount structures with that vhost's URL 'namespace', in
+a similar way that unix lets you mount filesystems into areas of your /
+filesystem how you like and deal with the contents transparently.
+
+```
+	struct lws_http_mount {
+		struct lws_http_mount *mount_next;
+		const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */
+		const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com" */
+		const char *def; /* default target, eg, "index.html" */
+	
+		struct lws_protocol_vhost_options *cgienv;
+	
+		int cgi_timeout;
+		int cache_max_age;
+	
+		unsigned int cache_reusable:1;
+		unsigned int cache_revalidate:1;
+		unsigned int cache_intermediaries:1;
+	
+		unsigned char origin_protocol;
+		unsigned char mountpoint_len;
+	};
+```
+
+The last mount structure should have a NULL mount_next, otherwise it should
+point to the 'next' mount structure in your list.
+
+Both the mount structures and the strings must persist until the context is
+destroyed, since they are not copied but used in place.
+
+`.origin_protocol` should be one of
+
+```
+	enum {
+		LWSMPRO_HTTP,
+		LWSMPRO_HTTPS,
+		LWSMPRO_FILE,
+		LWSMPRO_CGI,
+		LWSMPRO_REDIR_HTTP,
+		LWSMPRO_REDIR_HTTPS,
+		LWSMPRO_CALLBACK,
+	};
+```
+
+ - LWSMPRO_FILE is used for mapping url namespace to a filesystem directory and
+serve it automatically.
+
+ - LWSMPRO_CGI associates the url namespace with the given CGI executable, which
+runs when the URL is accessed and the output provided to the client.
+
+ - LWSMPRO_REDIR_HTTP and LWSMPRO_REDIR_HTTPS auto-redirect clients to the given
+origin URL.
+
+ - LWSMPRO_CALLBACK causes the http connection to attach to the callback
+associated with the named protocol (which may be a plugin).
+
+
+@section mountcallback Operation of LWSMPRO_CALLBACK mounts
+
+The feature provided by CALLBACK type mounts is binding a part of the URL
+namespace to a named protocol callback handler.
+
+This allows protocol plugins to handle areas of the URL namespace.  For example
+in test-server-v2.0.c, the URL area "/formtest" is associated with the plugin
+providing "protocol-post-demo" like this
+
+```
+	static const struct lws_http_mount mount_post = {
+		NULL,		/* linked-list pointer to next*/
+		"/formtest",		/* mountpoint in URL namespace on this vhost */
+		"protocol-post-demo",	/* handler */
+		NULL,	/* default filename if none given */
+		NULL,
+		0,
+		0,
+		0,
+		0,
+		0,
+		LWSMPRO_CALLBACK,	/* origin points to a callback */
+		9,			/* strlen("/formtest"), ie length of the mountpoint */
+	};
+```
+
+Client access to /formtest[anything] will be passed to the callback registered
+with the named protocol, which in this case is provided by a protocol plugin.
+
+Access by all methods, eg, GET and POST are handled by the callback.
+
+protocol-post-demo deals with accepting and responding to the html form that
+is in the test server HTML.
+
+When a connection accesses a URL related to a CALLBACK type mount, the
+connection protocol is changed until the next access on the connection to a
+URL outside the same CALLBACK mount area.  User space on the connection is
+arranged to be the size of the new protocol user space allocation as given in
+the protocol struct.
+
+This allocation is only deleted / replaced when the connection accesses a
+URL region with a different protocol (or the default protocols[0] if no
+CALLBACK area matches it).
+
+This "binding connection to a protocol" lifecycle in managed by
+`LWS_CALLBACK_HTTP_BIND_PROTOCOL` and `LWS_CALLBACK_HTTP_DROP_PROTOCOL`.
+Because of HTTP/1.1 connection pipelining, one connection may perform
+many transactions, each of which may map to different URLs and need
+binding to different protocols.  So these messages are used to
+create the binding of the wsi to your protocol including any
+allocations, and to destroy the binding, at which point you should
+destroy any related allocations.
+
+@section BINDTODEV SO_BIND_TO_DEVICE
+
+The .bind_iface flag in the context / vhost creation struct lets you
+declare that you want all traffic for listen and transport on that
+vhost to be strictly bound to the network interface named in .iface.
+
+This Linux-only feature requires SO_BIND_TO_DEVICE, which in turn
+requires CAP_NET_RAW capability... root has this capability.
+
+However this feature needs to apply the binding also to accepted
+sockets during normal operation, which implies the server must run
+the whole time as root.
+
+You can avoid this by using the Linux capabilities feature to have
+the unprivileged user inherit just the CAP_NET_RAW capability.
+
+You can confirm this with the test server
+
+
+```
+ $ sudo /usr/local/bin/libwebsockets-test-server -u agreen -i eno1 -k
+```
+
+The part that ensures the capability is inherited by the unprivileged
+user is
+
+```
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+                        info.caps[0] = CAP_NET_RAW;
+                        info.count_caps = 1;
+#endif
+```
+
+
+@section dim Dimming webpage when connection lost
+
+The lws test plugins' html provides useful feedback on the webpage about if it
+is still connected to the server, by greying out the page if not.  You can
+also add this to your own html easily
+
+ - include lws-common.js from your HEAD section
+ 
+   \<script src="/lws-common.js">\</script>
+   
+ - dim the page during initialization, in a script section on your page
+ 
+   lws_gray_out(true,{'zindex':'499'});
+   
+ - in your ws onOpen(), remove the dimming
+ 
+   lws_gray_out(false);
+   
+ - in your ws onClose(), reapply the dimming
+ 
+   lws_gray_out(true,{'zindex':'499'});
+
+@section errstyle Styling http error pages
+
+In the code, http errors should be handled by `lws_return_http_status()`.
+
+There are basically two ways... the vhost can be told to redirect to an "error
+page" URL in response to specifically a 404... this is controlled by the
+context / vhost info struct (`struct lws_context_creation_info`) member
+`.error_document_404`... if non-null the client is redirected to this string.
+
+If it wasn't redirected, then the response code html is synthesized containing
+the user-selected text message and attempts to pull in `/error.css` for styling.
+
+If this file exists, it can be used to style the error page.  See 
+https://libwebsockets.org/git/badrepo for an example of what can be done (
+and https://libwebsockets.org/error.css for the corresponding css).
+

+ 148 - 0
Source/ThirdParty/libwebsockets/READMEs/README.content-security-policy.md

@@ -0,0 +1,148 @@
+## Using Content Security Policy (CSP)
+
+### What is it?
+
+Modern browsers have recently implemented a new feature providing
+a sort of "selinux for your web page".  If the server sends some
+new headers describing the security policy for the content, then
+the browser strictly enforces it.
+
+### Why would we want to do that?
+
+Scripting on webpages is pretty universal, sometimes the scripts
+come from third parties, and sometimes attackers find a way to
+inject scripts into the DOM, eg, through scripts in content.
+
+CSP lets the origin server define what is legitimate for the page it
+served and everything else is denied.
+
+The CSP for warmcat.com and libwebsockets.org looks like this,
+I removed a handful of whitelisted image sources like travis
+status etc for clarity...
+
+```
+"content-security-policy": "default-src 'none'; img-src 'self' data:; script-src 'self'; font-src 'self'; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none';",
+"x-content-type-options": "nosniff",
+"x-xss-protection": "1; mode=block",
+"x-frame-options": "deny",
+"referrer-policy": "no-referrer"
+```
+
+The result of this is the browser won't let the site content be iframed, and it
+will reject any inline styles or inline scripts.  Fonts, css, ajax, ws and
+images are only allowed to come from 'self', ie, the server that served the
+page.  You may inject your script, or deceptive styles: it won't run or be shown.
+
+Because inline scripts are banned, the usual methods for XSS are dead;
+the attacker can't even load js from another server.  So these rules
+provide a very significant increase in client security.
+
+### Implications of strict CSP
+
+Halfhearted CSP isn't worth much.  The only useful approach is to start
+with `default-src 'none'` which disables everything, and then whitelist the
+minimum needed for the pages to operate.
+
+"Minimum needed for the pages to operate" doesn't mean defeat the protections
+necessary so everything in the HTML can stay the same... it means adapt the
+pages to want the minimum and then enable the minimum.
+
+The main point is segregation of styles and script away from the content, in
+files referenced in the document `<head>` section, along these lines:
+
+```
+<head>
+ <meta charset=utf-8 http-equiv="Content-Language" content="en"/>
+ <link rel="stylesheet" type="text/css" href="test.css"/>
+ <script type='text/javascript' src="/lws-common.js"></script>
+ <script type='text/javascript' src='test.js'></script>
+ <title>Minimal Websocket test app</title>
+</head>
+```
+
+#### Inline styles must die
+
+All styling must go in one or more `.css` file(s) best served by the same
+server... while you can whitelist other sources in the CSP if you have to,
+unless you control that server as well, you are allowing whoever gains
+access to that server access to your users.
+
+Inline styles are no longer allowed (eg, "style='font-size:120%'" in the
+HTML)... they must be replaced by reference to one or more CSS class, which
+in this case includes "font-size:120%".  This has always been the best
+practice anyway, and your pages will be cleaner and more maintainable.
+
+#### Inline scripts must die
+
+Inline scripts need to be placed in a `.js` file and loaded in the page head
+section, again it should only be from the server that provided the page.
+
+Then, any kind of inline script, yours or injected or whatever, will be
+completely rejected by the browser.
+
+#### onXXX must be replaced by eventListener
+
+Inline `onclick()` etc are kinds of inline scripting and are banned.
+
+Modern browsers have offered a different system called ["EventListener" for
+a while](https://developer.mozilla.org/en-US/docs/Web/API/EventListener)
+which allows binding of events to DOM elements in JS.
+
+A bunch of different named events are possible to listen on, commonly the
+`.js` file will ask for one or both of
+
+```
+window.addEventListener("load", function() {
+...
+}, false);
+
+document.addEventListener("DOMContentLoaded", function() {
+...
+}, false);
+```
+
+These give the JS a way to trigger when either everything on the page has
+been "loaded" or the DOM has been populated from the initial HTML.  These
+can set up other event listeners on the DOM objects and aftwards the
+events will drive what happens on the page from user interaction and / or
+timers etc.
+
+If you have `onclick` in your HTML today, you would replace it with an id
+for the HTML element, then eg in the DOMContentLoaded event listener,
+apply 
+
+```
+   document.getElementById("my-id").addEventListener("click", function() {
+   ...
+   }, false);
+```
+
+ie the .js file becomes the only place with the "business logic" of the
+elements mentioned in the HTML, applied at runtime.
+
+#### Do you really need external sources?
+
+Do your scripts and fonts really need to come from external sources?
+If your caching policy is liberal, they are not actually that expensive
+to serve once and then the user is using his local copy for the next
+days.
+
+Some external sources are marked as anti-privacy in modern browsers, meaning
+they track your users, in turn meaning if your site refers to them, you
+will lose your green padlock in the browser.  If the content license allows
+it, hosting them on "self", ie, the same server that provided the HTML,
+will remove that problem.
+
+Bringing in scripts from external sources is actually quite scary from the
+security perspective.  If someone hacks the `ajax.googleapis.com` site to serve
+a hostile, modified jquery, half the Internet will instantly
+become malicious.  However if you serve it yourself, unless your server
+was specifically targeted you know it will continue to serve what you
+expect.
+
+Since these scripts are usually sent with cache control headers for local
+caching duration of 1 year, the cost of serving them yourself under the same
+conditions is small but your susceptibility to attack is reduced to only taking
+care of your own server.  And there is a privacy benefit that google is not
+informed of your users' IPs and activities on your site.
+

+ 41 - 0
Source/ThirdParty/libwebsockets/READMEs/README.contributing.md

@@ -0,0 +1,41 @@
+## Contributing to lws
+
+### How to contribute
+
+Sending a patch with a bug report is very welcome.
+
+For nontrivial problems, it's probably best to discuss on the mailing list,
+or on github if you prefer, how to best solve it.
+
+However your contribution is coming is fine:
+
+ - paste a `git diff`
+
+ - send a patch series by mail or mailing list
+
+ - paste in a github issue
+
+ - github PR
+
+are all OK.
+
+### Coding Standards
+
+Code should look roughly like the existing code, which follows linux kernel
+coding style.
+
+If there are non-functional problems I will clean them out when I apply the
+patch.
+
+If there are functional problems (eg broken error paths etc) if they are
+small compared to the working part I will also clean them.  If there are
+larger problems, or consequences to the patch will have to discuss how to
+solve them with a retry.
+
+### Funding specific work
+
+If there is a feature you wish was supported in lws, consider paying for the
+work to be done.  The maintainer is a consultant and if we can agree the
+task, you can quickly get a high quality result that does just what you need,
+maintained ongoing along with the rest of lws.
+

+ 181 - 0
Source/ThirdParty/libwebsockets/READMEs/README.crypto-apis.md

@@ -0,0 +1,181 @@
+# Lws Crypto Apis
+
+## Overview
+
+![lws crypto overview](/doc-assets/lws-crypto-overview.svg)
+
+Lws provides a "generic" crypto layer on top of both OpenSSL and
+compatible tls library, and mbedtls.  Using this layer, your code
+can work without any changes on both types of tls library crypto
+backends... it's as simple as rebuilding lws with `-DLWS_WITH_MBEDTLS=0`
+or `=1` at cmake.
+
+The generic layer can be used directly (as in, eg, the sshd plugin),
+or via another layer on top, which processes JOSE JSON objects using
+JWS (JSON Web Signatures), JWK (JSON Web Keys), and JWE (JSON Web
+Encryption).
+
+The `JW` apis use the generic apis (`lws_genrsa_`, etc) to get the crypto tasks
+done, so anything they can do you can also get done using the generic apis.
+The main difference is that with the generic apis, you must instantiate the
+correct types and use type-specfic apis.  With the `JW` apis, there is only
+one interface for all operations, with the details hidden in the api and
+controlled by the JSON objects.
+
+Because of this, the `JW` apis are often preferred because they give you
+"crypto agility" cheaply... to change your crypto to another supported algorithm
+once it's working, you literally just change your JSON defining the keys and
+JWE or JWS algorithm.  (It's up to you to define your policy for which
+combinations are acceptable by querying the parsed JW structs).
+
+## Crypto supported in generic layer
+
+### Generic Hash
+
+ - SHA1
+ - SHA256
+ - SHA384
+ - SHA512
+
+### Generic HMAC
+
+ - SHA256
+ - SHA384
+ - SHA512
+
+### Generic AES
+
+ - CBC
+ - CFB128
+ - CFB8
+ - CTR
+ - ECB
+ - OFB
+ - XTS
+ - GCM
+ - KW (Key Wrap)
+
+### Generic RSA
+
+ - PKCS 1.5
+ - OAEP / PSS
+
+### Generic EC
+
+ - ECDH
+ - ECDSA
+ - P256 / P384 / P521 (sic) curves
+
+## Using the generic layer
+
+All the necessary includes are part of `libwebsockets.h`.
+
+Enable `-DLWS_WITH_GENCRYPTO=1` at cmake.
+
+|api|header|Functionality|
+|---|---|---|
+|genhash|[./include/libwebsockets/lws-genhash.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genhash.h)|Provides SHA1 + SHA2 hashes and hmac|
+|genrsa|[./include/libwebsockets/lws-genrsa.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genrsa.h)|Provides RSA encryption, decryption, signing, verification, key generation and creation|
+|genaes|[./include/libwebsockets/lws-genaes.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genaes.h)|Provides AES in all common variants for encryption and decryption|
+|genec|[./include/libwebsockets/lws-genec.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genec.h)|Provides Elliptic Curve for encryption, decryption, signing, verification, key generation and creation|
+|x509|[./include/libwebsockets/lws-x509.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-x509.h)|Apis for X.509 Certificate loading, parsing, and stack verification, plus JWK key extraction from PEM X.509 certificate / private key|
+
+Unit tests for these apis, which serve as usage examples, can be found in [./minimal-examples/api-tests/api-test-gencrypto](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-gencrypto)
+
+### Keys in the generic layer
+
+The necessary types and defines are brought in by `libwebsockets.h`.
+
+Keys are represented only by an array of `struct lws_jwk_elements`... the
+length of the array is defined by the cipher... it's one of
+
+|key elements count|definition|
+|---|---|
+|`LWS_COUNT_OCT_KEY_ELEMENTS`|1|
+|`LWS_COUNT_RSA_KEY_ELEMENTS`|8|
+|`LWS_COUNT_EC_KEY_ELEMENTS`|4|
+|`LWS_COUNT_AES_KEY_ELEMENTS`|1|
+
+`struct lws_jwk_elements` is a simple pointer / length combination used to
+store arbitrary octets that make up the key element's binary representation.
+
+## Using the JOSE layer
+
+The JOSE (JWK / JWS / JWE) stuff is a crypto-agile JSON-based layer
+that uses the gencrypto support underneath.
+
+"Crypto Agility" means the JSON structs include information about the
+algorithms and ciphers used in that particular object, making it easy to
+upgrade system crypto strength or cycle keys over time while supporting a
+transitional period where the old and new keys or algorithms + ciphers
+are also valid.
+
+Uniquely lws generic support means the JOSE stuff also has "tls library
+agility", code written to the lws generic or JOSE apis is completely unchanged
+even if the underlying tls library changes between OpenSSL and mbedtls, meaning
+sharing code between server and client sides is painless.
+
+All the necessary includes are part of `libwebsockets.h`.
+
+Enable `-DLWS_WITH_JOSE=1` at CMake.
+
+|api|header|Functionality|
+|---|---|---|
+|JOSE|[./include/libwebsockets/lws-jose.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jose.h)|Provides crypto agility for JWS / JWE|
+|JWE|[./include/libwebsockets/lws-jwe.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jwe.h)|Provides Encryption and Decryption services for RFC7516 JWE JSON|
+|JWS|[./include/libwebsockets/lws-jws.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jws.h)|Provides signature and verifcation services for RFC7515 JWS JSON|
+|JWK|[./include/libwebsockets/lws-jwk.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jwk.h)|Provides signature and verifcation services for RFC7517 JWK JSON, both "keys" arrays and singletons|
+
+Minimal examples are provided in the form of commandline tools for JWK / JWS / JWE / x509 handling:
+
+ - [JWK minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jwk)
+ - [JWS minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jws)
+ - [JWE minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jwe)
+ - [X509 minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-x509)
+
+Unit tests for these apis, which serve as usage examples, can be found in [./minimal-examples/api-tests/api-test-jose](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-jose)
+
+## Crypto supported in the JOSE layer
+
+The JOSE RFCs define specific short names for different algorithms
+
+### JWS
+
+|JSOE name|Hash|Signature|
+---|---|---
+|RS256, RS384, RS512|SHA256/384/512|RSA
+|ES256, ES384, ES521|SHA256/384/512|EC
+
+### JWE
+
+|Key Encryption|Payload authentication + crypt|
+|---|---|
+|`RSAES-PKCS1-v1.5` 2048b & 4096b|`AES_128_CBC_HMAC_SHA_256`|
+|`RSAES-PKCS1-v1.5` 2048b|`AES_192_CBC_HMAC_SHA_384`|
+|`RSAES-PKCS1-v1.5` 2048b|`AES_256_CBC_HMAC_SHA_512`|
+|`RSAES-OAEP`|`AES_256_GCM`|
+|`AES128KW`, `AES192KW`, `AES256KW`|`AES_128_CBC_HMAC_SHA_256`|
+|`AES128KW`, `AES192KW`, `AES256KW`|`AES_192_CBC_HMAC_SHA_384`|
+|`AES128KW`, `AES192KW`, `AES256KW`|`AES_256_CBC_HMAC_SHA_512`|
+|`ECDH-ES` (P-256/384/521 key)|`AES_128/192/256_GCM`|
+|`ECDH-ES+A128/192/256KW` (P-256/384/521 key)|`AES_128/192/256_GCM`|
+
+### Keys in the JOSE layer
+
+Keys in the JOSE layer use a `struct lws_jwk`, this contains two arrays of
+`struct lws_jwk_elements` sized for the worst case (currently RSA).  One
+array contains the key elements as described for the generic case, and the
+other contains various nonencrypted key metadata taken from JWK JSON.
+
+|metadata index|function|
+|---|---|
+|`JWK_META_KTY`|Key type, eg, "EC"|
+|`JWK_META_KID`|Arbitrary ID string|
+|`JWK_META_USE`|What the public key may be used to validate, "enc" or "sig"|
+|`JWK_META_KEY_OPS`|Which operations the key is authorized for, eg, "encrypt"|
+|`JWK_META_X5C`|Optional X.509 cert version of the key|
+|`JWK_META_ALG`|Optional overall crypto algorithm the key is intended for use with|
+
+`lws_jwk_destroy()` should be called when the jwk is going out of scope... this
+takes care to zero down any key element data in the jwk.
+

+ 67 - 0
Source/ThirdParty/libwebsockets/READMEs/README.ctest.md

@@ -0,0 +1,67 @@
+## Using CTest with lws
+
+### Updating ancient cmake
+
+You need a recent cmake to have the CTest tests work properly, if you're on an
+older distro you need to update your cmake.  Luckily Kitware provide a repo for
+common distros.  These instructions work for bionic and xenial.
+
+First remove the old distro cmake and install the pieces needed to get the new repo keys
+
+```
+# apt purge --auto-remove cmake
+# apt install gnupg wget apt-transport-https ca-certificates
+# wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
+# apt edit-sources
+```
+
+Add the line `deb https://apt.kitware.com/ubuntu/ bionic main` at the end
+replacing `bionic` with `xenial` as needed, and save (:wq).  Then
+
+```
+# apt update
+# apt install cmake
+```
+
+## Generating the tests
+
+The main tests just need `-DLWS_WITH_MINIMAL_EXAMPLES=1`.  You can optionally set
+`-DLWS_CTEST_INTERNET_AVAILABLE=0` to indicate you can't run the tests that need
+internet connectivity.
+
+## Preparing to run the tests
+
+The tests have to spawn by script some "test buddies", for example the client
+tests have to run a test server from the built lws image.  For that reason you
+have to do a side-install into `./destdir` using `make install DESTDIR=../destdir`
+from the build directory before all the tests will work properly.
+
+## Running the tests
+
+CMake puts the test action into a build-host type specific form, for unix type
+platforms you just run `make test` or `CTEST_OUTPUT_ON_FAILURE=1 make test` to
+see what happened to any broken tests.
+
+On windows, it looks like `ctest . -C DEBUG` or RELEASE if that was the build
+type.
+
+## Considerations for creating tests
+
+### Timeout
+
+The default test timeout is 1500s, for that reason it's good practice to set
+a more suitable `TIMEOUT` property on every test.
+
+### Working Directory
+
+Server-side test apps usually need to be run from their `./minimal-examples/...`
+directory so they can access their assets like index.html etc.
+
+However when building with `-DLWS_WITH_MBEDTLS=1` then even client-side apps
+need to be run from their directory, since they need to get the trusted CA for
+warmcat.com or libwebsockets.org additionally.
+
+For that reason it's good practice to set the `WORKING_DIRECTORY` property to
+the home dir of the example app in all cases.
+
+

+ 63 - 0
Source/ThirdParty/libwebsockets/READMEs/README.debugging.md

@@ -0,0 +1,63 @@
+# Tips on debugging with lws
+
+## Problem with the library, or your code?
+
+Because lws is only really used when already combined with user code,
+it can be a headache figuring out if the actual problem is inside lws
+or in the user code.
+
+If it's in lws, I would really like to solve it, but if it's in your
+code, that's your problem.  Finding out which side it's on when it
+involves your code is also something you need to try to resolve.
+
+The minimal examples are useful because if they demonstrate the same
+problem, it's something about your platform or lws itself, I have the
+minimal examples so I can test it and find out if it's your platform.
+If I can reproduce it, it's my problem.
+
+## Debug builds
+
+With cmake, build with `-DCMAKE_BUILD_TYPE=DEBUG` to build in extra
+logging, and use a log level bitmap of eg, 1039 or 1151 to enable
+the extra logs for print.
+
+The minimal examples take a -d xxx commandline parameter so you can
+select the logging level when you run it.
+
+The extra logging can be very useful to understand the sequencing of
+problematic actions.
+
+## Valgrind
+
+If your problems involve heap corruption or use-after-free, Valgrind
+is indespensible.  It's simple to use, if you normally run `xxx`, just
+run `valgrind xxx`.  Your code will run slower, usually something
+like 2 - 4x slower but it depends on the exact code.  However you will
+get a backtrace as soon as there is some kind of misbehaviour of either
+lws or your code.
+
+lws is developed using valgrind routinely and strives to be completely
+valgrind-clean.  So typically any problems reported are telling you
+about problems in user code (or my bugs).
+
+## Traffic dumping
+
+The best place for dumping traffic, assuming you are linking against a
+tls library, is `lws_ssl_capable_read()` and `lws_ssl_capable_write()`
+in either `./lib/tls/openssl/openssl-ssl.c` or
+`./lib/tls/mbedtls/mbedtls-ssl.c` according to which tls library you
+are using.  There are default-`#if 0` sections in each function like
+
+```
+#if 0
+	/*
+	 * If using mbedtls type tls library, this is the earliest point for all
+	 * paths to dump what was received as decrypted data from the tls tunnel
+	 */
+	lwsl_notice("%s: len %d\n", __func__, len);
+	lwsl_hexdump_notice(buf, len);
+#endif
+```
+
+Enable these to get hexdumps for all unencrypted data in both directions.
+

+ 117 - 0
Source/ThirdParty/libwebsockets/READMEs/README.detailed-latency.md

@@ -0,0 +1,117 @@
+# lws detailed latency
+
+![lws detailed latency example plot](../doc-assets/lws-detailed-latency-example.png)
+
+## Introduction
+
+lws has the capability to make detailed latency measurements and
+report them in realtime to a specified callback.
+
+A default callback is provided that renders the data as text in
+space-separated format suitable for gnuplot, to a specified file.
+
+## Configuring
+
+Enable `LWS_WITH_DETAILED_LATENCY` at cmake.
+
+Create your context with something similar to this
+
+```
+#if defined(LWS_WITH_DETAILED_LATENCY)
+	info.detailed_latency_cb = lws_det_lat_plot_cb;
+	info.detailed_latency_filepath = "/tmp/lws-latency-results";
+#endif
+```
+
+`lws_det_lat_plot_cb` is provided by lws as a convenience to convert
+the stuct data provided at the callback interface to space-separated
+text data that is easy to process with shell commands and gnuplot.
+
+## `lws_det_lat_plot_cb` format
+
+```
+728239173547 N 23062 0 0 23062 0 0 0
+728239192554 C 18879 0 0 18879 0 0 0
+728239217894 T 25309 0 0 25309 0 0 0
+728239234998 r 0 0 0 0 271 172 256
+728239250611 r 0 0 0 0 69 934 4096
+728239255679 w 19 122 18 159 20 80 80
+728239275718 w 20 117 15 152 18 80 80
+728239295578 w 10 73 7 90 7 80 80
+728239315567 w 9 67 5 81 7 80 80
+728239335745 w 23 133 9 165 14 80 80
+...
+```
+
+Each event is shown in 9 columns
+
+ - unix time in us
+ - event type
+   - N = Name resolution
+   - C = TCP Connection
+   - T = TLS negotiation server
+   - t = TLS negotiation client
+   - r = Read
+   - w = Write
+ - us duration, for w time client spent waiting to write
+ - us duration, for w time data spent in transit to proxy
+ - us duration, for w time proxy waited to send data
+ - as a convenience, sum of last 3 columns above
+ - us duration, time spent in callback
+ - last 2 are actual / requested size in bytes
+
+## Processing captured data with ministat
+
+Eg, to summarize overall latencies on all captured writes
+
+```
+ $ cat /tmp/lws-latency-results | grep " w " | cut -d' ' -f6 | ministat
+...
+    N           Min           Max        Median           Avg        Stddev
+x 1000            43           273           141       132.672     32.471693
+```
+
+## Processing captured data with gnuplot
+
+### Gnuplot plotting script
+
+Create a gnuplot script, eg myscript.gp
+
+```
+reset
+set term pngcairo enhanced nocrop font "OpenSans, 12" size 800,600#output terminal and file
+set output "lws-latency.png"
+#set yrange [0:10000]
+#to put an empty boundary around the
+#data inside an autoscaled graph.
+set offset graph 0.05,0.05,0.05,0.0
+set style fill transparent solid 0.5 #fillstyle
+set tics out nomirror
+set xlabel "event"
+set ylabel "latency (us)"
+set format x ""
+set title "Write latency"
+set key invert reverse Right inside nobox
+set key autotitle columnheader
+set style data histogram
+set style histogram rowstacked
+set style fill solid border -1
+set boxwidth 0.75
+set style fill solid 1.00 noborder
+set tic scale 0
+set grid ytics lc rgb "#505050"
+unset border
+unset xtics
+
+plot '/tmp/1' \
+	   using ($3 + $4 + $5):xtic(1)         w boxes lt rgbcolor "blue"  title 'prox wr wait', \
+	'' using ($3 + $4):xtic(1)         w boxes lt rgbcolor "green" title 'txfr to prox', \
+	'' using 3:xtic(1) w boxes lt rgbcolor "red"   title 'cli wri wait'
+```
+
+### gnuplot invocation
+
+```
+ $ cat /tmp/lws-latency-results | grep " w " \>/tmp/1 ; gnuplot myscript.gp && eog lws-latency.png
+```
+

+ 37 - 0
Source/ThirdParty/libwebsockets/READMEs/README.esp32.md

@@ -0,0 +1,37 @@
+ESP32 Support
+=============
+
+See \ref esp32 for details on how to build lws as a component in an ESP-IDF project.
+
+Lws provides a "factory" application
+
+https://github.com/warmcat/lws-esp32-factory
+
+and a test application which implements the generic lws server test apps
+
+https://github.com/warmcat/lws-esp32-test-server-demos
+
+The behaviours of the generic factory are are quite rich, and cover uploading SSL certs through factory and user configuration, AP selection and passphrase entry, and managing a switch to allow the user to force entry to user setup mode at boot subsequently.
+
+The factory app comes with partitioning for a 1MB factory partition containing that app and data, and a single 2.9MB OTA partition containing the main app.
+
+The factory app is able to do OTA updates for both the factory and OTA partition slots; updating the factory slot first writes the new image to the OTA slot and copies it into place at the next boot, after which the user can reload the OTA slot.
+
+State|Image|AP SSID|Port|URL|Mode
+---|---|---|---|---|---
+Factory Reset or Uninitialized|Factory|AP: ESP_012345|80|http://192.168.4.1|factory.html - to set certificates and serial
+User configuration|Factory|AP: config-model-serial|443|https://192.168.4.1|index.html - user set up his AP information
+Operation|OTA|Station only|443|https://model-serial.local|OTA application
+
+## Basic Auth
+
+The lws-esp32-test-server-demos app also demos basic auth.
+
+On a normal platform this is done by binding a mount to a text file somewhere in the filesystem, which
+contains user:password information one per line.
+
+On ESP32 there is not necessarily any generic VFS in use.  So instead, the basic auth lookup is bound to
+a given nvs domain, where the username is the key and the password the value.  main/main.c in the test
+demos app shows how to both make the mount use basic auth, and how to set a user:password combination
+using nvs.
+

+ 80 - 0
Source/ThirdParty/libwebsockets/READMEs/README.event-libs.md

@@ -0,0 +1,80 @@
+# lws event library support
+
+## v4.0 and below
+
+Before v4.1, lws allowed selecting some event library support for inclusion
+in the libwebsockets library
+
+Option|Feature
+---|---
+`LWS_WITH_GLIB`|glib
+`LWS_WITH_LIBEVENT`|libevent
+`LWS_WITH_LIBUV`|libuv
+`LWS_WITH_LIBEV`|libev
+
+The user code can select by `info->options` flags at runtime which event loop
+it wants to use.
+
+The only restriction is that libev and libevent can't coexist, because their
+header namespace conflicts.
+
+## v4.1 and above
+
+Lws continues to support the old way described above, but there's an additional
+new cmake option that decides how they are built if any are selected,
+`LWS_WITH_EVLIB_PLUGINS`.
+
+The old behaviour is set by `LWS_WITH_EVLIB_PLUGINS=0`, for UNIX platforms, this
+is set to 1 by default.  This causes the enabled event lib support to each be built into
+its own dynamically linked plugin, and lws will bring in the requested support alone
+at runtime after seeing the `info->options` flags requested by the user code.
+
+This has two main benefits, first the conflict around building libevent and libev
+together is removed, they each build isolated in their own plugin; the libwebsockets
+core library build doesn't import any of their headers (see below for exception).
+And second, for distro packaging, the event lib support plugins can be separately
+packaged, and apps take dependencies on the specific event lib plugin package, which
+itself depends on the libwebsockets core library.  This allows just the needed
+dependencies for the packageset without forcing everything to bring everything in.
+
+Separately, lws itself has some optional dependencies on libuv, if you build lwsws
+or on Windows you want plugins at all.  CMake will detect these situations and
+select to link the lws library itself to libuv if so as well, independent of whatever
+is happening with the event lib support.
+
+## evlib plugin install
+
+The produced plugins are named
+
+event lib|plugin name
+---|---
+glib|`libwebsockets-evlib_glib.so`
+event|`libwebsockets-evlib_event.so`
+uv|`libwebsockets-evlib_uv.so`
+ev|`libwebsockets-evlib_ev.so`
+
+The evlib plugins are installed alongside libwebsockets.so/.a into the configured
+library dir, it's often `/usr/local/lib/` by default on linux.
+
+Lws looks for them at runtime using the build-time-configured path.
+
+## Component packaging
+
+The canonical package name is `libwebsockets`, the recommended way to split the
+packaging is put the expected libs and pkgconfig in `libwebsockets` or `libwebsockets-core`,
+the latter is followed by the provided cmake, and produce an additional package per build
+event library plugin, named, eg `libwebsockets-evlib_glib`, which has a dependency on
+`libwebsockets[-core]`.
+
+Applications that use the default event loop can directly require `libwebsockets[-core]`,
+and application packages that need specific event loop support can just require, eg,
+`libwebsockets-evlib_glib`, which will bring that in and the core lws pieces in one step.
+There is then no problem with multiple apps requiring different event libs, they will
+bring in all the necessary pieces which will not conflict either as packages or at
+runtime.
+
+## `LWS_WITH_DISTRO_RECOMMENDED`
+
+The cmake helper config `LWS_WITH_DISTRO_RECOMMENDED` is adapted to build all the
+event libs with the event lib plugin support enabled.
+

+ 55 - 0
Source/ThirdParty/libwebsockets/READMEs/README.h2-long-poll.md

@@ -0,0 +1,55 @@
+# h2 long poll in lws
+
+lws server and client can support "immortal" streams that are
+not subject to normal timeouts under a special condition.  These
+are read-only (to the client).
+
+Network connections that contain at least one immortal stream
+are themselves not subject to timeouts until the last immortal
+stream they are carrying closes.
+
+Because of this, it's recommended there is some other way of
+confirming that the client is still active.
+
+## Setting up lws server for h2 long poll
+
+Vhosts that wish to allow clients to serve these immortal
+streams need to set the info.options flag `LWS_SERVER_OPTION_VH_H2_HALF_CLOSED_LONG_POLL`
+at vhost creation time.  The JSON config equivalent is to set
+
+```
+"h2-half-closed-long-poll": "1"
+```
+
+on the vhost.  That's all that is needed.
+
+Streams continue to act normally for timeout with the exception
+client streams are allowed to signal they are half-closing by
+sending a zero-length DATA frame with END_STREAM set.  These
+streams are allowed to exist outside of any timeout and data
+can be sent on them at will in the server -> client direction.
+
+## Setting client streams for long poll
+
+An API is provided to allow established h2 client streams to
+transition to immortal mode and send the END_STREAM to the server
+to indicate it.
+
+```
+int
+lws_h2_client_stream_long_poll_rxonly(struct lws *wsi);
+```
+
+## Example applications
+
+You can confirm the long poll flow simply using example applications.
+Build and run `http-server/minimal-http-server-h2-long-poll` in one
+terminal.
+
+In another, build the usual `http-client/minimal-http-client` example
+and run it with the flags `-l --long-poll`
+
+The client will connect to the server and transition to the immortal mode.
+The server sends a timestamp every minute to the client, and that will
+stay up without timeouts.
+

+ 172 - 0
Source/ThirdParty/libwebsockets/READMEs/README.http-fallback.md

@@ -0,0 +1,172 @@
+# Http fallback and raw proxying
+
+Lws has several interesting options and features that can be applied to get
+some special behaviours... this article discusses them and how they work.
+
+## Overview of normal vhost selection
+
+Lws supports multiple http or https vhosts sharing a listening socket on the
+same port.
+
+For unencrypted http, the Host: header is used to select which vhost the
+connection should bind to, by comparing what is given there against the
+names the server was configured with for the various vhosts.  If no match, it
+selects the first configured vhost.
+
+For TLS, it has an extension called SNI (Server Name Indication) which tells
+the server early in the TLS handshake the host name the connection is aimed at.
+That allows lws to select the vhost early, and use vhost-specific TLS certs
+so everything is happy.  Again, if there is no match the connection proceeds
+using the first configured vhost and its certs.
+
+## Http(s) fallback options
+
+What happens if you try to connect, eg, an ssh client to the http server port
+(this is not an idle question...)?  Obviously the http server part or the tls
+part of lws will fail the connection and close it.  (We will look at that flow
+in a moment in detail for both unencrypted and tls listeners.)
+
+However if the first configured vhost for the port was created with the
+vhost creation info struct `.options` flag `LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG`,
+then instead of the error, the connection transitions to whatever role was
+given in the vhost creation info struct `.listen_accept_role` and `.listen_accept_protocol`.
+
+With lejp-conf / lwsws, the options can be applied to the first vhost using:
+
+```
+   "listen-accept-role": "the-role-name",
+   "listen-accept-protocol": "the-protocol-name",
+   "fallback-listen-accept": "1"
+```
+
+See `./minimal-examples/raw/minimal-raw-fallback-http-server` for examples of
+all the options in use via commandline flags.
+
+So long as the first packet for the protocol doesn't look like GET, POST, or
+a valid tls packet if connection to an https vhost, this allows the one listen
+socket to handle both http(s) and a second protocol, as we will see, like ssh.
+
+Notice there is a restriction that no vhost selection processing is possible,
+neither for tls listeners nor plain http ones... the packet belonging to a
+different protocol will not send any Host: header nor tls SNI.
+
+Therefore although the flags and settings are applied to the first configured
+vhost, actually their effect is global for a given listen port.  If enabled,
+all vhosts on the same listen port will do the fallback action.
+
+### Plain http flow
+
+![plain http flow](/doc-assets/accept-flow-1.svg)
+
+Normally, if the first received packet does not contain a valid HTTP method,
+then the connection is dropped.  Which is what you want from an http server.
+
+However if enabled, the connection can transition to the defined secondary
+role / protocol.
+
+|Flag|lejp-conf / lwsws|Function|
+|---|---|---|
+|`LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG`|`"fallback-listen-accept": "1"`|Enable fallback processing|
+
+### TLS https flow
+
+![tls https flow](/doc-assets/accept-flow-2.svg)
+
+If the port is listening with tls, the point that a packet from a different
+protocol will fail is earlier, when the tls tunnel is being set up.
+
+|Flag|lejp-conf / lwsws|Function|
+|---|---|---|
+|`LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG`|`"fallback-listen-accept": "1"`|Enable fallback processing|
+|`LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS`|`"redirect-http": "1"`|Treat invalid tls packet as http, issue http redirect to https://|
+|`LWS_SERVER_OPTION_ALLOW_HTTP_ON_HTTPS_LISTENER`|`"allow-http-on-https": "1"`|Accept unencrypted http connections on this tls port (dangerous)|
+
+The latter two options are higher priority than, and defeat, the first one.
+
+### Non-http listener
+
+![non-http flow](/doc-assets/accept-flow-3.svg)
+
+It's also possible to skip the fallback processing and just force the first
+vhost on the port to use the specified role and protocol in the first place.
+
+|Flag|lejp-conf / lwsws|Function|
+|---|---|---|
+|LWS_SERVER_OPTION_ADOPT_APPLY_LISTEN_ACCEPT_CONFIG|`"apply-listen-accept": "1"`|Force vhost to use listen-accept-role / listen-accept-protocol|
+
+## Using http(s) fallback with raw-proxy
+
+If enabled for build with `cmake .. -DLWS_ROLE_RAW_PROXY=1 -DLWS_WITH_PLUGINS=1`
+then lws includes ready-to-use support for raw tcp proxying.
+
+This can be used standalone on the first vhost on a port, but most intriguingly
+it can be specified as the fallback for http(s)...
+
+See `./minimal-examples/raw/minimal-raw-proxy-fallback.c` for a working example.
+
+### fallback with raw-proxy in code
+
+On the first vhost for the port, specify the required "onward" pvo to configure
+the raw-proxy protocol...you can adjust the "ipv4:127.0.0.1:22" to whatever you
+want...
+
+```
+	static struct lws_protocol_vhost_options pvo1 = {
+	        NULL,
+	        NULL,
+	        "onward",		/* pvo name */
+	        "ipv4:127.0.0.1:22"	/* pvo value */
+	};
+
+	static const struct lws_protocol_vhost_options pvo = {
+	        NULL,           	/* "next" pvo linked-list */
+	        &pvo1,			/* "child" pvo linked-list */
+	        "raw-proxy",		/* protocol name we belong to on this vhost */
+	        ""              	/* ignored */
+	};
+```
+
+... and set up the fallback enable and bindings...
+
+```
+	info.options |= LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG;
+	info.listen_accept_role = "raw_proxy";
+	info.listen_accept_proxy = "raw_proxy";
+	info.pvo = &pvo;
+```
+
+### fallback with raw-proxy in JSON conf
+
+On the first vhost for the port, enable the raw-proxy protocol on the vhost and
+set the pvo config
+
+```
+                "ws-protocols": [{
+                        "raw-proxy": {
+                         "status": "ok",
+                         "onward": "ipv4:127.0.0.1:22"
+                        }
+                 }],
+```
+
+Enable the fallback behaviour on the vhost and the role / protocol binding
+
+```
+	"listen-accept-role": "raw-proxy",
+	"listen-accept-protocol": "raw-proxy",
+	"fallback-listen-accept": "1"
+```
+
+### Testing
+
+With this configured, the listen port will function normally for http or https
+depending on how it was set up.
+
+But if you try to connect to it with an ssh client, that will also work fine.
+
+The libwebsockets.org server is set up in this way, you can confirm it by
+visiting `https://libwebsockets.org` on port 443 as usual, but also trying
+`ssh -p 443 [email protected]`... you will get permission denied from
+your ssh client.  With valid credentials in fact that works perfectly for
+ssh, scp, git-over-ssh etc all on port 443...
+

+ 176 - 0
Source/ThirdParty/libwebsockets/READMEs/README.jwt.md

@@ -0,0 +1,176 @@
+# JWT support in lws
+
+lws supports the common usage scenarios of JWS (signed) JWT generation,
+parsing and transferring in and out as http cookies.  Care is taken to provide
+helpers that implement the current security best practices for cookie handling
+and JWT validation.  All of the common algorithms like ES512 are supported
+along with JWK generation and handling apis.
+
+The build options needed are `-DLWS_WITH_JOSE=1` `-DLWS_WITH_GENCRYPTO=1`.
+
+Underlying JOSE primitives are exposed as apis, some JWT specific primitives
+and finally a JWT-via http cookie level creation apis each building on top of
+what was underneath.
+
+The higher level APIs are provided additionally because they have the most
+opportunity for implementation pitfalls like not validating alg carefully, or
+not using the latest cookie security options; the provided APIs handle that
+centrally for you.  If your needs vary from what the higher level apis are
+doing, you can cut-and-paste out those implementations and create your own
+using the public lower level apis.
+
+## LWS JWT fields
+
+Lws JWT uses mainly well-known fields
+
+Field|Std|Meaning
+---|---|---
+iss|yes|Issuer, typically the domain like "warmcat.com"
+aud|yes|Audience, typically a url path like "https://warmcat.com/sai"
+iat|yes|Unix-time "Issued At"
+nbf|yes|Unix-time "Not Before"
+exp|yes|Unix-time "Expired"
+sub|yes|Subject, eg, a username or user email
+csrf|no|A random 16-char hex token generated with the JWT for use in links specific to the JWT bearer
+ext|no|Application-specific JSON sub-object with whatever fields you need, eg, `"authorization": 1`
+
+## Approach for JWT as session token
+
+Once JWTs are produced, they are autonomous bearer tokens, if they are not kept
+secret between the browser and the site, they will be accepted as evidence for
+having rights to the session from anyone.
+
+Requiring https, and various other cookie hardening techniques make it more
+difficult for them to leak, but it is still necessary to strictly constrain the
+token's validity time, usually to a few tens of minutes or how long it takes a
+user to login and get stuff done on the site in one session.
+
+## CSRF mitigation
+
+Cross Site Request Forgery (CSRF) is a hacking scenario where an authorized
+user with a valid token is tricked into clicking on an external link that
+performs some action with side-effects on the site he has active auth on.  For
+example, he has a cookie that's logged into his bank, and the link posts a form
+to the bank site transferring money to the attacker.
+
+Lws JWT mitigates this possibility by putting a random secret in the generated
+JWT; when the authorized user presents his JWT to generate the page, generated
+links that require auth to perform their actions include the CSRF string from
+that user's current JWT.
+
+When the user clicks those links intentionally, the CSRF string in the link
+matches the CSRF string in the currently valid JWT that was also provided to
+the server along with the click, and all is well.
+
+An attacker does not know the random, ephemeral JWT CSRF secret to include in
+forged links, so the attacker-controlled action gets rejected at the server as
+having used an invalid link.
+
+The checking and link manipulation need to be implemented in user code / JS...
+lws JWT provides the random CSRF secret in the JWT and makes it visible to the
+server when the incoming JWT is processed.
+
+## Need for client tracking of short JWT validity times
+
+Many links or references on pages do not require CSRF strings, only those that
+perform actions with side-effects like deletion or money transfer should need
+protecting this way.
+
+Due to CSRF mitigation, generated pages containing the protected links
+effectively have an expiry time linked to that of the JWT, since only the bearer
+of the JWT used to generate the links on the page can use them; once that
+expires actually nobody can use them and the page contents, which may anyway
+be showing content that only authenticated users can see must be invalidated and
+re-fetched.  Even if the contents are visible without authentication, additional
+UI elements like delete buttons that should only be shown when authenticated
+will wrongly still be shown 
+
+For that reason, the client should be informed by the server along with the
+authentication status, the expiry time of it.  The client should then by itself
+make arrangements to refresh the page when this time is passed,
+either showing an unauthenticated version of the same page if it exists, or by
+redirecting to the site homepage if showing any of the contents required
+authentication.  The user can then log back in using his credientials typically
+stored in the browser's password store and receive a new short-term JWT with a
+new random csrf token along with a new page using the new csrf token in its
+links.
+
+## Considerations for long-lived connections
+
+Once established as authorized, websocket links may be very long-lived and hold
+their authorization state at the server.  Although the browser monitoring the
+JWT reloading the page on auth expiry should mitigate this, an attacker can
+choose to just not do that and have an immortally useful websocket link.
+
+At least for actions on the long-lived connection, it should not only confirm
+the JWT authorized it but that the current time is still before the "exp" time
+in the JWT, this is made available as `expiry_unix_time` in the args struct
+after successful validation.
+
+Ideally the server should close long-lived connections according to their auth
+expiry time.
+
+## JWT lower level APIs
+
+The related apis are in `./include/libwebsockets/lws-jws.h`
+
+### Validation of JWT
+
+```
+int
+lws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk,
+			const char *alg_list, const char *com, size_t len,
+			char *temp, int tl, char *out, size_t *out_len);
+```
+
+### Composing and signing JWT
+
+```
+int
+lws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk,
+		     const char *alg, char *out, size_t *out_len, char *temp,
+		     int tl, const char *format, ...);
+```
+
+## JWT creation and cookie get / set API
+
+Both the validation and signing apis use the same struct to contain their
+aguments.
+
+```
+struct lws_jwt_sign_set_cookie {
+	struct lws_jwk			*jwk;
+	/**< entry: required signing key */
+	const char			*alg;
+	/**< entry: required signing alg, eg, "ES512" */
+	const char 			*iss;
+	/**< entry: issuer name to use */
+	const char			*aud;
+	/**< entry: audience */
+	const char			*cookie_name;
+	/**< entry: the name of the cookie */
+	char				sub[33];
+	/**< sign-entry, validate-exit: subject */
+	const char			*extra_json;
+	/**< sign-entry, validate-exit:
+	 * optional "ext" JSON object contents for the JWT */
+	size_t				extra_json_len;
+	/**< validate-exit:
+	 * length of optional "ext" JSON object contents for the JWT */
+	const char			*csrf_in;
+	/**< validate-entry:
+	 * NULL, or an external CSRF token to check against what is in the JWT */
+	unsigned long			expiry_unix_time;
+	/**< sign-entry: seconds the JWT and cookie may live,
+	 * validate-exit: expiry unix time */
+};
+
+int
+lws_jwt_sign_token_set_http_cookie(struct lws *wsi,
+				   const struct lws_jwt_sign_set_cookie *i,
+				   uint8_t **p, uint8_t *end);
+int
+lws_jwt_get_http_cookie_validate_jwt(struct lws *wsi,
+				     struct lws_jwt_sign_set_cookie *i,
+				     char *out, size_t *out_len);
+```

+ 43 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lifecycle.md

@@ -0,0 +1,43 @@
+# lws lifecycles
+
+## Context
+
+![context lifecycle](/doc-assets/lifecycle-context.png)
+
+## Client wsi
+
+![client wsi](/doc-assets/lifecycle-wsi.png)
+
+## Server wsi
+
+![server wsi](/doc-assets/lifecycle-server-wsi.png)
+
+## role-specific events
+
+role|client|server
+---|---|---
+http COMPLETED|`LWS_CALLBACK_COMPLETED_CLIENT_HTTP`|-
+http RECEIVE|`LWS_CALLBACK_RECEIVE_CLIENT_HTTP`|`LWS_CALLBACK_RECEIVE_HTTP`
+http WRITEABLE|`LWS_CALLBACK_CLIENT_HTTP_WRITEABLE`|`LWS_CALLBACK_HTTP_WRITEABLE`
+http CLOSE|`LWS_CALLBACK_CLOSED_CLIENT_HTTP`|`LWS_CALLBACK_CLOSED_HTTP`
+http BIND|`LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL`|`LWS_CALLBACK_HTTP_BIND_PROTOCOL`
+http DROP|`LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL`|`LWS_CALLBACK_HTTP_DROP_PROTOCOL`
+
+role|client|server
+---|---|---
+ws ESTABLISHED|`LWS_CALLBACK_CLIENT_ESTABLISHED`|`LWS_CALLBACK_ESTABLISHED`
+ws RECEIVE|`LWS_CALLBACK_CLIENT_RECEIVE`|`LWS_CALLBACK_RECEIVE`
+ws WRITEABLE|`LWS_CALLBACK_CLIENT_WRITEABLE`|`LWS_CALLBACK_SERVER_WRITEABLE`
+ws CLOSE|`LWS_CALLBACK_CLIENT_CLOSED`|`LWS_CALLBACK_CLOSED`
+ws BIND|`LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL`|`LWS_CALLBACK_WS_BIND_PROTOCOL`
+ws DROP|`LWS_CALLBACK_WS_CLIENT_DROP_PROTOCOL`|`LWS_CALLBACK_WS_DROP_PROTOCOL`
+
+role|client|server
+---|---|---
+raw ESTABLISHED|`LWS_CALLBACK_RAW_CONNECTED`|`LWS_CALLBACK_RAW_ADOPT`
+raw RECEIVE|`LWS_CALLBACK_RAW_RX`|`LWS_CALLBACK_RAW_RX`
+raw WRITEABLE|`LWS_CALLBACK_RAW_WRITEABLE`|`LWS_CALLBACK_RAW_WRITEABLE`
+raw CLOSE|`LWS_CALLBACK_RAW_CLOSE`|`LWS_CALLBACK_RAW_CLOSE`
+raw BIND|`LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL`|`LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL`
+raw DROP|`LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL`|`LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL`
+

+ 130 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_dll.md

@@ -0,0 +1,130 @@
+# lws_dll Doubly-linked list
+
+## Introduction
+
+Lws supports two kinds of doubly-linked list, `lws_dll` and `lws_dll2`.
+
+Unless memory is at a big premium, or it has to work on lws < v3.2, it's
+best to simply use `lws_dll2`.
+
+![lws_dll overview](../doc-assets/lws_dll.svg)
+
+## How to use
+
+The basics are the same for lws_dll and lws_dll2.
+
+The list objects point only to themselves, and you use the `lws_container_of`
+macro to get a pointer to your struct that contains the list object.  Doing
+it this way
+
+ - the list object does not have to be the first thing in your struct
+ 
+ - your struct can contain multiple list objects and appear on lists belonging
+   to multiple owners simultaenously,
+   
+### lws_dll Minimal example
+
+```
+struct mystruct {
+	....
+	lws_dll list;
+	...
+};
+
+lws_dll owner;
+```
+
+Adding a mystruct to the owner list (...add_tail() works the same way but adds
+to the other end of the list)
+
+```
+	struct mystruct *p;
+	
+	...
+	
+	lws_dll_add_head(&p->list, &owner);
+```
+
+Removing the list object from its owner
+
+```
+	lws_dll2_remove(&p->list, &owner);
+```
+
+If you have a `struct lws_dll *d` pointing to `list` in struct mystruct, you can
+convert it to a `struct mystruct *p` ike this
+
+```
+	struct mystruct *p = lws_container_of(d, struct lws_dll, list);
+```
+
+### lws_dll2 Minimal example
+
+
+```
+struct mystruct {
+	....
+	lws_dll2 list;
+	...
+};
+
+lws_dll2_owner owner;
+```
+
+Adding a mystruct to the owner list (...add_tail() works the same way but adds
+to the other end of the list)
+
+```
+	struct mystruct *p;
+	
+	...
+	
+	lws_dll2_add_head(&p->list, &owner);
+```
+
+Removing the list object from its owner (notice compared to lws_dll, it doesn't
+need to be told the owner)
+
+```
+	lws_dll2_remove(&p->list);
+```
+
+If you have a `struct lws_dll2 *d` pointing to `list` in struct mystruct, you
+can convert it to a `struct mystruct *p` ike this
+
+```
+	struct mystruct *p = lws_container_of(d, struct lws_dll2, list);
+```
+
+## Summary Comparing lws_dll and lws_dll2
+
+ - both offer a doubly-linked list object, and (since v3.2) track both the
+   head and tail in an "list owner" object
+   
+ - both are initalized by memsetting to 0
+
+ - for `lws_dll`, it reuses an `lws_dll` as the "owner", for `lws_dll2`, there's a
+   specific `lws_dll2_owner` structure for that
+   
+ - `lws_dll2_owner` also keeps count of the number of list elements
+ 
+ - `lws_dll2` knows which owner's list it is participating on.  So it can remove
+   itself and update the owner without the caller needing to know its owner.
+   In the case there are several potential owners list objects may be on, this
+   is very convenient.
+
+ - `lws_dll` is simpler and has a smaller footprint (two pointers per entry vs
+   three).  But you have to know the exact list owner to perform operations on
+   it.
+ 
+## apis
+ 
+|function|lws_dll|lws_dll2|
+|---|---|---|
+|add entry at head|`void lws_dll_add_head(struct lws_dll *d, struct lws_dll *phead)`|`void lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
+|add entry at tail|`void lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead);`|`void lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
+|remove entry from its owning list|`void lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead)`|`void lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
+|get owner|(not supported)|`struct lws_dll2_owner * lws_dll2_owner(const struct lws_dll2 *d)`|
+|check if item is detached from any list|`lws_dll_is_detached(struct lws_dll *d, struct lws_dll *phead)|int lws_dll2_is_detached(const struct lws_dll2 *d)`|
+|iterate through items on list|`int lws_dll_foreach_safe(struct lws_dll *phead, void *user, int (*cb)(struct lws_dll *d, void *user))|int lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user, int (*cb)(struct lws_dll2 *d, void *user))`|
+

+ 105 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_plugins.md

@@ -0,0 +1,105 @@
+# lws_plugins
+
+Lws now offers apis to manage your own user plugins with `LWS_WITH_PLUGINS_API`.
+Lws uses these apis internally for protocol plugins and event loop plugins
+if they're selected for build.  But they are also exported for user code to
+use them how you like.
+
+## Creating your plugin export
+
+### Specifying your plugin export type
+
+Lws plugins have a single exported struct with a specified header and a user
+defined remainder.  The public `lws_plugin_header_t` describes the common
+plugin export header, it's defined via libwebsockets.h as
+
+```
+typedef struct lws_plugin_header {
+	const char *name;
+	const char *_class;
+
+	unsigned int api_magic;
+	/* set to LWS_PLUGIN_API_MAGIC at plugin build time */
+
+	/* plugin-class specific superclass data follows */
+} lws_plugin_header_t;
+```
+
+The exported symbol name itself must match the plugin filename, for
+example if the symbol name is `my_plugin`, then the filename of the
+plugin might be `libmyapp-my_plugin.so` or similar... the matching
+part is after the first `-` or `_`, up to the first `.`.  The exact
+details differ by platform but these rules cover the supported
+platforms.  If lws has the filename of the plugin, it can then
+deduce the symbol export it should look for in the plugin.
+
+`name` is a freeform human-readable description for the plugin.
+
+`_class` is shared by your plugins and used to select them from other kinds
+of plugin that may be in the same dir.  So choose a unique name like
+`"myapp xxx plugin"` or whatever shared by all plugins of that class.
+
+`api_magic` is set to `LWS_PLUGIN_API_MAGIC` to detect if the plugin is
+incompatible with the lws plugin apis version.
+
+So for example your plugin type wrapping the header might look like
+
+```
+typedef struct myapp_plugin {
+        lws_plugin_header_t	hdr; /* must be first */
+
+	/* optional extra data like function pointers from your plugin */
+	mytype_t		mymember;
+	/* ... */
+} myapp_plugin_t;
+```
+
+Typically, you will put function pointers to whatever capability your plugin
+class offers as the additional members.
+
+## Building your own plugins
+
+Plugins are built standalone, cmake is recommended but you can do what you want.
+
+The only requirement is the single visible export of the plugin name, eg
+
+```
+const myapp_plugin_t my_plugin = {
+	.hdr = {
+		"my_plugin",
+		"myapp xxx plugin",
+		LWS_PLUGIN_API_MAGIC
+	},
+
+	.mymember	= my_plugin_init,
+	/*...*/
+};
+```
+
+## Bringing in plugins at runtime
+
+Lws provides an api to import plugins into the process space and another to
+remove and destroy plugins.
+
+You can take two approaches depending on what you're doing, either bring in and
+later destroy a whole class of plugins at once, and walk them via a linked-list,
+or bring in and later destroy a single specific plugin from the class by filtering
+on its specific export name.
+
+See `include/libwebsockets/lws-protocols-plugins.h` for documentation.
+
+```
+LWS_VISIBLE LWS_EXTERN int
+lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
+		 const char *_class, const char *filter,
+		 each_plugin_cb_t each, void *each_user);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
+		    void *each_user);
+```
+
+`struct lws_plugin` is a public struct that contains the linked-list of loaded
+plugins and a pointer to its exported header object, so you can walk this
+after loading.
+

+ 98 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_retry.md

@@ -0,0 +1,98 @@
+# `lws_retry_bo_t` client connection management
+
+This struct sets the policy for delays between retries, and for
+how long a connection may be 'idle' before it first tries to
+ping / pong on it to confirm it's up, or drops the connection
+if still idle.
+
+## Retry rate limiting
+
+You can define a table of ms-resolution delays indexed by which
+connection attempt number is ongoing, this is pointed to by
+`.retry_ms_table` with `.retry_ms_table_count` containing the
+count of table entries.
+
+`.conceal_count` is the number of retries that should be allowed
+before informing the parent that the connection has failed.  If it's
+greater than the number of entries in the table, the last entry is
+reused for the additional attempts.
+
+`.jitter_percent` controls how much additional random delay is
+added to the actual interval to be used... this stops a lot of
+devices all synchronizing when they try to connect after a single
+trigger event and DDoS-ing the server.
+
+The struct and apis are provided for user implementations, lws does
+not offer reconnection itself.
+
+## Connection validity management
+
+Lws has a sophisticated idea of connection validity and the need to
+reconfirm that a connection is still operable if proof of validity
+has not been seen for some time.  It concerns itself only with network
+connections rather than streams, for example, it only checks h2
+network connections rather than the individual streams inside (which
+is consistent with h2 PING frames only working at the network stream
+level itself).
+
+Connections may fail in a variety of ways, these include that no traffic
+at all is passing, or, eg, incoming traffic may be received but no
+outbound traffic is making it to the network, and vice versa.  In the
+case that tx is not failing at any point but just isn't getting sent,
+endpoints can potentially kid themselves that since "they are sending"
+and they are seeing RX, the combination means the connection is valid.
+This can potentially continue for a long time if the peer is not
+performing keepalives.
+
+"Connection validity" is proven when one side sends something and later
+receives a response that can only have been generated by the peer
+receiving what was just sent.  This can happen for some kinds of user
+transactions on any stream using the connection, or by sending PING /
+PONG protocol packets where the PONG is only returned for a received PING.
+
+To ensure that the generated traffic is only sent when necessary, user
+code can report for any stream that it has observed a transaction amounting
+to a proof of connection validity using an api.  This resets the timer for
+the associated network connection before the validity is considered
+expired.
+
+`.secs_since_valid_ping` in the retry struct sets the number of seconds since
+the last validity after which lws will issue a protocol-specific PING of some
+kind on the connection.  `.secs_since_valid_hangup` specifies how long lws
+will allow the connection to go without a confirmation of validity before
+simply hanging up on it.
+
+## Defaults
+
+The context defaults to having a 5m valid ping interval and 5m10s hangup interval,
+ie, it'll send a ping at 5m idle if the protocol supports it, and if no response
+validating the connection arrives in another 10s, hang up the connection.
+
+User code can set this in the context creation info and can individually set the
+retry policy per vhost for server connections.  Client connections can set it
+per connection in the client creation info `.retry_and_idle_policy`.
+
+## Checking for h2 and ws
+
+Check using paired minimal examples with the -v flag on one or both sides to get a
+small validity check period set of 3s / 10s
+
+Also give, eg, -d1039 to see info level debug logging
+
+### h2
+
+```
+$ lws-minimal-http-server-h2-long-poll -v
+
+$ lws-minimal-http-client -l -v
+```
+
+### ws
+
+```
+$ lws-minimal-ws-server-h2 -s -v
+
+$ lws-minimal-ws-client-ping -n --server 127.0.0.1 --port 7681 -v
+```
+
+

+ 149 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_sequencer.md

@@ -0,0 +1,149 @@
+# `struct lws_sequencer` introduction
+
+Often a single network action like a client GET is just part of a
+larger series of actions, perhaps involving different connections.
+
+Since lws operates inside an event loop, if the outer sequencing
+doesn't, it can be awkward to synchronize these steps with what's
+happening on the network with a particular connection on the event
+loop thread.
+
+![lws_sequencer](/doc-assets/lws_sequencer.svg)
+
+`struct lws_sequencer` provides a generic way to stage multi-step
+operations from inside the event loop.  Because it participates
+in the event loop similar to a wsi, it always operates from the
+service thread context and can access structures that share the
+service thread without locking.  It can also provide its own
+higher-level timeout handling.
+
+Naturally you can have many of them running in the same event
+loop operating independently.
+
+Sequencers themselves bind to a pt (per-thread) service thread,
+by default there's only one of these and it's the same as saying
+they bind to an `lws_context`.  The sequencer callback may create
+wsi which in turn are bound to a vhost, but the sequencer itself
+is above all that.
+
+## Sequencer timeouts
+
+The sequencer additionally maintains its own second-resolution timeout
+checked by lws for the step being sequenced... this is independent of
+any lws wsi timeouts which tend to be set and reset for very short-term
+timeout protection inside one transaction.
+
+The sequencer timeout operates separately and above any wsi timeout, and
+is typically only reset by the sequencer callback when it receives an
+event indicating a step completed or failed, or it sets up the next sequence
+step.
+
+If the sequencer timeout expires, then the sequencer receives a queued
+`LWSSEQ_TIMED_OUT` message informing it, and it can take corrective action
+or schedule a retry of the step.  This message is queued and sent normally
+under the service thread context and in order of receipt.
+
+Unlike lws timeouts which force the wsi to close, the sequencer timeout
+only sends the message.  This allows the timeout to be used to, eg, wait
+out a retry cooloff period and then start the retry when the
+`LWSSEQ_TIMED_OUT` is received, according to the state of the sequencer.
+
+## Creating an `struct lws_sequencer`
+
+```
+typedef struct lws_seq_info {
+	struct lws_context		*context;   /* lws_context for seq */
+	int				tsi;	    /* thread service idx */
+	size_t				user_size;  /* size of user alloc */
+	void				**puser;    /* place ptr to user */
+	lws_seq_event_cb		cb;	    /* seq callback */
+	const char			*name;	    /* seq name */
+	const lws_retry_bo_t		*retry;	    /* retry policy */
+} lws_seq_info_t;
+```
+
+```
+struct lws_sequencer *
+lws_sequencer_create(lws_seq_info_t *info);
+```
+
+When created, in lws the sequencer objects are bound to a 'per-thread',
+which is by default the same as to say bound to the `lws_context`.  You
+can tag them with an opaque user data pointer, and they are also bound to
+a user-specified callback which handles sequencer events
+
+```
+typedef int (*lws_seq_event_cb)(struct lws_sequencer *seq, void *user_data,
+				lws_seq_events_t event, void *data);
+```
+
+`struct lws_sequencer` objects are private to lws and opaque to the user.  A small
+set of apis lets you perform operations on the pointer returned by the
+create api.
+
+## Queueing events on a sequencer
+
+Each sequencer object can be passed "events", which are held on a per-sequencer
+queue and handled strictly in the order they arrived on subsequent event loops.
+`LWSSEQ_CREATED` and `LWSSEQ_DESTROYED` events are produced by lws reflecting
+the sequencer's lifecycle, but otherwise the event indexes have a user-defined
+meaning and are queued on the sequencer by user code for eventual consumption
+by user code in the sequencer callback.
+
+Pending events are removed from the sequencer queues and sent to the sequencer
+callback from inside the event loop at a rate of one per event loop wait.
+
+## Destroying sequencers
+
+`struct lws_sequencer` objects are cleaned up during context destruction if they are
+still around.
+
+Normally the sequencer callback receives a queued message that
+informs it that it's either failed at the current step, or succeeded and that
+was the last step, and requests that it should be destroyed by returning
+`LWSSEQ_RET_DESTROY` from the sequencer callback.
+
+## Lifecycle considerations
+
+Sequencers may spawn additional assets like client wsi as part of the sequenced
+actions... the lifecycle of the sequencer and the assets overlap but do not
+necessarily depend on each other... that is a wsi created by the sequencer may
+outlive the sequencer.
+
+It's important therefore to detach assets from the sequencer and the sequencer
+from the assets when each step is over and the asset is "out of scope" for the
+sequencer.  It doesn't necessarily mean closing the assets, just making sure
+pointers are invalidated.  For example, if a client wsi held a pointer to the
+sequencer as its `.user_data`, when the wsi is out of scope for the sequencer
+it can set it to NULL, eg, `lws_set_wsi_user(wsi, NULL);`.
+
+Under some conditions wsi may want to hang around a bit to see if there is a
+subsequent client wsi transaction they can be reused on.  They will clean
+themselves up when they time out.
+
+## Watching wsi lifecycle from a sequencer
+
+When a sequencer is creating a wsi as part of its sequence, it will be very
+interested in lifecycle events.  At client wsi creation time, the sequencer
+callback can set info->seq to itself in order to receive lifecycle messages
+about its wsi.
+
+|message|meaning|
+|---|---|
+|`LWSSEQ_WSI_CONNECTED`|The wsi has become connected|
+|`LWSSEQ_WSI_CONN_FAIL`|The wsi has failed to connect|
+|`LWSSEQ_WSI_CONN_CLOSE`|The wsi had been connected, but has now closed|
+
+By receiving these, the sequencer can understand when it should attempt
+reconnections or that it cannot progress the sequence.
+
+When dealing with wsi that were created by the sequencer, they may close at
+any time, eg, be closed by the remote peer or an intermediary.  The
+`LWSSEQ_WSI_CONN_CLOSE` message may have been queued but since they are
+strictly handled in the order they arrived, before it was
+handled an earlier message may want to cause some api to be called on
+the now-free()-d wsi.  To detect this situation safely, there is a
+sequencer api `lws_sequencer_check_wsi()` which peeks the message
+buffer and returns nonzero if it later contains an `LWSSEQ_WSI_CONN_CLOSE`
+already.
+

+ 38 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_struct.md

@@ -0,0 +1,38 @@
+# lws_struct
+
+## Overview
+
+lws_struct provides a lightweight method for serializing and deserializing C
+structs to and from JSON, and to and from sqlite3.
+
+![lws_struct overview](../doc-assets/lws_struct-overview.svg)
+
+ - you provide a metadata array describing struct members one-time, then call
+   generic apis to serialize and deserialize 
+
+ - supports flat structs, single child struct pointers, and unbounded arrays /
+   linked-lists of child objects automatically using [lws_dll2 linked-lists](./README.lws_dll.md)
+ 
+ - supports boolean and C types char, int, long, long long in explicitly signed
+   and unsigned forms
+ 
+ - supports both char * type string members where the unbounded content is
+   separate and pointed to, and fixed length char array[] type members where
+   the content is part of the struct
+
+ - huge linear strings are supported by storing to a temp lwsac of chained chunks,
+   which is written into a single linear chunk in the main lwsac once the
+   total string length is known
+   
+ - deserialization allocates into an [lwsac](../lib/misc/lwsac/README.md), so everything is inside as few
+   heap allocations as possible while still able to expand to handle arbitrary
+   array or strins sizes
+   
+ - when deserialized structs are finished with, a single call to free the
+   lwsac frees the whole thing without having to walk it
+   
+ - stateful serializaton and deserialization allows as-you-get packets incremental
+   parsing and production of chunks of as-you-can-send incremental serialization
+   output cleanly
+
+## Examples

+ 99 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_sul.md

@@ -0,0 +1,99 @@
+# `lws_sul` scheduler api
+
+Since v3.2 lws no longer requires periodic checking for timeouts and
+other events.  A new system was refactored in where future events are
+scheduled on to a single, unified, sorted linked-list in time order,
+with everything at us resolution.
+
+This makes it very cheap to know when the next scheduled event is
+coming and restrict the poll wait to match, or for event libraries
+set a timer to wake at the earliest event when returning to the
+event loop.
+
+Everything that was checked periodically was converted to use `lws_sul`
+and schedule its own later event.  The end result is when lws is idle,
+it will stay asleep in the poll wait until a network event or the next
+scheduled `lws_sul` event happens, which is optimal for power.
+
+# Side effect for older code
+
+If your older code uses `lws_service_fd()`, it used to be necessary
+to call this with a NULL pollfd periodically to indicate you wanted
+to let the background checks happen.  `lws_sul` eliminates the whole
+concept of periodic checking and NULL is no longer a valid pollfd
+value for this and related apis.
+
+# Using `lws_sul` in user code
+
+See `minimal-http-client-multi` for an example of using the `lws_sul`
+scheduler from your own code; it uses it to spread out connection
+attempts so they are staggered in time.  You must create an
+`lws_sorted_usec_list_t` object somewhere, eg, in you own existing object.
+
+```
+static lws_sorted_usec_list_t sul_stagger;
+```
+
+Create your own callback for the event... the argument points to the sul object
+used when the callback was scheduled.  You can use pointer arithmetic to translate
+that to your own struct when the `lws_sorted_usec_list_t` was a member of the
+same struct.
+
+```
+static void
+stagger_cb(lws_sorted_usec_list_t *sul)
+{
+...
+}
+```
+
+When you want to schedule the callback, use `lws_sul_schedule()`... this will call
+it 10ms in the future
+
+```
+	lws_sul_schedule(context, 0, &sul_stagger, stagger_cb, 10 * LWS_US_PER_MS);
+```
+
+In the case you destroy your object and need to cancel the scheduled callback, use
+
+```
+	lws_sul_schedule(context, 0, &sul_stagger, NULL, LWS_SET_TIMER_USEC_CANCEL);
+```
+
+# lws_sul2 and system suspend
+
+In v4.1, alongside the existing `lws_sul` apis there is a refactor and additional
+functionality aimed at negotiating system suspend, while remaining completely
+backwards-compatible with v3.2+ lws_sul apis.
+
+Devicewide suspend is basically the withdrawal of CPU availability for an unbounded
+amount of time, so what may have been scheduled by the user code may miss its time
+slot because the cpu was down and nothing is getting serviced.  Whether that is
+actively desirable, OK, a big disaster, or a failure that will be corrected at other
+layers at the cost of, eg, some additional latency, depends on the required device
+behaviours and the function of the user code that was scheduled, and its meaning to
+the system.
+
+Before v4.1, lws just offers the same scheduling service for everything both internal
+and arranged by user code, and has no way to know what is critical for the device to
+operate as intended, and so must force wake from suspend, or if for that scheduled
+event 'failure [to get the event] is an option'.
+
+For example locally-initiated periodic keepalive pings not happening may allow
+persistently dead (ie, no longer passing data) connections to remain unrenewed, but
+eventually when suspend ends for another reason, the locally-initiated PING probes
+will resume and it will be discovered and if the connectivity allows, corrected.
+
+If the device's function can handle the latency of there being no connectivity in
+suspend under those conditions until it wakes for another reason, it's OK for these
+kind of timeouts to be suppressed during suspend and basically take the power saving
+instead.  If for a particular device it's intolerable to ever have a silently dead
+connection for more than a very short time compared to suspend durations, then these
+kind of timeouts must have the priority to wake the whole device from suspend so
+they continue to operate unimpeded.
+
+That is just one example, lws offers generic scheduler services the user code can
+exploit for any purpose, including mission-critical ones.  The changes give the user
+code a way to tell lws if a particular scheduled event is important enough to the
+system operation to wake the system from devicewide suspend.
+

+ 219 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lws_system.md

@@ -0,0 +1,219 @@
+# `lws_system`
+
+See `include/libwebsockets/lws-system.h` for function and object prototypes.
+
+## System integration api
+
+`lws_system` allows you to set a `system_ops` struct at context creation time,
+which can write up some function callbacks for system integration.  The goal
+is the user code calls these by getting the ops struct pointer from the
+context using `lws_system_get_ops(context)` and so does not spread system
+dependencies around the user code, making it directly usable on completely
+different platforms.
+
+```
+typedef struct lws_system_ops {
+	int (*reboot)(void);
+	int (*set_clock)(lws_usec_t us);
+	int (*attach)(struct lws_context *context, int tsi, lws_attach_cb_t cb,
+		      lws_system_states_t state, void *opaque,
+		      struct lws_attach_item **get);
+} lws_system_ops_t;
+```
+
+|Item|Meaning|
+|---|---|
+|`(*reboot)()`|Reboot the system|
+|`(*set_clock)()`|Set the system clock|
+|`(*attach)()`|Request an event loop callback from another thread context|
+
+### `reboot`
+
+Reboots the device
+
+### `set_clock`
+
+Set the system clock to us-resolution Unix time in seconds
+
+### `attach`
+
+Request a callback from the event loop from a foreign thread.  This is used, for
+example, for foreign threads to set up their event loop activity in their
+callback, and eg, exit once it is done, with their event loop activity able to
+continue wholly from the lws event loop thread and stack context.
+
+## Foreign thread `attach` architecture
+
+When lws is started, it should define an `lws_system_ops_t` at context creation
+time which defines its `.attach` handler.  In the `.attach` handler
+implementation, it should perform platform-specific locking around a call to
+`__lws_system_attach()`, a public lws api that actually queues the callback
+request and does the main work.  The platform-specific wrapper is just there to
+do the locking so multiple calls from different threads to the `.attach()`
+operation can't conflict.
+
+User code can indicate it wants a callback from the lws event loop like this:
+
+```
+lws_system_get_ops(context)->attach(context, tsi, cb, state, opaque, NULL)
+```
+
+`context` is a pointer to the lws_context, `tsi` is normally 0, `cb` is the user
+callback in the form  
+
+```
+void (*lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque);
+```
+
+`state` is the `lws_system` state we should have reached before performing the
+callback (usually, `LWS_SYSTATE_OPERATIONAL`), and `opaque` is a user pointer that
+will be passed into the callback.
+
+`cb` will normally want to create scheduled events and set up lws network-related
+activity from the event loop thread and stack context.
+
+Once the event loop callback has been booked by calling this api, the thread and
+its stack context that booked it may be freed.  It will be called back and can
+continue operations from the lws event loop thread and stack context.  For that
+reason, if `opaque` is needed it will usually point to something on the heap,
+since the stack context active at the time the callback was booked may be long
+dead by the time of the callback. 
+
+See ./lib/system/README.md for more details.
+
+## `lws_system` blobs
+
+"Blobs" are arbitrary binary objects that have a total length.  Lws lets you set
+them in two ways
+
+ - "directly", by pointing to them, which has no heap implication
+
+ - "heap", by adding one or more arbitrary chunk to a chained heap object
+
+In the "heap" case, it can be incrementally defined and the blob doesn't all
+have to be declared at once.
+
+For read, the same api allows you to read all or part of the blob into a user
+buffer. 
+
+The following kinds of blob are defined 
+
+|Item|Meaning|
+|---|---|
+|`LWS_SYSBLOB_TYPE_AUTH`|Auth-related blob 1, typically a registration token|
+|`LWS_SYSBLOB_TYPE_AUTH + 1`|Auth-related blob 2, typically an auth token|
+|`LWS_SYSBLOB_TYPE_CLIENT_CERT_DER`|Client cert public part|
+|`LWS_SYSBLOB_TYPE_CLIENT_KEY_DER`|Client cert key part|
+|`LWS_SYSBLOB_TYPE_DEVICE_SERIAL`|Arbitrary device serial number|
+|`LWS_SYSBLOB_TYPE_DEVICE_FW_VERSION`|Arbitrary firmware version|
+|`LWS_SYSBLOB_TYPE_DEVICE_TYPE`|Arbitrary Device Type identifier|
+|`LWS_SYSBLOB_TYPE_NTP_SERVER`|String with the ntp server address (defaults to pool.ntp.org)|
+
+### Blob handle api
+
+Returns an object representing the blob for a particular type (listed above)
+
+```
+lws_system_blob_t *
+lws_system_get_blob(struct lws_context *context, lws_system_blob_item_t type,
+                    int idx);
+```
+
+### Blob Setting apis
+
+Sets the blob to point length `len` at `ptr`.  No heap allocation is used.
+
+```
+void
+lws_system_blob_direct_set(lws_system_blob_t *b, const uint8_t *ptr, size_t len);
+```
+
+Allocates and copied `len` bytes from `buf` into heap and chains it on the end of
+any existing.
+
+```
+int
+lws_system_blob_heap_append(lws_system_blob_t *b, const uint8_t *buf, size_t len)
+```
+
+Remove any content from the blob, freeing it if it was on the heap
+
+```
+void
+lws_system_blob_heap_empty(lws_system_blob_t *b)
+```
+
+### Blob getting apis
+
+Get the total size of the blob (ie, if on the heap, the aggreate size of all the
+chunks that were appeneded)
+
+```
+size_t
+lws_system_blob_get_size(lws_system_blob_t *b)
+```
+
+Copy part or all of the blob starting at offset ofs into a user buffer at buf.
+`*len` should be the length of the user buffer on entry, on exit it's set to
+the used extent of `buf`.  This works the same whether the bob is a direct pointer
+or on the heap.
+
+```
+int
+lws_system_blob_get(lws_system_blob_t *b, uint8_t *buf, size_t *len, size_t ofs)
+```
+
+If you know that the blob was handled as a single direct pointer, or a single
+allocation, you can get a pointer to it without copying using this.
+
+```
+int
+lws_system_blob_get_single_ptr(lws_system_blob_t *b, const uint8_t **ptr)
+```
+
+### Blob destroy api
+
+Deallocates any heap allocation for the blob
+
+```
+void
+lws_system_blob_destroy(lws_system_blob_t *b)
+```
+
+
+## System state and notifiers
+
+Lws implements a state in the context that reflects the readiness of the system
+for various steps leading up to normal operation.  By default it acts in a
+backwards-compatible way and directly reaches the OPERATIONAL state just after
+the context is created.
+
+However other pieces of lws, and user, code may define notification handlers
+that get called back when the state changes incrementally, and may veto or delay
+the changes until work necessary for the new state has completed asynchronously.
+
+The generic states defined are:
+
+|State|Meaning|
+|---|---|
+|`LWS_SYSTATE_CONTEXT_CREATED`|The context was just created.|
+|`LWS_SYSTATE_INITIALIZED`|The vhost protocols have been initialized|
+|`LWS_SYSTATE_IFACE_COLDPLUG`|Existing network interfaces have been iterated|
+|`LWS_SYSTATE_DHCP`|Network identity is available|
+|`LWS_SYSTATE_TIME_VALID`|The system knows the time|
+|`LWS_SYSTATE_POLICY_VALID`|If the system needs information about how to act from the net, it has it|
+|`LWS_SYSTATE_REGISTERED`|The device has a registered identity|
+|`LWS_SYSTATE_AUTH1`|The device identity has produced a time-limited access token|
+|`LWS_SYSTATE_AUTH2`|Optional second access token for different services|
+|`LWS_SYSTATE_OPERATIONAL`|The system is ready for user code to work normally|
+|`LWS_SYSTATE_POLICY_INVALID`|All connections are being dropped because policy information is changing.  It will transition back to `LWS_SYSTATE_INITIALIZED` and onward to `OPERATIONAL` again afterwards with the new policy|
+
+### Inserting a notifier
+
+You should create an object `lws_system_notify_link_t` in non-const memory and zero it down.
+Set the `notify_cb` member and the `name` member and then register it using either
+`lws_system_reg_notifier()` or the `.register_notifier_list`
+member of the context creation info struct to make sure it will exist early
+enough to see all events.  The context creation info method takes a list of
+pointers to notify_link structs ending with a NULL entry.
+

+ 702 - 0
Source/ThirdParty/libwebsockets/READMEs/README.lwsws.md

@@ -0,0 +1,702 @@
+Notes about lwsws
+=================
+
+@section lwsws Libwebsockets Web Server
+
+lwsws is an implementation of a very lightweight, ws-capable generic web
+server, which uses libwebsockets to implement everything underneath.
+
+If you are basically implementing a standalone server with lws, you can avoid
+reinventing the wheel and use a debugged server including lws.
+
+
+@section lwswsb Build
+
+Just enable -DLWS_WITH_LWSWS=1 at cmake-time.
+
+It enables libuv and plugin support automatically.
+
+NOTICE on Ubuntu, the default libuv package is called "libuv-0.10".  This is ancient.
+
+You should replace this with libuv1 and libuv1-dev before proceeding.
+
+@section lwswsc Lwsws Configuration
+
+lwsws uses JSON config files, they're pure JSON except:
+
+ - '#' may be used to turn the rest of the line into a comment.
+
+ - There's also a single substitution, if a string contains "_lws_ddir_", then that is
+replaced with the LWS install data directory path, eg, "/usr/share" or whatever was
+set when LWS was built + installed.  That lets you refer to installed paths without
+having to change the config if your install path was different.
+
+There is a single file intended for global settings
+
+/etc/lwsws/conf
+```
+	# these are the server global settings
+	# stuff related to vhosts should go in one
+	# file per vhost in ../conf.d/
+
+	{
+	  "global": {
+	   "username": "apache",
+	   "groupname": "apache",
+	   "count-threads": "1",
+	   "server-string": "myserver v1", # returned in http headers
+	   "ws-pingpong-secs": "200", # confirm idle established ws connections this often
+	   "init-ssl": "yes"
+	 }
+	}
+```
+and a config directory intended to take one file per vhost
+
+/etc/lwsws/conf.d/warmcat.com
+```
+	{
+		"vhosts": [{
+			"name": "warmcat.com",
+			"port": "443",
+			"interface": "eth0",  # optional
+			"host-ssl-key": "/etc/pki/tls/private/warmcat.com.key",  # if given enable ssl
+			"host-ssl-cert": "/etc/pki/tls/certs/warmcat.com.crt",
+			"host-ssl-ca": "/etc/pki/tls/certs/warmcat.com.cer",
+			"mounts": [{  # autoserve
+				"mountpoint": "/",
+				"origin": "file:///var/www/warmcat.com",
+				"default": "index.html"
+			}]
+		}]
+	}
+```
+To get started quickly, an example config reproducing the old test server
+on port 7681, non-SSL is provided.  To set it up
+```
+	# mkdir -p /etc/lwsws/conf.d /var/log/lwsws
+	# cp ./lwsws/etc-lwsws-conf-EXAMPLE /etc/lwsws/conf
+	# cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server
+	# sudo lwsws
+```
+
+@section lwswsacme Using Letsencrypt or other ACME providers
+
+Lws supports automatic provisioning and renewal of TLS certificates.
+
+See ./READMEs/README.plugin-acme.md for examples of how to set it up on an lwsws vhost.
+
+@section lwsogo Other Global Options
+
+ - `reject-service-keywords` allows you to return an HTTP error code and message of your choice
+if a keyword is found in the user agent
+
+```
+   "reject-service-keywords": [{
+        "scumbot": "404 Not Found"
+   }]
+```
+
+ - `timeout-secs` lets you set the global timeout for various network-related
+ operations in lws, in seconds.  It defaults to 5.
+ 
+@section lwswsv Lwsws Vhosts
+
+One server can run many vhosts, where SSL is in use SNI is used to match
+the connection to a vhost and its vhost-specific SSL keys during SSL
+negotiation.
+
+Listing multiple vhosts looks something like this
+```
+	{
+	 "vhosts": [ {
+	     "name": "localhost",
+	     "port": "443",
+	     "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
+	     "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
+	     "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
+	     "mounts": [{
+	       "mountpoint": "/",
+	       "origin": "file:///var/www/libwebsockets.org",
+	       "default": "index.html"
+	       }, {
+	        "mountpoint": "/testserver",
+	        "origin": "file:///usr/local/share/libwebsockets-test-server",
+	        "default": "test.html"
+	       }],
+	     # which protocols are enabled for this vhost, and optional
+	     # vhost-specific config options for the protocol
+	     #
+	     "ws-protocols": [{
+	       "warmcat,timezoom": {
+	         "status": "ok"
+	       }
+	     }]
+	    },
+	    {
+	    "name": "localhost",
+	    "port": "7681",
+	     "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
+	     "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
+	     "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
+	     "mounts": [{
+	       "mountpoint": "/",
+	       "origin": ">https://localhost"
+	     }]
+	   },
+	    {
+	    "name": "localhost",
+	    "port": "80",
+	     "mounts": [{
+	       "mountpoint": "/",
+	       "origin": ">https://localhost"
+	     }]
+	   }
+	
+	  ]
+	}
+```
+
+That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost
+
+
+@section lwswsvn Lwsws Vhost name and port sharing
+
+The vhost name field is used to match on incoming SNI or Host: header, so it
+must always be the host name used to reach the vhost externally.
+
+ - Vhosts may have the same name and different ports, these will each create a
+listening socket on the appropriate port.
+
+ - Vhosts may also have the same port and different name: these will be treated as
+true vhosts on one listening socket and the active vhost decided at SSL
+negotiation time (via SNI) or if no SSL, then after the Host: header from
+the client has been parsed.
+
+
+@section lwswspr Lwsws Protocols
+
+Vhosts by default have available the union of any initial protocols from context creation time, and
+any protocols exposed by plugins.
+
+Vhosts can select which plugins they want to offer and give them per-vhost settings using this syntax
+```
+	     "ws-protocols": [{
+	       "warmcat-timezoom": {
+	         "status": "ok"
+	       }
+	     }]
+```
+
+The "x":"y" parameters like "status":"ok" are made available to the protocol during its per-vhost
+LWS_CALLBACK_PROTOCOL_INIT (in is a pointer to a linked list of struct lws_protocol_vhost_options
+containing the name and value pointers).
+
+To indicate that a protocol should be used when no Protocol: header is sent
+by the client, you can use "default": "1"
+```
+	     "ws-protocols": [{
+	       "warmcat-timezoom": {
+	         "status": "ok",
+	         "default": "1"
+	       }
+	     }]
+```
+
+Similarly, if your vhost is serving a raw protocol, you can mark the protocol
+to be selected using "raw": "1"
+```
+	     "ws-protocols": [{
+	       "warmcat-timezoom": {
+	         "status": "ok",
+	         "raw": "1"
+	       }
+	     }]
+```
+
+See also "apply-listen-accept" below.
+
+@section lwswsovo Lwsws Other vhost options
+
+ - If the three options `host-ssl-cert`, `host-ssl-ca` and `host-ssl-key` are given, then the vhost supports SSL.
+
+ Each vhost may have its own certs, SNI is used during the initial connection negotiation to figure out which certs to use by the server name it's asking for from the request DNS name.
+
+ - `keeplive-timeout` (in secs) defaults to 60 for lwsws, it may be set as a vhost option
+
+ - `interface` lets you specify which network interface to listen on, if not given listens on all.  If the network interface is not usable (eg, ethernet cable out) it will be logged at startup with such vhost not listening, and lws will poll for it and bind a listen socket to the interface if and when it becomes available.
+
+ - "`unix-socket`": "1" causes the unix socket specified in the interface option to be used instead of an INET socket
+
+ - "`unix-socket-perms`": "user:group" allows you to control the unix permissons on the listening unix socket.  It's always get to `0600` mode, but you can control the user and group for the socket fd at creation time.  This allows you to use unix user and groups to control who may open the other end of the unix socket on the local system.
+
+ - "`sts`": "1" causes lwsws to send a Strict Transport Security header with responses that informs the client he should never accept to connect to this address using http.  This is needed to get the A+ security rating from SSL Labs for your server.
+
+ - "`access-log`": "filepath"   sets where apache-compatible access logs will be written
+
+ - `"enable-client-ssl"`: `"1"` enables the vhost's client SSL context, you will need this if you plan to create client conections on the vhost that will use SSL.  You don't need it if you only want http / ws client connections.
+
+ - "`ciphers`": "<cipher list>"  OPENSSL only: sets the allowed list of TLS <= 1.2 ciphers and key exchange protocols for the serving SSL_CTX on the vhost.  The default list is restricted to only those providing PFS (Perfect Forward Secrecy) on the author's Fedora system.
+ 
+ If you need to allow weaker ciphers, you can provide an alternative list here per-vhost.
+
+ - "`client-ssl-ciphers`": "<cipher list>"  OPENSSL only: sets the allowed list of <= TLS1.2 ciphers and key exchange protocols for the client SSL_CTX on the vhost
+
+ - "`tls13-ciphers`": "<cipher list>"  OPENSSL 1.1.1+ only: sets allowed list of TLS1.3+ ciphers and key exchange protocols for the client SSL_CTX on the vhost.  The default is to allow all.
+
+ - "`client-tls13-ciphers`": "<cipher list>"  OPENSSL 1.1.1+ only: sets the allowed list of TLS1.3+ ciphers and key exchange protocols for the client SSL_CTX on the vhost.  The default is to allow all.
+ 
+ - "`ecdh-curve`": "<curve name>"   The default ecdh curve is "prime256v1", but you can override it here, per-vhost
+
+ - "`noipv6`": "on"  Disable ipv6 completely for this vhost
+
+ - "`ipv6only`": "on"  Only allow ipv6 on this vhost / "off" only allow ipv4 on this vhost
+
+ - "`ssl-option-set`": "<decimal>"  Sets the SSL option flag value for the vhost.
+ It may be used multiple times and OR's the flags together.
+ 
+ The values are derived from /usr/include/openssl/ssl.h
+```
+	 # define SSL_OP_NO_TLSv1_1                               0x10000000L
+```
+ 
+ would equate to
+ 
+```
+	 "`ssl-option-set`": "268435456"
+ ```
+ - "`ssl-option-clear'": "<decimal>"   Clears the SSL option flag value for the vhost.
+ It may be used multiple times and OR's the flags together.
+
+ - "`ssl-client-option-set`" and "`ssl-client-option-clear`" work the same way for the vhost Client SSL context
+
+ - "`headers':: [{ "header1": "h1value", "header2": "h2value" }] 
+
+allows you to set arbitrary headers on every file served by the vhost
+
+recommended vhost headers for good client security are
+
+```
+                   "headers": [{
+                        "Content-Security-Policy": "script-src 'self'",
+                        "X-Content-Type-Options": "nosniff",
+                        "X-XSS-Protection": "1; mode=block",
+                        "X-Frame-Options": "SAMEORIGIN"
+                 }]
+
+```
+
+ - "`apply-listen-accept`": "on"  This vhost only serves a non-http protocol, specified in "listen-accept-role" and "listen-accept-protocol"
+
+@section lwswsm Lwsws Mounts
+
+Where mounts are given in the vhost definition, then directory contents may
+be auto-served if it matches the mountpoint.
+
+Mount protocols are used to control what kind of translation happens
+
+ - file://  serve the uri using the remainder of the url past the mountpoint based on the origin directory.
+
+ Eg, with this mountpoint
+```
+	       {
+	        "mountpoint": "/",
+	        "origin": "file:///var/www/mysite.com",
+	        "default": "/"
+	       }
+```
+ The uri /file.jpg would serve /var/www/mysite.com/file.jpg, since / matched.
+
+ - ^http:// or ^https://  these cause any url matching the mountpoint to issue a redirect to the origin url
+
+ - cgi://   this causes any matching url to be given to the named cgi, eg
+```
+	       {
+	        "mountpoint": "/git",
+	        "origin": "cgi:///var/www/cgi-bin/cgit",
+	        "default": "/"
+	       }, {
+	        "mountpoint": "/cgit-data",
+	        "origin": "file:///usr/share/cgit",
+	        "default": "/"
+	       },
+```
+ would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client.
+
+ - http:// or https://  these perform reverse proxying, serving the remote origin content from the mountpoint.  Eg
+
+```
+		{
+		 "mountpoint": "/proxytest",
+		 "origin": "https://libwebsockets.org"
+		}
+```
+
+This will cause your local url `/proxytest` to serve content fetched from libwebsockets.org over ssl; whether it's served from your server using ssl is unrelated and depends how you configured your local server.  Notice if you will use the proxying feature, `LWS_WITH_HTTP_PROXY` is required to be enabled at cmake, and for `https` proxy origins, your lwsws configuration must include `"init-ssl": "1"` and the vhost with the proxy mount must have `"enable-client-ssl": "1"`, even if you are not using ssl to serve.
+
+`/proxytest/abc`, or `/proxytest/abc?def=ghi` etc map to the origin + the part past `/proxytest`, so links and img src urls etc work as do all urls under the origin path.
+
+In addition link and src urls in the document are rewritten so / or the origin url part are rewritten to the mountpoint part.
+
+
+@section lwswsomo Lwsws Other mount options
+
+1) Some protocols may want "per-mount options" in name:value format.  You can
+provide them using "pmo"
+
+	       {
+	        "mountpoint": "/stuff",
+	        "origin": "callback://myprotocol",
+	        "pmo": [{
+	                "myname": "myvalue"
+	        }]
+	       }
+
+2) When using a cgi:// protocol origin at a mountpoint, you may also give cgi environment variables specific to the mountpoint like this
+```
+	       {
+	        "mountpoint": "/git",
+	        "origin": "cgi:///var/www/cgi-bin/cgit",
+	        "default": "/",
+	        "cgi-env": [{
+	                "CGIT_CONFIG": "/etc/cgitrc/libwebsockets.org"
+	        }]
+	       }
+```
+ This allows you to customize one cgi depending on the mountpoint (and / or vhost).
+
+3) It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this
+```
+	"cgi-timeout": "30"
+```
+4) `callback://` protocol may be used when defining a mount to associate a
+named protocol callback with the URL namespace area.  For example
+```
+	       {
+	        "mountpoint": "/formtest",
+	        "origin": "callback://protocol-post-demo"
+	       }
+```
+All handling of client access to /formtest[anything] will be passed to the
+callback registered to the protocol "protocol-post-demo".
+
+This is useful for handling POST http body content or general non-cgi http
+payload generation inside a plugin.
+
+See the related notes in README.coding.md
+
+5) Cache policy of the files in the mount can also be set.  If no
+options are given, the content is marked uncacheable.
+```
+	       {
+	        "mountpoint": "/",
+	        "origin": "file:///var/www/mysite.com",
+	        "cache-max-age": "60",      # seconds
+	        "cache-reuse": "1",         # allow reuse at client at all
+	        "cache-revalidate": "1",    # check it with server each time
+	        "cache-intermediaries": "1" # allow intermediary caches to hold
+	       }
+```
+
+6) You can also define a list of additional mimetypes per-mount
+```
+	        "extra-mimetypes": {
+	                 ".zip": "application/zip",
+	                 ".doc": "text/evil"
+	         }
+```
+
+Normally a file suffix MUST match one of the canned mimetypes or one of the extra
+mimetypes, or the file is not served.  This adds a little bit of security because
+even if there is a bug somewhere and the mount dirs are circumvented, lws will not
+serve, eg, /etc/passwd.
+
+If you provide an extra mimetype entry
+
+			"*": ""
+
+Then any file is served, if the mimetype was not known then it is served without a
+Content-Type: header.
+
+7) A mount can be protected by HTTP Basic Auth.  This only makes sense when using
+https, since otherwise the password can be sniffed.
+
+You can add a `basic-auth` entry on an http mount like this
+
+```
+{
+        "mountpoint": "/basic-auth",
+        "origin": "file://_lws_ddir_/libwebsockets-test-server/private",
+        "basic-auth": "/var/www/balogins-private"
+}
+```
+
+Before serving anything, lws will signal to the browser that a username / password
+combination is required, and it will pop up a dialog.  When the user has filled it
+in, lwsws checks the user:password string against the text file named in the `basic-auth`
+entry.
+
+The file should contain user:pass one per line
+
+```
+testuser:testpass
+myuser:hispass
+```
+
+The file should be readable by lwsws, and for a little bit of extra security not
+have a file suffix, so lws would reject to serve it even if it could find it on
+a mount.
+
+After successful authentication, `WSI_TOKEN_HTTP_AUTHORIZATION` contains the
+authenticated username.
+
+In the case you want to also protect being able to connect to a ws protocol on
+a particular vhost by requiring the http part can authenticate using Basic
+Auth before the ws upgrade, this is also possible.  In this case, the
+"basic-auth": and filepath to the credentials file is passed as a pvo in the
+"ws-protocols" section of the vhost definition.
+
+@section lwswscc Requiring a Client Cert on a vhost
+
+You can make a vhost insist to get a client certificate from the peer before
+allowing the connection with
+
+```
+	"client-cert-required": "1"
+```
+
+the connection will only proceed if the client certificate was signed by the
+same CA as the server has been told to trust.
+
+@section rawconf Configuring Fallback and Raw vhosts
+
+Lws supports some unusual modes for vhost listen sockets, which may be
+configured entirely using the JSON per-vhost config language in the related
+vhost configuration section.
+
+There are three main uses for them
+
+1) A vhost bound to a specific role and protocol, not http.  This binds all
+incoming connections on the vhost listen socket to the "raw-proxy" role and
+protocol "myprotocol".
+
+```
+	"listen-accept-role":		"raw-proxy",
+	"listen-accept-protocol":	"myprotocol",
+	"apply-listen-accept":		"1"
+```
+
+2) A vhost that wants to treat noncompliant connections for http or https as
+   belonging to a secondary fallback role and protocol.  This causes non-https
+   connections to an https listener to stop being treated as https, to lose the
+   tls wrapper, and bind to role "raw-proxy" and protocol "myprotocol".  For
+   example, connect a browser on your external IP :443 as usual and it serves
+   as normal, but if you have configured the raw-proxy to portforward
+   127.0.0.1:22, then connecting your ssh client to your external port 443 will
+   instead proxy your sshd over :443 with no http or tls getting in the way.
+
+```
+	"listen-accept-role":		"raw-proxy",
+	"listen-accept-protocol":	"myprotocol",
+	"fallback-listen-accept":	"1",
+	"allow-non-tls":		"1"
+```
+
+3) A vhost wants to either redirect stray http traffic back to https, or to
+   actually serve http on an https listen socket (this is not recommended
+   since it allows anyone to drop the security assurances of https by
+   accident or design).
+
+```
+	"allow-non-tls":		"1",
+	"redirect-http":		"1",
+```
+
+...or,
+
+```
+	"allow-non-tls":		"1",
+	"allow-http-on-https":		"1",
+```
+
+@section lwswspl Lwsws Plugins
+
+Protcols and extensions may also be provided from "plugins", these are
+lightweight dynamic libraries.  They are scanned for at init time, and
+any protocols and extensions found are added to the list given at context
+creation time.
+
+Protocols receive init (LWS_CALLBACK_PROTOCOL_INIT) and destruction
+(LWS_CALLBACK_PROTOCOL_DESTROY) callbacks per-vhost, and there are arrangements
+they can make per-vhost allocations and get hold of the correct pointer from
+the wsi at the callback.
+
+This allows a protocol to choose to strictly segregate data on a per-vhost
+basis, and also allows the plugin to handle its own initialization and
+context storage.
+
+To help that happen conveniently, there are some new apis
+
+ - lws_vhost_get(wsi)
+ - lws_protocol_get(wsi)
+ - lws_callback_on_writable_all_protocol_vhost(vhost, protocol)
+ - lws_protocol_vh_priv_zalloc(vhost, protocol, size)
+ - lws_protocol_vh_priv_get(vhost, protocol)
+ 
+dumb increment, mirror and status protocol plugins are provided as examples.
+
+
+@section lwswsplaplp Additional plugin search paths
+
+Packages that have their own lws plugins can install them in their own
+preferred dir and ask lwsws to scan there by using a config fragment
+like this, in its own conf.d/ file managed by the other package
+```
+	{
+	  "global": {
+	   "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
+	  }
+	}
+```
+
+@section lwswsssp lws-server-status plugin
+
+One provided protocol can be used to monitor the server status.
+
+Enable the protocol like this on a vhost's ws-protocols section
+```
+	       "lws-server-status": {
+	         "status": "ok",
+	         "update-ms": "5000"
+	       }
+```
+`"update-ms"` is used to control how often updated JSON is sent on a ws link.
+
+And map the provided HTML into the vhost in the mounts section
+```
+	       {
+	        "mountpoint": "/server-status",
+	        "origin": "file:///usr/local/share/libwebsockets-test-server/server-status",
+	        "default": "server-status.html"
+	       }
+```
+You might choose to put it on its own vhost which has "interface": "lo", so it's not
+externally visible, or use the Basic Auth support to require authentication to
+access it.
+
+`"hide-vhosts": "{0 | 1}"` lets you control if information about your vhosts is included.
+Since this includes mounts, you might not want to leak that information, mount names,
+etc.
+
+`"filespath":"{path}"` lets you give a server filepath which is read and sent to the browser
+on each refresh.  For example, you can provide server temperature information on most
+Linux systems by giving an appropriate path down /sys.
+
+This may be given multiple times.
+
+
+@section lwswsreload Lwsws Configuration Reload
+
+You may send lwsws a `HUP` signal, by, eg
+
+```
+$ sudo killall -HUP lwsws
+```
+
+This causes lwsws to "deprecate" the existing lwsws process, and remove and close all of
+its listen sockets, but otherwise allowing it to continue to run, until all
+of its open connections close.
+
+When a deprecated lwsws process has no open connections left, it is destroyed
+automatically.
+
+After sending the SIGHUP to the main lwsws process, a new lwsws process, which can
+pick up the newly-available listen sockets, and use the current configuration
+files, is automatically started.
+
+The new configuration may differ from the original one in arbitrary ways, the new
+context is created from scratch each time without reference to the original one.
+
+Notes
+
+1) Protocols that provide a "shared world" like mirror will have as many "worlds"
+as there are lwsws processes still active.  People connected to a deprecated lwsws
+process remain connected to the existing peers.
+
+But any new connections will apply to the new lwsws process, which does not share
+per-vhost "shared world" data with the deprecated process.  That means no new
+connections on the deprecated context, ie a "shrinking world" for those guys, and a
+"growing world" for people who connect after the SIGHUP.
+
+2) The new lwsws process owes nothing to the previous one.  It starts with fresh
+plugins, fresh configuration, fresh root privileges if that how you start it.
+
+The plugins may have been updated in arbitrary ways including struct size changes
+etc, and lwsws or lws may also have been updated arbitrarily.
+
+3) A root parent process is left up that is not able to do anything except
+respond to SIGHUP or SIGTERM.  Actual serving and network listening etc happens
+in child processes which use the privileges set in the lwsws config files.
+
+@section lwswssysd Lwsws Integration with Systemd
+
+lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service`
+```
+[Unit]
+Description=Libwebsockets Web Server
+After=syslog.target
+
+[Service]
+ExecStart=/usr/local/bin/lwsws 
+ExecReload=/usr/bin/killall -s SIGHUP lwsws ; sleep 1 ; /usr/local/bin/lwsws
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
+```
+
+You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service`
+
+
+@section lwswslr Lwsws Integration with logrotate
+
+For correct operation with logrotate, `/etc/logrotate.d/lwsws` (if that's
+where we're putting the logs) should contain
+```
+	/var/log/lwsws/*log {
+	    copytruncate
+	    missingok
+	    notifempty
+	    delaycompress
+	}
+```
+You can find this prepared in `/lwsws/etc-logrotate.d-lwsws`
+
+Prepare the log directory like this
+
+```
+	sudo mkdir /var/log/lwsws
+	sudo chmod 700 /var/log/lwsws
+```
+
+@section lwswsgdb Debugging lwsws with gdb
+
+Hopefully you won't need to debug lwsws itself, but you may want to debug your plugins.  start lwsws like this to have everything running under gdb
+
+```
+sudo gdb -ex "set follow-fork-mode child" -ex "run" --args /usr/local/bin/lwsws
+
+```
+
+this will give nice backtraces in lwsws itself and in plugins, if they were built with symbols.
+
+@section lwswsvgd Running lwsws under valgrind
+
+You can just run lwsws under valgrind as usual and get valid results.  However the results / analysis part of valgrind runs
+after the plugins have removed themselves, this means valgrind backtraces into plugin code is opaque, without
+source-level info because the dynamic library is gone.
+
+There's a simple workaround, use LD_PRELOAD=<plugin.so> before running lwsws, this has the loader bring the plugin
+in before executing lwsws as if it was a direct dependency.  That means it's still mapped until the whole process
+exits after valgtind has done its thing.
+
+

+ 180 - 0
Source/ThirdParty/libwebsockets/READMEs/README.plugin-acme.md

@@ -0,0 +1,180 @@
+lws-acme-client Plugin
+======================
+
+## Introduction
+
+lws-acme-client is a protcol plugin for libwebsockets that implements an
+ACME client able to communicate with let's encrypt and other certificate
+providers.
+
+It implements `tls-sni-01` challenge, and is able to provision tls certificates
+"from thin air" that are accepted by all the major browsers.  It also manages
+re-requesting the certificate when it only has two weeks left to run.
+
+It works with both the OpenSSL and mbedTLS backends.
+
+## Overview for use
+
+You need to:
+
+ - Provide name resolution to the IP with your server, ie, myserver.com needs to
+ resolve to the IP that hosts your server
+
+ - Enable port forwarding / external firewall access to your port, usually 443
+
+ - Enable the "lws-acme-client" plugin on the vhosts you want it to manage
+   certs for
+
+ - Add per-vhost options describing what should be in the certificate
+
+After that the plugin will sort everything else out.
+
+## Example lwsws setup
+
+```
+ "vhosts": [ {
+	"name": 		   "home.warmcat.com",
+	"port":			   "443",
+        "host-ssl-cert":           "/etc/lwsws/acme/home.warmcat.com.crt.pem",
+        "host-ssl-key":            "/etc/lwsws/acme/home.warmcat.com.key.pem",
+        "ignore-missing-cert":     "1",
+	"access-log": 		   "/var/log/lwsws/test-access-log",
+        "ws-protocols": [{
+	  "lws-acme-client": {
+	    "auth-path":	   "/etc/lwsws/acme/auth.jwk",
+	    "cert-path":           "/etc/lwsws/acme/home.warmcat.com.crt.pem",
+	    "key-path":            "/etc/lwsws/acme/home.warmcat.com.key.pem",
+	    "directory-url":       "https://acme-staging.api.letsencrypt.org/directory",
+	    "country":             "TW",
+	    "state":               "Taipei",
+	    "locality":            "Xiaobitan",
+	    "organization":        "Crash Barrier Ltd",
+	    "common-name":         "home.warmcat.com",
+	    "email":               "[email protected]"
+	  },
+	  ...
+```
+
+## Required PVOs
+
+Notice that the `"host-ssl-cert"` and `"host-ssl-key"` entries have the same
+meaning as usual, they point to your certificate and private key.  However
+because the ACME plugin can provision these, you should also mark the vhost with
+`"ignore-missing-cert" : "1"`, so lwsws will ignore what will initially be
+missing certificate / keys on that vhost, and will set about creating the
+necessary certs and keys instead of erroring out.
+
+You must make sure the directories mentioned here exist, lws doesn't create them
+for you.  They should be 0700 root:root, even if you drop lws privileges.
+
+If you are implementing support in code, this corresponds to making sure the
+vhost creating `info.options` has the `LWS_SERVER_OPTION_IGNORE_MISSING_CERT`
+bit set.
+
+Similarly, in code, the each of the per-vhost options shown above can be
+provided in a linked-list of structs at vhost creation time.  See
+`./test-apps/test-server-v2.0.c` for example code for providing pvos.
+
+### auth-path
+
+This is where the plugin will store the auth keys it generated.
+
+### cert-path
+
+Where the plugin will store the certificate file.  Should match `host-ssl-cert`
+that the vhost wants to use.
+
+The path should include at least one 0700 root:root directory.
+
+### key-path
+
+Where the plugin will store the certificate keys.  Again it should match
+`host-ssl-key` the vhost is trying to use.
+
+The path should include at least one 0700 root:root directory.
+
+### directory-url
+
+This defines the URL of the certification server you will get your
+certificates from.  For let's encrypt, they have a "practice" one
+
+ - `https://acme-staging.api.letsencrypt.org/directory`
+
+and they have a "real" one
+
+ - `https://acme-v01.api.letsencrypt.org/directory`
+
+the main difference is the CA certificate for the real one is in most browsers
+already, but the staging one's CA certificate isn't.  The staging server will
+also let you abuse it more in terms of repeated testing etc.
+
+It's recommended you confirm expected operation with the staging directory-url,
+and then switch to the "real" URL.
+
+### common-name
+
+Your server DNS name, like "libwebsockets.org".  The remote ACME server will
+use this to find your server to perform the SNI challenges.
+
+### email
+
+The contact email address for the certificate.
+
+## Optional PVOs
+
+These are not included in the cert by letsencrypt
+
+### country
+
+Two-letter country code for the certificate
+
+### state
+
+State "or province" for the certificate
+
+### locality
+
+Locality for the certificate
+
+### organization
+
+Your company name
+
+## Security / Key storage considerations
+
+The `lws-acme-client` plugin is able to provision and update your certificate
+and keys in an entirely root-only storage environment, even though lws runs
+as a different uid / gid with no privileges to access the storage dir.
+
+It does this by opening and holding two WRONLY fds on "update paths" inside the
+root directory structure for each cert and key it manages; these are the normal
+cert and key paths with `.upd` appended.  If during the time the server is up
+the certs become within two weeks of expiry, the `lws-acme-client` plugin will
+negotiate new certs and write them to the file descriptors.
+
+Next time the server starts, if it sees `.upd` cert and keys, it will back up
+the old ones and copy them into place as the new ones, before dropping privs.
+
+To also handle the long-uptime server case, lws will update the vhost with the
+new certs using in-memory temporary copies of the cert and key after updating
+the cert.
+
+In this way the cert and key live in root-only storage but the vhost is kept up
+to date dynamically with any cert changes as well.
+
+## Multiple vhosts using same cert
+
+In the case you have multiple vhosts using of the same cert, just attach
+the `lws-acme-client` plugin to one instance.  When the cert updates, all the
+vhosts are informed and vhosts using the same filepath to access the cert will
+be able to update their cert.
+
+## Implementation point
+
+You will need to remove the auth keys when switching from OpenSSL to
+mbedTLS.  They will be regenerated automatically.  It's the file at this
+path:
+
+```
+"auth-path":	   "/etc/lwsws/acme/auth.jwk",
+```

+ 249 - 0
Source/ThirdParty/libwebsockets/READMEs/README.plugin-sshd-base.md

@@ -0,0 +1,249 @@
+ssh-base Plugin
+================
+
+## Introduction
+
+lws-ssh-base is a protcol plugin for libwebsockets that implements a
+generic, abstract, ssh server.
+
+ - very small footprint in code and memory, takes up small part of ESP32
+ 
+ - written with security in mind: valgrind and Coverity -clean
+ 
+ - binds to one or more vhosts, that controls listen port(s)
+ 
+ - all IO and settings abstracted through a single "ops" struct from user code
+ 
+ - each instance on a vhost has its own "ops" struct, defining server keys,
+   auth method and functions to implement IO and other operations
+
+ - The plugin has no built-in behaviours like check ~/.ssh/authorized_keys,
+   treat auth usernames as system usernames, or spawn the user's shell.
+   Everything potentially dangerous is left to the user ops code to decide
+   how to handle.  It's NOT like sshd where running it implies it will accept
+   existing keys for any system user, will spawn a shell, etc, unless you
+   implement those parts in the ops callbacks.
+   
+ - The plugin requires extra code around it in the form of the ops struct
+   handlers.  So it's role is something like an abstract base class for an ssh
+   server.  All the crypto, protocol sequencing and state machine are inside,
+   but all the IO except the network connection is outside.
+   
+ - Built as part of libwebsockets, like all plugins may be dynamically loaded
+   at runtime or built statically.  Test app `libwebsockets-test-sshd` provided
+   
+ - Uses hash and RSA functions from either mbedTLS or OpenSSL automatically,
+   according to which library libwebsockets was built for
+
+To maintain its small size, it implements a single "best of breed" crypto for
+the following functions:
+
+|Function|Crypto|
+|---|---|
+|KEX|[email protected]|
+|Server host key|ssh-rsa (4096b)|
+|Encryption|[email protected]|
+|Compression|None|
+
+## License
+
+lws-ssh-base is Free Software, available under libwebsockets' MIT license.
+
+The crypto parts are available elsewhere under a BSD license.  But for
+simplicity the whole plugin is under MIT.
+
+## Generating your own keys
+
+```
+ $ ssh-keygen -t rsa -b 4096 -f mykeys
+```
+
+will ask for a passphrase and generate the private key in `mykeys` and the
+public key in `mykeys.pub`.  If you already have a suitable RSA key you use
+with ssh, you can just use that directly.
+
+lws installs a test keypair in /usr[/local]/share/libwebsockets-test-server
+that the test apps will accept.
+
+## Example code
+
+1) There's a working example app `libwebsockets-test-sshd` included that
+spawns a bash shell when an ssh client authenticates.  The username used on
+the remote ssh has no meaning, it spawns the shell under the credentials of
+"lws-test-sshd" was run under.  It accepts the lws ssh test key which is
+installed into /usr[/local]/share/libwebsockets-test-server.
+
+Start the server like this (it wants root only because the server key is stored
+in /etc)
+
+```
+ $ sudo libwebsockets-test-sshd
+```
+
+Connect to it using the test private key like this
+
+```
+ $ ssh -p 2200 -i /usr/local/share/libwebsockets-test-server/lws-ssh-test-keys [email protected]
+```
+
+2) There's also a working example plugin `lws-sshd-demo` that "subclasses" the
+abstract `lws-ssh-base` plugin to make a protocol which can be used from,
+eg, lwsws.  For an lwsws vhost that listens on port 2222 and responds with
+the lws-sshd-demo ssh server, the related config is:
+
+```
+        {
+                "name": "sshd",
+                "port": "2222",
+                "onlyraw": "1",
+                "ws-protocols": [{
+                        "lws-ssh-base": {
+                                "status": "ok",
+                                "ops-from": "lws-sshd-demo"
+                        },
+                        "lws-sshd-demo": {
+                                "status": "ok",
+                                "raw": "1"
+                        }
+                }]
+        }
+```
+
+
+
+## Integration to other apps
+
+### Step 0: Build and install libwebsockets
+
+For the `libwebsockets-test-sshd` example, you will need CMake options
+`LWS_WITH_CGI`, since it uses lws helpers to spawn a shell.
+
+lws-ssh-base itself doesn't require CGI support in libwebsockets.
+
+### Step 1: make the code available in your app
+
+Include `lws-plugin-ssh-base` in your app, either as a runtime plugin or by using
+the lws static include scheme.
+
+To bring in the whole of the ssh-base plugin
+into your app in one step, statically, just include
+`plugins/ssh-base/include/lws-plugin-sshd-static-build-includes.h`, you can see
+an example of this in `./test-apps/test-sshd.c`.
+
+### Step 2: define your `struct lws_ssh_ops`
+
+`plugins/ssh-base/include/lws-plugin-ssh.h` defines
+`struct lws_ssh_ops` which is used for all customization and integration
+of the plugin per vhost.  Eg,
+
+```
+static const struct lws_ssh_ops ssh_ops = {
+	.channel_create			= ssh_ops_channel_create,
+	.channel_destroy		= ssh_ops_channel_destroy,
+	.tx_waiting			= ssh_ops_tx_waiting,
+	.tx				= ssh_ops_tx,
+	.rx				= ssh_ops_rx,
+	.get_server_key			= ssh_ops_get_server_key,
+	.set_server_key			= ssh_ops_set_server_key,
+	.set_env			= ssh_ops_set_env,
+	.pty_req			= ssh_ops_pty_req,
+	.child_process_io		= ssh_ops_child_process_io,
+	.child_process_terminated	= ssh_ops_child_process_terminated,
+	.exec				= ssh_ops_exec,
+	.shell				= ssh_ops_shell,
+	.is_pubkey_authorized		= ssh_ops_is_pubkey_authorized,
+	.banner				= ssh_ops_banner,
+	.disconnect_reason		= ssh_ops_disconnect_reason,
+	.server_string			= "SSH-2.0-Libwebsockets",
+	.api_version			= 1,
+};
+```
+The `ssh_ops_...()` functions are your implementations for the operations
+needed by the plugin for your purposes.
+
+### Step 3: enable `lws-ssh-base` protocol to a vhost and configure using pvo
+
+A pointer to your struct lws_ssh_ops is passed into the vhost instance of the
+protocol using per-vhost options
+
+```
+static const struct lws_protocol_vhost_options pvo_ssh_ops = {
+	NULL,
+	NULL,
+	"ops",
+	(void *)&ssh_ops
+};
+
+static const struct lws_protocol_vhost_options pvo_ssh = {
+	NULL,
+	&pvo_ssh_ops,
+	"lws-sshd-base",
+	"" /* ignored, just matches the protocol name above */
+};
+
+...
+	info.port = 22;
+	info.options = LWS_SERVER_OPTION_ONLY_RAW;
+	info.vhost_name = "sshd";
+	info.protocols = protocols_sshd;
+	info.pvo = &pvo_ssh;
+
+	vh_sshd = lws_create_vhost(context, &info);
+```
+
+There are two possible pvos supported, "ops", shown above, directly passes the
+ops structure in using the value on the "ops" pvo.
+
+To support other protocols that want to provide ops to lws-ssh-base themselves
+for a particular vhost, you can also provide a pvo `"ops-from"` whose value is
+the name of the protocol also enabled on this vhost, whose protocol ".user"
+pointer points to the ops struct lws-ssh-base should use.
+
+## Integration to other plugins
+
+A worked example of using the abstract `lws-ssh-base` plugin from another
+plugin that provides the ops struct is in `./plugins/protocol_lws_sshd_demo`.
+
+The key points to note
+
+ - the plugin sets the ops struct for the vhost instantiation of `lws-ssh-base`
+ by passing a pointer to the ops struct in its `lws_protocols` struct `user`
+ member.
+ 
+ - the config for the vhost tells `lws-ssh-base` to pick up the ops struct
+ pointer using an "ops-from" pvo that indicates the protocol name.
+ 
+```
+ 			"lws-ssh-base": {
+                                "status": "ok",
+                                "ops-from": "lws-sshd-demo"
+                        },
+```
+
+ - the config for the vhost tells lws this vhost only serves RAW (ie, no http)
+ 
+```
+         {
+                "name": "sshd",
+                "port": "2222",
+                "onlyraw": "1",
+                ...
+```
+
+ - the config for the vhost marks the protocol that uses `lws-ssh-base`, not
+ `lws-ssh-base` itself, as the protocol to be served for raw connections
+
+```
+                        "lws-sshd-demo": {
+                                "status": "ok",
+                                "raw": "1"
+                         ...
+```
+
+## Notes
+
+You can have the vhost it binds to listen on a nonstandard port.  The ssh
+commandline app cane be told to connect to a non-22 port with
+`ssh -p portnum user@hostname`
+
+

+ 60 - 0
Source/ThirdParty/libwebsockets/READMEs/README.porting.md

@@ -0,0 +1,60 @@
+# Guidance for porting to new platform
+
+Where differences existed between the initial POSIX platform for lws and other
+supported platforms like Windows, `lws_plat_...()` apis were added to move
+handling to platform-specific code in `./lib/plat/`.
+
+Depending o which platform is built, different platform-specific implementations
+of these `lws_plat...()` apis get built.
+
+## 1) Prepare the cmake cross-build file if necessary
+
+CMake isolates its settings for cross-build into a separate file, which can be
+used to different cmake projects for the same platform as well.
+
+Find a similar examples already in `./contrib/cross-*` and copy and adapt it
+as needed,
+
+All settings related to toolchain should go in there.  For cross-toolchain,
+the convention is to pass the path to its installed directory in `CROSS_PATH`
+environment variable.
+
+## 2) Copy the closest platform dir in ./lib/plat
+
+Wholesale copy the closest existing platform dir to `/lib/plat/myplatform` and
+rename the files.
+
+Remove stuff specific to the original platform.
+
+## 3) Add a flag in CMakeLists.txt
+
+Cut and paste a flag to select your platform, preferably `LWS_PLAT_MYPLATFORM` or so
+
+## 4) Add a section to force-select and deselect other cmake options based on platform flag
+
+Some options on by default may not make sense on your platform, and others off
+by default may be mandatory.  After the options() section in CMakeLists.txt, you
+can use this kind of structure
+
+```
+	if (LWS_PLAT_MYPLATFORM)
+		set(LWS_WITH_XXXX 0)
+	endif()
+```
+
+to enforce implicit requirements of your platform.  Optional stuff should be set by
+running cmake commandline as usual.
+
+## 5) Add building your platform files into CMakeLists.txt
+
+Add entries in CMakeLists.txt for building stuff in `./lib/plat/myplatform` when
+`LWS_PLAT_MYPLATFORM` is enabled.
+
+## 6) Adapt your copied ./lib/plat/myplatform/ files
+
+You can now do test builds using the cross-build file, your platform flag in
+cmake, and your copied ./lib/plat content... this last part since it was
+copied from another platform will initially be a plentiful source of errors.
+
+You can iteratively build and adapt the platform files.
+

+ 66 - 0
Source/ThirdParty/libwebsockets/READMEs/README.problems.md

@@ -0,0 +1,66 @@
+Debugging problems
+==================
+
+Check it's still a problem with latest lws
+------------------------------------------
+
+Older versions of lws don't attract any new work after they are released
+(see [the release policy](https://libwebsockets.org/git/libwebsockets/tree/READMEs/README.release-policy.md) for details);
+for a while they will get backported bugfixes but that's it.
+
+All new work and bugfixes happen on master branch.
+
+Old, old versions may be convenient for you to use for some reason.  But unless
+you pay for support or have contributed work to lws so we feel we owe you some
+consideration, nobody else has any reason to particularly care about solving
+issues on ancient versions.  Whereas if the problem exists on master, and can be
+reproduced by developers, it usually gets attention, often immediately.
+
+If the problem doesn't exist on master, you can either use master or check also
+the -stable branch of the last released version to see if it was already solved
+there.
+
+Library is a component
+----------------------
+
+As a library, lws is always just a component in a bigger application.
+
+When users have a problem involving lws, what is happening in the bigger
+application is usually critical to understand what is going on (and where the
+solution lies).  Sometimes access to the remote peer like server or client is also
+necessary to provoke the symptom.  Sometimes, the problem is in lws, but
+sometimes the problem is not in lws but in these other pieces.
+
+Many users are able to share their sources, but others decide not to, for
+presumed "commercial advantage" or whatever.  (In any event, it can be painful
+looking through large chunks of someone else's sources for problems when that
+is not the library author's responsibility.)
+
+This makes answering questions like "what is wrong with my code I am not
+going to show you?" or even "what is wrong with my code?" very difficult.
+
+Even if it's clear there is a problem somewhere, it cannot be understood or
+reproduced by anyone else if it needs user code that isn't provided.
+
+The biggest question is, "is this an lws problem actually"?  To solve that
+the best solution is to strip out all or as much user code as possible,
+and see if the problem is still coming.
+
+
+Use the test apps / minimal examples as sanity checks
+-----------------------------------------------------
+
+The test server and client, and any more specifically relevant minimal example
+ are extremely useful for sanity checks and debugging guidance.
+
+ - **test apps work on your platform**, then either
+   - your user code is broken, align it to how the test apps work, or,
+   - something from your code is required to show an lws problem, provide a
+     minimal patch on a test app so it can be reproduced
+     
+ - **test apps break on your platform**, but work on, eg, x86_64, either
+   - toolchain or platform-specific (eg, OS) issue, or
+   - lws platform support issue
+
+ - **test apps break everywhere**
+   - sounds like lws problem, info to reproduce and / or a patch is appreciated

+ 126 - 0
Source/ThirdParty/libwebsockets/READMEs/README.release-policy.md

@@ -0,0 +1,126 @@
+# lws release policy
+
+## How should users consume lws?
+
+The one definitively wrong way to consume lws (or anything else) is "import" some
+version of it into your proprietary tree and think you will stick with that
+forever, perhaps piling cryptic fixes or hacks on top until quite quickly,
+nobody dare think about updating it.
+
+The stable releases go on to a branch like v4.0-stable as described below, over
+time these attract dozens or even hundreds of minor or major fix patches
+backported from master.  So you should not consume tags like v4.0.0 but build
+into your planning that you will need to follow v4.0-stable in order to stay on
+top of known bugs.
+
+And we only backport fixes to the last stable release, although we will make
+exceptions for important fixes.  So after a while, trying to stick with one
+old versions means nobody is providing security fixes on it any more.  So you
+should build into your planning that you will follow lws release upgrades.
+
+If you find problems and create fixes, please upstream them, simplifying your
+life so you can just directly consume the upstream tree with no private changes.
+
+## Master branch
+
+Master branch is the default and all new work happens there.  It's unstable and
+subject to history rewrites, patches moving about and being squashed etc.  In
+terms of it working, it is subject to passing CI tests including a battery of
+runtime tests, so if it is passing CI as it usually is then it's probably in
+usable shape.  See "Why no history on master" below for why it's managed like
+that.
+
+![all work happens on master](../doc-assets/lws-relpol-1.svg)
+
+If you have patches (you are a hero) they should be targeted at master.
+
+To follow such a branch, `git pull` is the wrong tool... the starting point
+of what you currently have may no longer exist remotely due to rearranging the
+patches there.  Instead use a flow like this:
+
+```
+ $ git fetch https://libwebsockets.org/repo/libwebsockets +master:m && git reset --hard m
+```
+
+This fetches current remote master into local branch `m`, and then forces your
+local checkout to exactly match `m`.  This replaces your checked-out tree
+including any of your local changes, so stash those first, or use stgit or so
+to pop them before updating your basis against lws master.
+
+## Stable branches
+
+Master is very useful for coordinating development, and integrating WIP,
+but for distros or integration into large user projects some stability is often
+more desirable than the latest development work.
+
+Periodically, when master seems in good shape and various new developments seem
+to be working, it's copied out into a versioned stable branch, like `v3.0-stable`.
+
+![stable branches are copied from master](../doc-assets/lws-relpol-2.svg)
+
+The initial copy is tagged with, eg, `v3.0.0`.
+
+(At that time, master's logical version is set to "...99", eg, `v3.0.99` so
+version comparisons show that version of master is "later" than any other
+v3.0 version, which will never reach 99 point releases itself, but "earlier"
+than, eg, v3.1.)
+
+## Backport policy
+
+Work continues on master, and as part of that usually bugs are reported and / or
+fixes found that may apply not just to current master, but the version of master
+that was copied to form the last -stable branch.
+
+In that case, the patch may be backported to the last stable branch to also fix
+the bug there.  In the case of refactors or major internal improvements, these
+typically do not get backported.
+
+This applies only to fixes and public API-neutral internal changes to lws... if
+new features were backported or API changes allowed, then there would be
+multiple apis under the same version name and library soname, which is
+madness.
+
+When new stable releases are made, the soname is bumped reflecting the API is
+different than that of previous versions.
+
+![backports from master to stable](../doc-assets/lws-relpol-3.svg)
+
+If there is something you need in a later lws version that is not backported,
+you need to either backport it yourself or use a later lws version.
+Using a more recent version of lws (and contributing fixes and changes so you
+yourself can get them easily as well as contributing for others) is almost
+always the correct way.
+
+## Stable point releases
+
+Periodically fix patches pile up on the -stable branch and are tagged out as
+"point releases".  So if the original stable release was "v3.0.0", the point
+release may be "v3.0.1".
+
+![point releases of stable](../doc-assets/lws-relpol-4.svg)
+
+## Critical fixes
+
+Sometimes a bug is found and fixed that had been hiding for a few versions.
+If the bug has some security dimension or is otherwise important, we may
+backport it to a few recent releases, not just the last one.  This is pretty
+uncommon though.
+
+![backport to multiple stable branches](../doc-assets/lws-relpol-5.svg)
+
+## Why no history on master
+
+Git is a wonderful tool that can be understood to have two main modes of operation,
+merge and rebase that are mutually exclusive.  Most devs only use merge / pull,
+but rebase / fetch is much more flexible.  Running master via rebases allows me to
+dispense with feature branches during development and enables tracking multiple
+in-progress patches in-tree by updating them in place.  If this doesn't make
+sense or seems heretical to you, it's OK I don't need devsplain'ing about it,
+just sit back and enjoy the clean, rapid development results.
+
+Since stable branches don't allow new features, they are run as traditional trees
+with a history, like a one-way pile of patches on top of the original release.  If
+CI shows something is messed up with the latest patch, I will edit it in-place if
+it has only been out for a few hours, but there is no re-ordering or other history
+manipulation.
+

+ 448 - 0
Source/ThirdParty/libwebsockets/READMEs/README.test-apps.md

@@ -0,0 +1,448 @@
+Overview of lws test apps
+=========================
+
+Are you building a client?  You just need to look at the test client
+[libwebsockets-test-client](../test-apps/test-client.c).
+
+If you are building a standalone server, there are three choices, in order of
+preferability.
+
+1) lwsws + protocol plugins
+
+Lws provides a generic web server app that can be configured with JSON
+config files.  https://libwebsockets.org itself uses this method.
+
+With lwsws handling the serving part, you only need to write an lws protocol
+plugin.  See [plugin-standalone](../plugin-standalone) for an example of how
+to do that outside lws itself, using lws public apis.
+
+ $ cmake .. -DLWS_WITH_LWSWS=1
+
+See [README.lwsws.md](../READMEs/README.lwsws.md) for information on how to configure
+lwsws.
+
+NOTE this method implies libuv is used by lws, to provide crossplatform
+implementations of timers, dynamic lib loading etc for plugins and lwsws.
+
+2) Using plugins in code
+
+This method lets you configure web serving in code, instead of using lwsws.
+
+Plugins are still used, but you have a choice whether to dynamically load
+them or statically include them.  In this example, they are dynamically
+loaded.
+
+ $ cmake .. -DLWS_WITH_PLUGINS=1
+
+See, eg, the [test-server](../test-apps/test-server.c)
+
+3) protocols in the server app
+
+This is the original way lws implemented servers, plugins and libuv are not
+required, but without plugins separating the protocol code directly, the
+combined code is all squidged together and is much less maintainable.
+
+This method is still supported in lws but all ongoing and future work is
+being done in protocol plugins only.
+
+You can simply include the plugin contents and have it buit statically into
+your server, just define this before including the plugin source
+
+```
+#define LWS_PLUGIN_STATIC
+```
+
+This gets you most of the advantages without needing dynamic loading +
+libuv.
+
+
+Notes about lws test apps
+=========================
+
+@section tsb Testing server with a browser
+
+If you run [libwebsockets-test-server](../test-apps/test-server.c) and point your browser
+(eg, Chrome) to
+
+	http://127.0.0.1:7681
+
+It will fetch a script in the form of `test.html`, and then run the
+script in there on the browser to open a websocket connection.
+Incrementing numbers should appear in the browser display.
+
+By default the test server logs to both stderr and syslog, you can control
+what is logged using `-d <log level>`, see later.
+
+
+@section tsd Running test server as a Daemon
+
+You can use the -D option on the test server to have it fork into the
+background and return immediately.  In this daemonized mode all stderr is
+disabled and logging goes only to syslog, eg, `/var/log/messages` or similar.
+
+The server maintains a lockfile at `/tmp/.lwsts-lock` that contains the pid
+of the master process, and deletes this file when the master process
+terminates.
+
+To stop the daemon, do
+```
+       $ kill \`cat /tmp/.lwsts-lock\`
+```
+If it finds a stale lock (the pid mentioned in the file does not exist
+any more) it will delete the lock and create a new one during startup.
+
+If the lock is valid, the daemon will exit with a note on stderr that
+it was already running.
+
+@section clicert Testing Client Certs
+
+Here is a very quick way to create a CA, and a client and server cert from it,
+for testing.
+
+```
+$ cp -rp ./scripts/client-ca /tmp
+$ cd /tmp/client-ca
+$ ./create-ca.sh
+$ ./create-server-cert.sh server
+$ ./create-client-cert.sh client
+```
+
+The last step wants an export password, you will need this password again to
+import the p12 format certificate into your browser.
+
+This will get you the following
+
+|name|function|
+|----|--------|
+|ca.pem|Your Certificate Authority cert|
+|ca.key|Private key for the CA cert|
+|client.pem|Client certificate, signed by your CA|
+|client.key|Client private key|
+|client.p12|combined client.pem + client.key in p12 format for browsers|
+|server.pem|Server cert, signed by your CA|
+|server.key|Server private key|
+
+You can confirm yourself the client and server certs are signed by the CA.
+
+```
+ $ openssl verify -verbose -trusted ca.pem server.pem
+ $ openssl verify -verbose -trusted ca.pem client.pem
+```
+
+Import the client.p12 file into your browser.  In FFOX57 it's
+
+ - preferences
+ - Privacy & Security
+ - Certificates | View Certificates
+ - Certificate Manager | Your Certificates | Import...
+ - Enter the password you gave when creating client1.p12
+ - Click OK.
+
+You can then run the test server like this:
+
+```
+ $ libwebsockets-test-server -s -A ca.pem -K server.key -C server.pem -v
+```
+
+When you connect your browser to https://localhost:7681 after accepting the
+selfsigned server cert, your browser will pop up a prompt to send the server
+your client cert (the -v switch enables this).  The server will only accept
+a client cert that has been signed by ca.pem.
+
+@section sssl Using SSL on the server side
+
+To test it using SSL/WSS, just run the test server with
+```
+	$ libwebsockets-test-server --ssl
+```
+and use the URL
+```
+	https://127.0.0.1:7681
+```
+The connection will be entirely encrypted using some generated
+certificates that your browser will not accept, since they are
+not signed by any real Certificate Authority.  Just accept the
+certificates in the browser and the connection will proceed
+in first https and then websocket wss, acting exactly the
+same.
+
+[test-server.c](../test-apps/test-server.c) is all that is needed to use libwebsockets for
+serving both the script html over http and websockets.
+
+@section lwstsdynvhost Dynamic Vhosts
+
+You can send libwebsockets-test-server or libwebsockets-test-server-v2.0 a SIGUSR1
+to toggle the creation and destruction of an identical second vhost on port + 1.
+
+This is intended as a test and demonstration for how to bring up and remove
+vhosts dynamically.
+
+@section unixskt Testing Unix Socket Server support
+
+Start the test server with -U and the path to create the unix domain socket
+
+```
+ $ libwebsockets-test-server -U /tmp/uds
+```
+
+On exit, lws will delete the socket inode.
+
+To test the client side, eg
+
+```
+ $ nc -C -U /tmp/uds -i 30
+```
+
+and type
+
+`GET / HTTP/1.1`
+
+followed by two ENTER.  The contents of test.html should be returned.
+
+@section wscl Testing websocket client support
+
+If you run the test server as described above, you can also
+connect to it using the test client as well as a browser.
+
+```
+	$ libwebsockets-test-client localhost
+```
+
+will by default connect to the test server on localhost:7681
+and print the dumb increment number from the server at the
+same time as drawing random circles in the mirror protocol;
+if you connect to the test server using a browser at the
+same time you will be able to see the circles being drawn.
+
+The test client supports SSL too, use
+
+```
+	$ libwebsockets-test-client localhost --ssl -s
+```
+
+the -s tells it to accept the default self-signed cert from the server,
+otherwise it will strictly fail the connection if there is no CA cert to
+validate the server's certificate.
+
+
+@section choosingts Choosing between test server variations
+
+If you will be doing standalone serving with lws, ideally you should avoid
+making your own server at all, and use lwsws with your own protocol plugins.
+
+The second best option is follow test-server-v2.0.c, which uses a mount to
+autoserve a directory, and lws protocol plugins for ws, without needing any
+user callback code (other than what's needed in the protocol plugin).
+
+For those two options libuv is needed to support the protocol plugins, if
+that's not possible then the other variations with their own protocol code
+should be considered.
+
+@section tassl Testing SSL on the client side
+
+To test SSL/WSS client action, just run the client test with
+```
+	$ libwebsockets-test-client localhost --ssl
+```
+By default the client test applet is set to accept self-signed
+certificates used by the test server, this is indicated by the
+`use_ssl` var being set to `2`.  Set it to `1` to reject any server
+certificate that it doesn't have a trusted CA cert for.
+
+
+@section taping Using the websocket ping utility
+
+libwebsockets-test-ping connects as a client to a remote
+websocket server and pings it like the
+normal unix ping utility.
+```
+	$ libwebsockets-test-ping localhost
+	handshake OK for protocol lws-mirror-protocol
+	Websocket PING localhost.localdomain (127.0.0.1) 64 bytes of data.
+	64 bytes from localhost: req=1 time=0.1ms
+	64 bytes from localhost: req=2 time=0.1ms
+	64 bytes from localhost: req=3 time=0.1ms
+	64 bytes from localhost: req=4 time=0.2ms
+	64 bytes from localhost: req=5 time=0.1ms
+	64 bytes from localhost: req=6 time=0.2ms
+	64 bytes from localhost: req=7 time=0.2ms
+	64 bytes from localhost: req=8 time=0.1ms
+	^C
+	--- localhost.localdomain websocket ping statistics ---
+	8 packets transmitted, 8 received, 0% packet loss, time 7458ms
+	rtt min/avg/max = 0.110/0.185/0.218 ms
+	$
+```
+By default it sends 64 byte payload packets using the 04
+PING packet opcode type.  You can change the payload size
+using the `-s=` flag, up to a maximum of 125 mandated by the
+04 standard.
+
+Using the lws-mirror protocol that is provided by the test
+server, libwebsockets-test-ping can also use larger payload
+sizes up to 4096 is BINARY packets; lws-mirror will copy
+them back to the client and they appear as a PONG.  Use the
+`-m` flag to select this operation.
+
+The default interval between pings is 1s, you can use the -i=
+flag to set this, including fractions like `-i=0.01` for 10ms
+interval.
+
+Before you can even use the PING opcode that is part of the
+standard, you must complete a handshake with a specified
+protocol.  By default lws-mirror-protocol is used which is
+supported by the test server.  But if you are using it on
+another server, you can specify the protocol to handshake with
+by `--protocol=protocolname`
+
+
+@section ta fraggle Fraggle test app
+
+By default it runs in server mode
+```
+	$ libwebsockets-test-fraggle
+	libwebsockets test fraggle
+	(C) Copyright 2010-2011 Andy Green <[email protected]> licensed under MIT
+	 Compiled with SSL support, not using it
+	 Listening on port 7681
+	server sees client connect
+	accepted v06 connection
+	Spamming 360 random fragments
+	Spamming session over, len = 371913. sum = 0x2D3C0AE
+	Spamming 895 random fragments
+	Spamming session over, len = 875970. sum = 0x6A74DA1
+	...
+```
+You need to run a second session in client mode, you have to
+give the `-c` switch and the server address at least:
+```
+	$ libwebsockets-test-fraggle -c localhost
+	libwebsockets test fraggle
+	(C) Copyright 2010-2011 Andy Green <[email protected]> licensed under MIT
+	 Client mode
+	Connecting to localhost:7681
+	denied deflate-stream extension
+	handshake OK for protocol fraggle-protocol
+	client connects to server
+	EOM received 371913 correctly from 360 fragments
+	EOM received 875970 correctly from 895 fragments
+	EOM received 247140 correctly from 258 fragments
+	EOM received 695451 correctly from 692 fragments
+	...
+```
+The fraggle test sends a random number up to 1024 fragmented websocket frames
+each of a random size between 1 and 2001 bytes in a single message, then sends
+a checksum and starts sending a new randomly sized and fragmented message.
+
+The fraggle test client receives the same message fragments and computes the
+same checksum using websocket framing to see when the message has ended.  It
+then accepts the server checksum message and compares that to its checksum.
+
+
+@section taproxy proxy support
+
+The http_proxy environment variable is respected by the client
+connection code for both `ws://` and `wss://`.  It doesn't support
+authentication.
+
+You use it like this
+```
+	$ export http_proxy=myproxy.com:3128
+	$ libwebsockets-test-client someserver.com
+```
+
+@section talog debug logging
+
+By default logging of severity "notice", "warn" or "err" is enabled to stderr.
+
+Again by default other logging is compiled in but disabled from printing.
+
+By default debug logs below "notice" in severity are not compiled in.  To get
+them included, add this option in CMAKE
+
+```
+	$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
+```
+
+If you want to see more detailed debug logs, you can control a bitfield to
+select which logs types may print using the `lws_set_log_level()` api, in the
+test apps you can use `-d <number>` to control this.  The types of logging
+available are (OR together the numbers to select multiple)
+
+ - 1   ERR
+ - 2   WARN
+ - 4   NOTICE
+ - 8   INFO
+ - 16  DEBUG
+ - 32  PARSER
+ - 64  HEADER
+ - 128 EXTENSION
+ - 256 CLIENT
+ - 512 LATENCY
+
+
+@section ws13 Websocket version supported
+
+The final IETF standard is supported for both client and server, protocol
+version 13.
+
+
+@section latency Latency Tracking
+
+Since libwebsockets runs using `poll()` and a single threaded approach, any
+unexpected latency coming from system calls would be bad news.  There's now
+a latency tracking scheme that can be built in with `-DLWS_WITH_LATENCY=1` at
+cmake, logging the time taken for system calls to complete and if
+the whole action did complete that time or was deferred.
+
+You can see the detailed data by enabling logging level 512 (eg, `-d 519` on
+the test server to see that and the usual logs), however even without that
+the "worst" latency is kept and reported to the logs with NOTICE severity
+when the context is destroyed.
+
+Some care is needed interpreting them, if the action completed the first figure
+(in us) is the time taken for the whole action, which may have retried through
+the poll loop many times and will depend on network roundtrip times.  High
+figures here don't indicate a problem.  The figure in us reported after "lat"
+in the logging is the time taken by this particular attempt.  High figures
+here may indicate a problem, or if you system is loaded with another app at
+that time, such as the browser, it may simply indicate the OS gave preferential
+treatment to the other app during that call.
+
+
+@section autobahn Autobahn Test Suite
+
+Lws can be tested against the autobahn websocket fuzzer in both client and
+server modes
+
+1) pip install autobahntestsuite
+
+2) From your build dir:
+
+```
+ $ cmake .. -DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_MINIMAL_EXAMPLES=1 && make
+```
+
+3) ../scripts/autobahn-test.sh
+
+4) In a browser go to the directory you ran wstest in (eg, /projects/libwebsockets)
+
+file:///projects/libwebsockets/build/reports/clients/index.html
+
+to see the results
+
+
+@section autobahnnotes Autobahn Test Notes
+
+1) Two of the tests make no sense for Libwebsockets to support and we fail them.
+
+ - Tests 2.10 + 2.11: sends multiple pings on one connection.  Lws policy is to
+only allow one active ping in flight on each connection, the rest are dropped.
+The autobahn test itself admits this is not part of the standard, just someone's
+random opinion about how they think a ws server should act.  So we will fail
+this by design and it is no problem about RFC6455 compliance.
+
+2) Currently two parts of autobahn are broken and we skip them
+
+https://github.com/crossbario/autobahn-testsuite/issues/71
+ 

+ 50 - 0
Source/ThirdParty/libwebsockets/READMEs/README.udp.md

@@ -0,0 +1,50 @@
+## Using UDP in lws
+
+UDP is supported in lws... the quickest way is to use the api
+`lws_create_adopt_udp()` which returns a wsi bound to the provided
+vhost, protocol, `lws_retry` struct, dns address and port.
+
+The wsi can be treated normally and `lws_write()` used to write on
+it.
+
+## Implementing UDP retries
+
+Retries are important in udp but there's no standardized ack method
+unlike tcp.  Lws allows you to bind an `lws_retry` struct describing
+the policy to the udp wsi, but since one UDP socket may have many
+transactions in flight, the `lws_sul` and `uint16_t` to count the
+retries must live in the user's transaction object like this
+
+```
+...
+	lws_sorted_usec_list_t	sul;
+	uint16_t		retry;
+...
+```
+
+in the `LWS_CALLBACK_RAW_WRITEABLE` callback, before doing the write,
+set up the retry like this
+
+```
+	if (lws_dll2_is_detached(&transaction->sul_write.list) &&
+	    lws_retry_sul_schedule_retry_wsi(wsi, &transaction->sul_write,
+					     transaction_retry_write_cb,
+					     &transaction->retry_count_write)) {
+			/* we have reached the end of our concealed retries */
+		lwsl_warn("%s: concealed retries done, failing\n", __func__);
+		goto retry_conn;
+	}
+```
+
+This manages the retry counter in the transaction object, guards against it wrapping,
+selects the timeout using the policy bound to the wsi, and sets the `lws_sul` in the
+transaction object to call the given callback if the sul time expires.
+
+In the callback, it should simply call `lws_callback_on_writable()` for the udp wsi.
+
+## Simulating packetloss
+
+lws now allows you to set the amount of simulated packetloss on udp rx and tx in
+the context creation info struct, using `.udp_loss_sim_tx_pc` and `.udp_loss_sim_rx_pc`,
+the values are percentages between 0 and 100.  0, the default, means no packetloss.
+

+ 101 - 0
Source/ThirdParty/libwebsockets/READMEs/README.unix-domain-reverse-proxy.md

@@ -0,0 +1,101 @@
+## Unix Domain Sockets Reverse Proxy
+
+### Introduction
+
+lws is able to use a mount to place reverse proxies into the URL space.
+
+These are particularly useful when using Unix Domain Sockets, basically
+files in the server filesystem, to communicate between lws and a separate
+server process and integrate the result into a coherent URL namespace on
+the lws side.  It's also possible to proxy using tcp sockets.
+
+![overview](../doc-assets/http-proxy-overview.svg)
+
+This has the advantage that the actual web server that forwards the
+data from the unix socket owner is in a different process than the server
+that serves on the unix socket.  If it has problems, they do not affect
+the actual public-facing web server.  The unix domain socket server may
+be in a completely different language than the web server.
+
+Compared to CGI, there are no forks to make a connection to the unix
+domain socket server.
+
+### Mount origin format
+
+Unix Domain Sockets are effectively "files" in the server filesystem, and
+are defined by their filepath.  The "server" side that is to be proxied opens
+the socket and listens on it, which creates a file in the server filesystem.
+The socket understands either http or https protocol.
+
+Lws can be told to act as a proxy for that at a mountpoint in the lws vhost
+url space.
+
+If your mount is expressed in C code, then the mount type is LWSMPRO_HTTP or
+LWSMPRO_HTTPS depending on the protocol the unix socket understands, and the
+origin address has the form `+/path/to/unix/socket:/path/inside/mount`.
+
+The + at the start indicates it is a local unix socket we are proxying, and
+the ':' acts as a delimiter for the socket path, since unlike other addresses
+the unix socket path can contain '/' itself.
+
+### Connectivity rules and translations
+
+Onward proxy connections from lws to the Unix Domain Socket happen using
+http/1.1.  That implies `transfer-encoding: chunking` in the case that the
+length of the output is not known beforehand.
+
+Lws takes care of stripping any chunking (which is illegal in h2) and
+translating between h1 and h2 header formats if the return connection is
+actually in http/2.
+
+The h1 onward proxy connection translates the following headers from the return
+connection, which may be h1 or h2:
+
+Header|Function
+---|---
+host|Which vhost
+etag|Information on any etag the client has cached for this URI
+if-modified-since|Information on the freshness of any etag the client has cached for this URI
+accept-language|Which languages the return path client prefers
+accept-encoding|Which compression encodings the client can accept
+cache-control|Information from the return path client about cache acceptability
+x-forwarded-for|The IP address of the return path client
+
+This implies that the proxied connection can
+
+ - return 301 etc to say the return path client's etag is still valid
+
+ - choose to compress using an acceptable content-encoding
+
+The following headers are translated from the headers replied via the onward
+connection (always h1) back to the return path (which may be h1 or h2)
+
+Header|Function
+---|---
+content-length|If present, an assertion of how much payload is expected
+content-type|The mimetype of the payload
+etag|The canonical etag for the content at this URI
+accept-language|This is returned to the return path client because there is no easy way for the return path client to know what it sent originally.  It allows clientside selection of i18n.
+content-encoding|Any compression format on the payload (selected from what the client sent in accept-encoding, if anything)
+cache-control|The onward server's response about cacheability of its payload
+
+### h1 -> h2 conversion
+
+Chunked encoding that may have been used on the outgoing proxy client connection
+is removed for h2 return connections (chunked encoding is illegal for h2).
+
+Headers are converted to all lower-case and hpack format for h2 return connections.
+
+Header and payload proxying is staged according to when the return connection
+(which may be an h2 child stream) is writable.
+
+### Behaviour if unix domain socket server unavailable
+
+If the server that listens on the unix domain socket is down or being restarted,
+lws understands that it couldn't connect to it and returns a clean 503 response
+`HTTP_STATUS_SERVICE_UNAVAILABLE` along with a brief human-readable explanation.
+
+The generated status page produced will try to bring in a stylesheet
+`/error.css`.  This allows you to produce a styled error pages with logos,
+graphics etc.  See [this](https://libwebsockets.org/git/badrepo) for an example of what you can do with it.
+

+ 12 - 0
Source/ThirdParty/libwebsockets/READMEs/README.vulnerability-reporting.md

@@ -0,0 +1,12 @@
+## Vulnerability Reporting
+
+If you become aware of an issue with lws that has a security
+dimension for users, please contact `[email protected]` by
+direct email.
+
+## Procedure for announcing vulnerability fixes
+
+The problem and fixed versions will be announced on the
+libwebsockets mailing list and a note added to the master
+README.md.
+

+ 23 - 0
Source/ThirdParty/libwebsockets/READMEs/mainpage.md

@@ -0,0 +1,23 @@
+##Libwebsockets API introduction
+
+Libwebsockets covers a lot of interesting features for people making embedded servers or clients
+
+ - HTTP(S) serving and client operation
+ - HTTP/2 support for serving and client operation
+ - WS(S) serving and client operation
+ - HTTP(S) apis for file transfer and upload
+ - HTTP 1 + 2 POST form handling (including multipart / file upload)
+ - cookie-based sessions
+ - account management (including registration, email verification, lost pw etc)
+ - strong SSL / TLS  PFS support (A+ on SSLlabs test)
+ - ssh server integration
+ - serving gzipped files directly from inside zip files, without conversion
+ - support for linux, bsd, windows etc... and very small nonlinux targets like ESP32
+
+Please note you just need in include libwebsockets.h.  It includes all the individual
+includes in /usr/include/libwebsockets/ itself.
+
+You can browse by api category <a href="modules.html">here</a>
+
+A collection of READMEs for build, coding, lwsws etc are <a href="pages.html">here</a>
+

+ 65 - 0
Source/ThirdParty/libwebsockets/READMEs/release-checklist

@@ -0,0 +1,65 @@
+Release Checklist
+-----------------
+
+1) non-CI QA
+ 
+ a) valgrind test servers + client + browser
+
+2) soname bump?
+
+ a) We need one if we added / changed / removed apis
+
+  - CMakeLists.txt
+
+   set(SOVERSION "6")
+
+  - scripts/libwebsockets.spec
+
+  -/%{_libdir}/libwebsockets.so.6
+  +/%{_libdir}/libwebsockets.so.7
+
+3) changelog
+
+ a) Add next version tag header.
+
+ b) Classify as
+
+    - NEW
+    - CHANGE
+    - REMOVE
+
+4) main version bump
+
+  - CMakeLists.txt
+
+   set(CPACK_PACKAGE_VERSION_MAJOR "1")
+   set(CPACK_PACKAGE_VERSION_MINOR "6")
+   set(CPACK_PACKAGE_VERSION_PATCH "0")
+
+5) Announce latest version on README.md
+
+6) Make sure all new READMEs and public headers are in libwebsockets.dox
+
+7) signed tag
+
+  git tag -s vX.Y[.Z]
+
+8) git
+
+ a) push
+ 
+ b) final CI check, if fail delete tag, kill pushed tags, restart flow
+
+9) website
+
+ a) update latest tag for release branch
+
+10) post-relase version bump
+
+Bump the PATCH part of the version to 99
+
+-set(CPACK_PACKAGE_VERSION_PATCH "0")
++set(CPACK_PACKAGE_VERSION_PATCH "99")
+
+to reflect it's newer than any stable release but not a new version yet.
+

+ 37 - 0
Source/ThirdParty/libwebsockets/bug_report.md

@@ -0,0 +1,37 @@
+** What version of lws **
+
+"vx.y.z" or "01234567 from master thismorning" etc
+
+If it's much older than last stable release, we will likely suggest you try that or master.
+
+** What platform and arch? **
+
+"Fedora 32 x86_64" or "OSX Catalina" etc
+
+** What parts of lws does it involve? **
+
+dunno / core / client / server
+raw / http / ws / mqtt / other (give me a hint)
+
+** How can I reproduce the problem just using lws code? **
+
+We can't guess your problem especially in your code.  It's great if you can give us a way to
+realize our own failure clearly with a reproducer that uses our own code.
+
+Try to remove your code from the equation by trying the same flow on an lws minimal example and provide a little diff against that. We can find out if it's only on your platform, or only on that version, or only in your code from that quickly, and if something to fix in lws, I can confirm it really is fixed using the same test.
+
+** Describe the bug **
+
+    "fails" --> this word is a red flag you didn't try to debug the issue much... exactly how does it "fail", what evidence is it leaving like logs or return codes or traces?
+    "hangs" --> this word is a red flag you didn't try to debug the issue much... exactly what does it mean, whole device frozen? Spinning 100% cpu? Just idle? Building on fire? Have you tried it via strace or similar if it seems frozen to see what it's doing? Attach a debugger like gdb -p pid and get a backtrace? perf top if Linux to see what it spends its time on.
+    "crashes" --> what happens if you run under valgrind? You know lws is not threadsafe except for lws_cancel_service(), right...
+    "sucks" --> let's discuss you writing a patch to improve whatever it is
+
+** Additional data **
+
+Build problems? Describe the toolchain and paste the warnings / errors.
+
+Crash? Get a usable backtrace by building with `cmake .. -DCMAKE_BUILD_TYPE=DEBUG` and run under gdb, lldb, or valgrind.
+
+Mysterious happenings? Get verbose lws logs by building with `cmake .. -DCMAKE_BUILD_TYPE=DEBUG` and run with `lws_set_log_level(1151, NULL)`, on the example apps they all take a switch like -d1151.
+

+ 629 - 0
Source/ThirdParty/libwebsockets/changelog

@@ -0,0 +1,629 @@
+Changelog
+---------
+
+v4.1.0
+======
+
+ - NEW: travis / appveyor / bintray are replaced by Sai
+   https://libwebsockets.org/sai/ which for lws currently does 193 builds per
+   git push on 16 platforms, all self-hosted.  The homebrew bash scripts used
+   to select Minimal examples are replaced by CTest.  Platforms currently
+   include Fedora/AMD/GCC, Windows/AMD/mingw32, Windows/AMD/mingw64, Android/
+   aarch64/LLVM, esp-idf (on WROVER-KIT and HELTEC physical boards), Fedora/
+   RISCV (on QEMU)/GCC, CentOS8/AMD/GCC, Gentoo/AMD/GCC, Bionic/AMD/GCC,
+   Linkit 7697, Focal/AMD/GCC, Windows (on QEMU)/AMD/MSVC,
+   Focal/aarch64-RPI4/GCC, iOS/aarch64/LLVM and OSX/AMD/LLVM.
+
+ - NEW: The single CMakeLists.txt has been refactored and modernized into smaller
+ CMakeLists.txt in the subdirectory along with the code that is being managed
+ for build by it.  Build options are still listed in the top level as before
+ but the new way is much more maintainable.
+
+ - NEW: event lib support on Unix is now built into dynamically loaded plugins
+ and brought in at runtime, allowing all of the support to be built in
+ isolation without conflicts, and separately packaged with individual
+ dependencies.  See ./READMEs/event-libs.md for details and how to force
+ the old static build into lws method.
+
+ - NEW: Captive Portal Detection.  Lws can determine if the active default
+ route is able to connect to the internet, or is in a captive portal type
+ situation, by trying to connect to a remote server that will respond in an
+ unusual way, like provide a 204.
+
+ - NEW: Secure streams: Support system trust store if it exists
+                        Build on Windows
+			Support lws raw socket protocol in SS
+			Support Unix Domain Socket transport
+
+ - NEW: Windows: Support Unix Domain Sockets same as other platforms
+
+ - NEW: Windows: Build using native pthreads, async dns, ipv6 on MSVC
+
+ - NEW: lws_struct: BLOB support
+
+ - NEW: lws_sul: Now provides two sorted timer domains, a default one as
+ before, and another whose scheduled events are capable to wake the system from suspend
+
+ - NEW: System Message Distribution: lws_smd provides a very lightweight way
+ to pass short messages between subsystems both in RTOS type case where the
+ subsystems are all on the lws event loop, and in the case participants are in
+ different processes, using Secure Streams proxying.   Participants register a bitmap
+ of message classes they care about; if no particpant cares about a particular message,
+ it is rejected at allocation time for the sender, making it cheap to provide messages
+ speculatively.  See lib/system/smd/README.md for full details.
+
+ - NEW: lws_drivers: wrappers for SDK driver abstractions (or actual drivers)
+		 See lib/drivers/README.md, example implementations
+		 minimal-examples/embedded/esp32/esp-wrover-kit
+                     - generic gpio
+		     - generic LED (by name)    lib/drivers/led/README.md
+		     - generic PWM, sophisticated interpolated table
+		                    sequencers with crossfade  
+		     - generic button (by name), with debounce and press classification
+		                       emitting rich SMD click, long-click, double-click,
+				       down, repeat, up JSON messages
+				       lib/drivers/button/README.md
+		     - bitbang i2c on generic gpio (hw support can use same
+		                       abstract API)
+		     - bitbang spi on generic gpio (hw support can use same
+		                       abstract API)
+		     - generic display object, can be wired up to controller
+		                  drivers that hook up by generic i2c or spi,
+				  generic backlight PWM sequencing and
+				  blanking timer support
+		     - generic settings storage: get and set blobs by name
+		     - generic network device: netdev abstract class with
+	                                       WIFI / Ethernet implementations
+					       using underlying SDK APIs;
+					       generic 80211 Scan managements
+					       and credentials handling via
+					       lws_settings
+		     This is the new way to provide embedded platform
+		     functionality that was in the past done like
+		     esp32-factory.  Unlike the old way, the new way has no
+		     native apis in it and can be built on other SDK / SoCs
+		     the same.
+
+ - NEW: Security-aware JWS JWT (JSON Web Tokens) apis are provided on top of the existing
+ JOSE / JWS apis.  All the common algorithms are available along with some
+ high level apis like lws http cookie -> JWT struct -> lws http cookie.
+
+ - REMOVED: esp32-helper and friends used by esp32-factory now lws_drivers
+ exists
+
+ - REMOVED: generic sessions and friends now JWT is provided
+
+v4.0.0
+======
+
+ - NEW: Lws is now under the MIT license, see ./LICENSE for details
+ 
+ - NEW: GLIB native event loop support, lws + gtk example
+
+ - NEW: native lws MQTT client... supports client stream binding like h2 when
+   multiple logical connections are going to the same endpoint over MQTT, they
+   transparently and independently share the one connection + tls tunnel
+ 
+ - NEW: "Secure Streams"... if you are making a device with client connections
+   to the internet or cloud, this allows separation of the communications
+   policy (endpoints, tls cert validation, protocols, etc) from the code, with
+   the goal you can combine streams, change protocols and cloud provision, and
+   reflect that in the device's JSON policy document without having to change
+   any code.
+
+ - NEW: lws_system: New lightweight and efficient Asynchronous DNS resolver
+   implementation for both A and AAAA records, supports recursive (without
+   recursion in code) lookups, caching, and getaddrinfo() compatible results
+   scheme (from cache directly without per-consumer allocation).  Able to
+   perform DNS lookups without introducing latency in the event loop.
+
+ - NEW: lws_system: ntpclient implementation with interface for setting system
+   time via lws_system ops
+ 
+ - NEW: lws_system: dhcpclient implementation
+ 
+ - NEW: Connection validity tracking, autoproduce PING/PONG for protocols that
+   support it if not informed that the connection has passed data in both
+   directions recently enough
+
+ - NEW: lws_retry: standardized exponential backoff and retry timing based
+   around backoff table and lws_sul
+
+ - NEW: there are official public helpers for unaligned de/serialization of all
+   common types, see eh, lws_ser_wu16be() in include/libwebsockets/lws-misc.h
+
+ - NEW: lws_tls_client_vhost_extra_cert_mem() api allows attaching extra certs
+   to a client vhost from DER in memory
+   
+ - NEW: lws_system: generic blobs support passing auth tokens, per-connection
+   client certs etc from platform into lws
+
+ - NEW: public helpers to consume and produce ipv4/6 addresses in a clean way,
+   along with lws_sockaddr46 type now public.  See eg, lws_sockaddr46-based
+   lws_sa46_parse_numeric_address(), lws_write_numeric_address()
+   in include/libwebsockets/lws-network-helper.h
+
+ - Improved client redirect handling, h2 compatibility
+ 
+ - NEW: lwsac: additional features for constant folding support (strings that
+   already are in the lwsac can be pointed to without copying again), backfill
+   (look for gaps in previous chunks that could take a new use size), and
+   lwsac_extend() so last use() can attempt to use more unallocated chunk space
+
+ - NEW: lws_humanize: apis for reporting scalar quanties like 1234 as "1.234KB"
+   with the scaled symbol strings passed in by caller
+
+ - NEW: freertos: support lws_cancel_service() by using UDP pair bound to lo,
+   since it doesn't have logical pipes
+
+ - NEW: "esp32" plat, which implemented freertos plat compatibility on esp32, is
+   renamed to "freertos" plat, targeting esp32 and other freertos platforms
+
+ - NEW: base64 has an additional api supporting stateful decode, where the input
+   is not all in the same place at the same time and can be processed
+   incrementally
+
+ - NEW: lws ws proxy: support RFC8441
+   
+ - NEW: lws_spawn_piped apis: generic support for vforking a process with child
+   wsis attached to its stdin, stdout and stderr via pipes.  When processes are
+   reaped, a specified callback is triggered.  Currently Linux + OSX.
+   
+ - NEW: lws_fsmount apis: Linux-only overlayfs mount and unmount management for
+   aggregating read-only layers with disposable, changeable upper layer fs
+
+ - Improvements for RTOS / small build case bring the footprint of lws v4 below
+   that of v3.1 on ARM 
+   
+ - lws_tokenize: flag specifying # should mark rest of line as comment
+
+ - NEW: minimal example for integrating libasound / alsa via raw file
+
+ - lws_struct: sqlite and json / lejp translation now usable
+
+
+v3.2.0
+======
+
+ - This is the last planned release under LGPLv2+SLE.  It's not planned to be
+   maintained like previous releases, please switch to master for the latest
+   stuff or continue to use v3.1-stable until the next release under the
+   new MIT license.
+
+ - NEW: completely refactored scheduler with a unified, sorted us-resolution
+   linked-list implementation.  All polled checks like timeout are migrated
+   to use the new timers, which also work on the event lib implementations.
+   Faster operation, us-resolution timeouts and generic scheduled callbacks
+   from the event loop.
+
+ - NEW: lws_dsh specialized buffer memory allocator that can borrow space
+   from other cooperating buffers on the same list.
+
+ - NEW: lws_sequencer allows managing multi-connection processes and
+   retries
+
+ - NEW: memory buffer cert support
+
+ - NEW: LWS_WITH_NETWORK in CMake... can be configured without any network-
+   related code at all
+
+ - NEW: builds on QNX 6.5 and SmartOS
+
+ - NEW: JOSE / JWK / JWS / JWE support, for all common ciphers and algs,
+   works on OpenSSL and mbedtls backends
+
+ - NEW: gencrypto now has genaes and genec in addition to genrsa, works
+   on OpenSSL and mbedtls backends
+
+ - NEW: raw_proxy role
+
+ - NEW: Basic Auth works on ws connections
+
+ - CHANGE: REMOVED: LWS_WITH_GENRSA, LWS_WITH_GENHASH, LWS_WITH_GENEC,
+ LWS_WITH_GENAES have all been removed and combined into LWS_WITH_GENCRYPTO
+
+ - CHANGE: REMOVED: LWS_WITH_JWS, LWS_WITH_JWE have been removed and combined
+ into LWS_WITH_JOSE
+
+v3.1.0
+======
+
+ - CHANGE: REMOVED: lws_client_connect() and lws_client_connect_extended()
+   compatibility apis for lws_client_connect_via_info() have been marked as
+   deprecated for several versions and are now removed.  Use
+   lws_client_connect_via_info() directly instead.
+
+ - CHANGE: CMAKE:
+     - LWS_WITH_HTTP2:         now defaults ON
+
+ - CHANGE: Minimal examples updated to use Content Security Policy best
+   practices, using
+   `LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE` vhost
+   option flag and disabling of inline style and scripts.  A side-effect of
+   this is that buffers used to marshal headers have to be prepared to take
+   more content than previously... LWS_RECOMMENDED_MIN_HEADER_SPACE (2048
+   currently) is available for user (and internal) use to logically tie the
+   buffer size to this usecase (and follow future increases).
+
+ - NEW: CMAKE
+     - LWS_FOR_GITOHASHI: sets various cmake options suitable for gitohashi
+     - LWS_WITH_ASAN: for Linux, enable build with ASAN
+
+     Don't forget LWS_WITH_DISTRO_RECOMMENDED, which enables a wide range of lws
+     options suitable for a distro build of the library.
+     
+ - NEW: lws threadpool - lightweight pool of pthreads integrated to lws wsi, with
+   all synchronization to event loop handled internally, queue for excess tasks
+   [threadpool docs](https://libwebsockets.org/git/libwebsockets/tree/lib/misc/threadpool)
+   [threadpool minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/ws-server/minimal-ws-server-threadpool)
+   Cmake config: `-DLWS_WITH_THREADPOOL=1`
+
+ - NEW: libdbus support integrated on lws event loop
+   [lws dbus docs](https://libwebsockets.org/git/libwebsockets/tree/lib/roles/dbus)
+   [lws dbus client minimal examples](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/dbus-client)
+   [lws dbus server minimal examples](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/dbus-server)
+   Cmake config: `-DLWS_ROLE_DBUS=1`
+
+ - NEW: lws allocated chunks (lwsac) - helpers for optimized mass allocation of small
+   objects inside a few larger malloc chunks... if you need to allocate a lot of
+   inter-related structs for a limited time, this removes per-struct allocation
+   library overhead completely and removes the need for any destruction handling
+   [lwsac docs](https://libwebsockets.org/git/libwebsockets/tree/lib/misc/lwsac)
+   [lwsac minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-lwsac)
+   Cmake Config: `-DLWS_WITH_LWSAC=1`
+
+ - NEW: lws tokenizer - helper api for robustly tokenizing your own strings without
+   allocating or adding complexity.  Configurable by flags for common delimiter
+   sets and comma-separated-lists in the tokenizer.  Detects and reports syntax
+   errors.
+   [lws_tokenize docs](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-tokenize.h)
+   [lws_tokenize minimal example / api test](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-lws_tokenize)
+
+ - NEW: lws full-text search - optimized trie generation, serialization,
+   autocomplete suggestion generation and instant global search support extensible
+   to huge corpuses of UTF-8 text while remaining super lightweight on resources.
+   [full-text search docs](https://libwebsockets.org/git/libwebsockets/tree/lib/misc/fts)
+   [full-text search minimal example / api test](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-fts)
+   [demo](https://libwebsockets.org/ftsdemo/)
+   [demo sources](https://libwebsockets.org/git/libwebsockets/tree/plugins/protocol_fulltext_demo.c)
+   Cmake config: `-DLWS_WITH_FTS=1 -DLWS_WITH_LWSAC=1`
+
+ - NEW: gzip + brotli http server-side compression - h1 and h2 automatic advertising
+   of server compression and application to files with mimetypes "text/*",
+   "application/javascript" and "image/svg.xml".
+   Cmake config: `-DLWS_WITH_HTTP_STREAM_COMPRESSION=1`, `-DLWS_WITH_HTTP_BROTLI=1`
+
+ - NEW: managed disk cache - API for managing a directory containing cached files
+   with hashed names, and automatic deletion of LRU files once the cache is
+   above a given limit.
+   [lws diskcache docs](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-diskcache.h)
+   Cmake config: `-DLWS_WITH_DISKCACHE=1`
+
+ - NEW: http reverse proxy - lws mounts support proxying h1 or h2 requests to
+   a local or remote IP, or unix domain socket over h1.  This allows microservice
+   type architectures where parts of the common URL space are actually handled
+   by external processes which may be remote or on the same machine.
+   [lws gitohashi serving](https://libwebsockets.org/git/) is handled this way.
+   CMake config: `-DLWS_WITH_HTTP_PROXY=1`
+   
+ - NEW: lws_buflist - internally several types of ad-hoc malloc'd buffer have
+   been replaced by a new, exported api `struct lws_buflist`.  This allows
+   multiple buffers to be chained and drawn down in strict FIFO order.
+
+ - NEW: In the case of h1 upgrade, the connection header is checked to contain
+   "upgrade".   The vhost flag LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK
+   also causes the Host: header to be confirmed to match the vhost name and
+   listen port.
+   
+ - NEW: If no 404 redirect for `lws_return_http_status()` is specified for the vhost,
+   the status page produced will try to bring in a stylesheet `/error.css`.  This allows
+   you to produce styled 404 or other error pages with logos, graphics etc.  See
+   https://libwebsockets.org/git/badrepo for an example of what you can do with it.
+
+v3.0.0
+======
+
+ - CHANGE: Clients used to call LWS_CALLBACK_CLOSED same as servers...
+   LWS_CALLBACK_CLIENT_CLOSED has been introduced and is called for clients
+   now.
+   
+ - CHANGE: LWS_CALLBACK_CLIENT_CONNECTION_ERROR used to only be directed at
+   protocols[0].  However in many cases, the protocol to bind to was provided
+   at client connection info time and the wsi bound accordingly.  In those
+   cases, CONNECTION_ERROR is directed at the bound protocol, not protcols[0]
+   any more.
+
+ - CHANGE: CMAKE: the following cmake defaults have changed with this version:
+ 
+     - LWS_WITH_ZIP_FOPS:      now defaults OFF
+     - LWS_WITH_RANGES:        now defaults OFF
+     - LWS_WITH_ZLIB:          now defaults OFF
+     - LWS_WITHOUT_EXTENSIONS: now defaults ON
+     
+ - CHANGE: REMOVED: lws_alloc_vfs_file() (read a file to malloc buffer)
+ 
+ - CHANGE: REMOVED: lws_read() (no longer useful outside of lws internals)
+ 
+ - CHANGE: REMOVED: ESP8266... ESP32 is now within the same price range and much
+   more performant
+   
+ - CHANGE: soname bump... don't forget to `ldconfig`
+     
+ - NEW: all event libraries support "foreign" loop integration where lws itself
+   if just a temporary user of the loop unrelated to the actual loop lifecycle.
+   
+   See `minimal-http-server-eventlib-foreign` for example code demonstrating
+   this for all the event libraries.
+   
+   Internal loop in lws is also supported and demonstrated by
+   `minimal-http-server-eventlib`.
+ 
+ - NEW: ws-over-h2 support.  This is a new RFC-on-the-way supported by Chrome
+   and shortly firefox that allows ws connections to be multiplexed back to the
+   server on the same tcp + tls wrapper h2 connection that the html and scripts
+   came in on.  This is hugely faster that discrete connections.
+ 
+ - NEW: UDP socket adoption and related event callbacks
+ 
+ - NEW: Multi-client connection binding, queuing and pipelining support.
+ 
+   Lws detects multiple client connections to the same server and port, and
+   optimizes how it handles them according to the server type and provided
+   flags.  For http/1.0, all occur with individual parallel connections.  For
+   http/1.1, you can enable keepalive pipelining, so the connections occur
+   sequentially on a single network connection.  For http/2, they all occur
+   as parallel streams within a single h2 network connection.
+   
+   See minimal-http-client-multi for example code. 
+   
+ - NEW: High resolution timer API for wsi, get a callback on your wsi with
+   LWS_CALLBACK_TIMER, set and reset the timer with lws_set_timer_usecs(wsi, us)
+   Actual resolution depends on event backend.  Works with all backends, poll,
+   libuv, libevent, and libev.
+   
+ - NEW: Protocols can arrange vhost-protocol instance specific callbacks with
+   second resolution using `lws_timed_callback_vh_protocol()`
+
+ - NEW: ACME client plugin for self-service TLS certificates
+  
+ - NEW: RFC7517 JSON Web Keys RFC7638 JWK thumbprint, and RFC7515 JSON Web
+    signatures support
+  
+ - NEW: lws_cancel_service() now provides a generic way to synchronize events
+   from other threads, which appear as a LWS_CALLBACK_EVENT_WAIT_CANCELLED
+   callback on all protocols.  This is compatible with all the event libraries.
+
+ - NEW: support BSD poll() where changes to the poll wait while waiting are
+   undone.
+
+ - NEW: Introduce generic hash, hmac and RSA apis that operate the same
+   regardless of OpenSSL or mbedTLS tls backend
+  
+ - NEW: Introduce X509 element query api that works the same regardless of
+   OpenSSL or mbedTLS tls backend
+    
+ - NEW: Introduce over 30 "minimal examples" in ./minimal-examples... these
+   replace most of the old test servers
+   
+    - test-echo -> minimal-ws-server-echo and minimal-ws-client-echo
+
+    - test-server-libuv / -libevent / -libev ->
+         minimal-https-server-eventlib / -eventlib-foreign / -eventlib-demos
+
+    - test-server-v2.0 -> folded into all the minimal servers
+
+    - test-server direct http serving -> minimal-http-server-dynamic
+    
+   The minimal examples allow individual standalone build using their own
+   small CMakeLists.txt.
+   
+ - NEW: lws now detects any back-to-back writes that did not go through the
+   event loop inbetween and reports them.  This will flag any possibility of
+   failure rather than wait until the problem happens.
+   
+ - NEW: CMake has LWS_WITH_DISTRO_RECOMMENDED to select features that are
+   appropriate for distros
+   
+ - NEW: Optional vhost URL `error_document_404` if given causes a redirect there
+   instead of serve the default 404 page.
+   
+ - NEW: lws_strncpy() wrapper guarantees NUL in copied string even if it was
+   truncated to fit.
+   
+ - NEW: for client connections, local protocol binding name can be separated
+   from the ws subprotocol name if needed, using .local_protocol_name
+
+ - NEW: Automatic detection of time discontiguities
+   
+ - NEW: Applies TCP_USER_TIMEOUT for Linux tcp keepalive where available
+     
+ - QA: 1600 tests run on each commit in Travis CI, including almost all
+   Autobahn in client and server mode, various h2load tests, h2spec, attack.sh
+   the minimal example selftests and others.
+
+ - QA: fix small warnings introduced on gcc8.x (eg, Fedora 28)
+ 
+ - QA: Add most of -Wextra on gcc (-Wsign-compare, -Wignored-qualifiers,
+   -Wtype-limits, -Wuninitialized)
+   
+ - QA: clean out warnings on windows
+ 
+ - QA: pass all 146 h2spec tests now on strict
+ 
+ - QA: introduce 35 selftests that operate different minimal examples against
+   each other and confirm the results.
+ 
+ - QA: LWS_WITH_MINIMAL_EXAMPLES allows mass build of all relevant minimal-
+   examples with the LWS build, for CI and to make all the example binaries
+   available from the lws build dir ./bin
+ 
+ - REFACTOR: the lws source directory layout in ./lib has been radically
+   improved, and there are now README.md files in selected subdirs with extra
+   documentation of interest to people working on lws itself.
+
+ - REFACTOR: pipelined transactions return to the event loop before starting the
+   next part. 
+ 
+ - REFACTOR: TLS: replace all TLS library constants with generic LWS ones and
+   adapt all the TLS library code to translate to these common ones.
+   
+   Isolated all the tls-related private stuff in `./lib/tls/private.h`, and all
+   the mbedTLS stuff in `./lib/tls/mbedtls` + openSSL stuff in
+   `./lib/tls/openssl`
+   
+ - REFACTOR: the various kinds of wsi possible with lws have been extracted
+   from the main code and isolated into "roles" in `./lib/roles` which
+   communicate with the core code via an ops struct.  Everything related to
+   ah is migrated to the http role.
+   
+   wsi modes are eliminated and replaced by the ops pointer for the role the
+   wsi is performing.  Generic states for wsi are available to control the
+   lifecycle using core code.
+   
+   Adding new "roles" is now much easier with the changes and ops struct to
+   plug into.
+
+ - REFACTOR: reduce four different kinds of buffer management in lws into a
+   generic scatter-gather struct lws_buflist. 
+
+ - REFACTOR: close notifications go through event loop
+
+
+v2.4.0
+======
+
+ - HTTP/2 server support is now mature and usable!  LWS_WITH_HTTP2=1 enables it.
+   Uses ALPN to serve HTTP/2, HTTP/1 and ws[s] connections all from the same
+   listen port seamlessly.  (Requires ALPN-capable OpenSSL 1.1 or mbedTLS).
+
+ - LWS_WITH_MBEDTLS=1 at CMake now builds and works against mbedTLS instead of
+   OpenSSL.  Most things work identically, although on common targets where
+   OpenSSL has acceleration, mbedTLS is many times slower in operation.  However
+   it is a lot smaller codewise.
+   
+ - Generic hash apis introduced that work the same on mbedTLS or OpenSSL backend
+ 
+ - LWS_WITH_PEER_LIMITS tracks IPs across all vhosts and allows restrictions on
+   both the number of simultaneous connections and wsi in use for any single IP
+
+ - lws_ring apis provide a generic single- or multi-tail ringbuffer... mirror
+   protocol now uses this.  Features include ring elements may be sized to fit
+   structs in the ringbuffer, callback when no tail any longer needs an element
+   and it can be deleted, and zerocopy options to write new members directly
+   into the ringbuffer, and use the ringbuffer element by address too.
+ 
+ - abstract ssh 2 server plugin included, with both plugin and standalone
+   demos provided.  You can bind the plugin to a vhost and also serve full-
+   strength ssh from the vhost.  IO from the ssh server is controlled by an
+   "ops" struct of callbacks for tx, rx, auth etc.
+   
+ - Many fixes, cleanups, source refactors and other improvements.
+
+
+v2.3.0
+======
+
+ - ESP32 OpenSSL support for client and server
+
+ - ESP32 4 x WLAN credential slots may be configured
+
+ - Libevent event loop support
+
+ - SOCKS5 proxy support
+
+ - lws_meta protocol for websocket connection multiplexing
+
+ - lws_vhost_destroy() added... allows dynamic removal of listening
+   vhosts.  Vhosts with shared listen sockets adopt the listen socket
+   automatically if the owner is destroyed.
+
+ - IPv6 on Windows
+
+ - Improved CGI handling suitable for general CGI scripting, eg, PHP
+
+ - Convert even the "old style" test servers to use statically included
+   plugin sources
+
+ - LWS_WITH_STATS cmake option dumps resource usage and timing information
+   every few seconds to debug log, including latency information about
+   delay from asking for writeable callback to getting it
+
+ - Large (> 2GB) files may be served
+
+ - LWS_WITH_HTTP_PROXY Cmake option adds proxying mounts
+
+ - Workaround for libev build by disabling -Werror on the test app
+
+ - HTTP2 support disabled since no way to serve websockets on it
+
+
+v2.2.0
+======
+
+Major new features
+
+ - A mount can be protected by Basic Auth... in lwsws it looks like this
+
+ ```
+{
+        "mountpoint": "/basic-auth",
+        "origin": "file://_lws_ddir_/libwebsockets-test-server/private",
+        "basic-auth": "/var/www/balogins-private"
+}
+```
+
+The text file named in `basic-auth` contains user:password information
+one per line.
+
+See README.lwsws.md for more information.
+
+ - RFC7233 RANGES support in lws server... both single and multipart.
+ This allows seeking for multimedia file serving and download resume.
+ It's enabled by default but can be disabled by CMake option.
+
+ - On Linux, lwsws can reload configuration without dropping ongoing
+ connections, when sent a SIGHUP.  The old configuration drops its
+ listen sockets so the new configuration can listen on them.
+ New connections connect to the server instance with the new
+ configuration.  When all old connections eventually close, the old
+ instance automatically exits.  This is equivalent to
+ `systemctl reload apache`
+
+ - New `adopt` api allow adoption including SSL negotiation and
+ for raw sockets and file descriptors.
+
+ - Chunked transfer encoding supported for client and server
+
+ - Adaptations to allow operations inside OPTEE Secure World
+
+ - ESP32 initial port - able to do all test server functions. See
+ README.build.md
+
+ - Serving gzipped files from inside a ZIP file is supported... this
+ includes directly serving the gzipped content if the client
+ indicated it could accept it (ie, almost all browsers) saving
+ bandwidth and time.  For clients that can't accept it, lws
+ automatically decompresses and serves the content in memory-
+ efficient chunks. Only a few hundred bytes of heap are needed
+ to serve any size file from inside the zip.  See README.coding.md
+
+ - RAW file descriptors may now be adopted into the lws event loop,
+ independent of event backend (including poll service).
+ See README.coding.md
+
+ - RAW server socket descriptors may now be enabled on the vhost if
+ the first thing sent on the connection is not a valid http method.
+ The user code can associate these with a specific protocol per
+ vhost, and RAW-specific callbacks appear there for creation, rx,
+ writable and close.  See libwebsockets-test-server-v2.0 for an example.
+ See README.coding.md
+
+ - RAW client connections are now possible using the method "RAW".
+ After connection, the socket is associated to the protocol
+ named in the client connection info and RAW-specific callbacks
+ appear there for creation, rx, writable and close.
+ See libwebsockets-test-client (with raw://) for an example.
+ See README.coding.md
+
+
+(for earlier changelogs, see the tagged releases)

+ 105 - 0
Source/ThirdParty/libwebsockets/cmake-build-debug/DartConfiguration.tcl

@@ -0,0 +1,105 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: /Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets
+BuildDirectory: /Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug
+
+# Where to place the cost data store
+CostDataFile: 
+
+# Site is something like machine.domain, i.e. pragmatic.crd
+Site: Arniss-MBP
+
+# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++
+BuildName: Darwin-cc
+
+# Subprojects
+LabelsForSubprojects: 
+
+# Submission information
+SubmitURL: http://
+
+# Dashboard start time
+NightlyStartTime: 00:00:00 EDT
+
+# Commands for the build/test/submit cycle
+ConfigureCommand: "/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake" "/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets"
+MakeCommand: /Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}" -- -i
+DefaultCTestConfigurationType: Release
+
+# version control
+UpdateVersionOnly: 
+
+# CVS options
+# Default is "-d -P -A"
+CVSCommand: CVSCOMMAND-NOTFOUND
+CVSUpdateOptions: -d -A -P
+
+# Subversion options
+SVNCommand: /usr/bin/svn
+SVNOptions: 
+SVNUpdateOptions: 
+
+# Git options
+GITCommand: /usr/bin/git
+GITInitSubmodules: 
+GITUpdateOptions: 
+GITUpdateCustom: 
+
+# Perforce options
+P4Command: P4COMMAND-NOTFOUND
+P4Client: 
+P4Options: 
+P4UpdateOptions: 
+P4UpdateCustom: 
+
+# Generic update command
+UpdateCommand: 
+UpdateOptions: 
+UpdateType: 
+
+# Compiler info
+Compiler: 
+CompilerVersion: 
+
+# Dynamic analysis (MemCheck)
+PurifyCommand: 
+ValgrindCommand: 
+ValgrindCommandOptions: 
+MemoryCheckType: 
+MemoryCheckSanitizerOptions: 
+MemoryCheckCommand: MEMORYCHECK_COMMAND-NOTFOUND
+MemoryCheckCommandOptions: 
+MemoryCheckSuppressionFile: 
+
+# Coverage
+CoverageCommand: /usr/bin/gcov
+CoverageExtraFlags: -l
+
+# Cluster commands
+SlurmBatchCommand: SLURM_SBATCH_COMMAND-NOTFOUND
+SlurmRunCommand: SLURM_SRUN_COMMAND-NOTFOUND
+
+# Testing options
+# TimeOut is the amount of time in seconds to wait for processes
+# to complete during testing.  After TimeOut seconds, the
+# process will be summarily terminated.
+# Currently set to 25 minutes
+TimeOut: 1500
+
+# During parallel testing CTest will not start a new test if doing
+# so would cause the system load to exceed this value.
+TestLoad: 
+
+UseLaunchers: 
+CurlOptions: 
+# warning, if you add new options here that have to do with submit,
+# you have to update cmCTestSubmitCommand.cxx
+
+# For CTest submissions that timeout, these options
+# specify behavior for retrying the submission
+CTestSubmitRetryDelay: 5
+CTestSubmitRetryCount: 3

+ 471 - 0
Source/ThirdParty/libwebsockets/cmake-build-debug/libwebsockets.cbp

@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6"/>
+	<Project>
+		<Option title="libwebsockets"/>
+		<Option makefile_is_custom="1"/>
+		<Option compiler="clang"/>
+		<Option virtualFolders="CMake Files\;CMake Files\cmake\;CMake Files\lib\;CMake Files\lib\plat\;CMake Files\lib\plat\unix\;CMake Files\lib\core\;CMake Files\lib\misc\;CMake Files\lib\system\;CMake Files\lib\system\smd\;CMake Files\lib\core-net\;CMake Files\lib\roles\;CMake Files\lib\roles\http\;CMake Files\lib\roles\h1\;CMake Files\lib\roles\ws\;CMake Files\lib\roles\raw-skt\;CMake Files\lib\roles\listen\;CMake Files\lib\event-libs\;CMake Files\lib\event-libs\poll\;CMake Files\plugins\;CMake Files\lwsws\;"/>
+		<Build>
+			<Target title="all">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 all"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="install/strip">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 install/strip"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="install/local">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 install/local"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="list_install_components">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 list_install_components"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="rebuild_cache">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 rebuild_cache"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="GENHDR">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 GENHDR"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="dist">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 dist"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="install">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 install"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="test">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 test"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="edit_cache">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 edit_cache"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="Nightly">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 Nightly"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="Continuous">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 Continuous"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="Experimental">
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+				<Option type="4"/>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 Experimental"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="websockets">
+				<Option output="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/libwebsockets.a" prefix_auto="0" extension_auto="0"/>
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib"/>
+				<Option object_output="./"/>
+				<Option type="2"/>
+				<Option compiler="clang"/>
+				<Compiler>
+					<Add option="-DLWS_BUILDING_STATIC"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/include"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/./async-dns"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/smd/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/./compression"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/h1/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/raw-skt/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/listen/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/poll/../poll"/>
+					<Add directory="/usr/local/include"/>
+					<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include"/>
+					<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"/>
+					<Add directory="/System/Library/Frameworks"/>
+					<Add directory="/Library/Frameworks"/>
+				</Compiler>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 websockets"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+			<Target title="websockets/fast">
+				<Option output="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/libwebsockets.a" prefix_auto="0" extension_auto="0"/>
+				<Option working_dir="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib"/>
+				<Option object_output="./"/>
+				<Option type="2"/>
+				<Option compiler="clang"/>
+				<Compiler>
+					<Add option="-DLWS_BUILDING_STATIC"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/include"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/./async-dns"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/smd/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/./compression"/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/h1/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/raw-skt/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/listen/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/."/>
+					<Add directory="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/poll/../poll"/>
+					<Add directory="/usr/local/include"/>
+					<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include"/>
+					<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"/>
+					<Add directory="/System/Library/Frameworks"/>
+					<Add directory="/Library/Frameworks"/>
+				</Compiler>
+				<MakeCommands>
+					<Build command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 websockets/fast"/>
+					<CompileFile command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 &quot;$file&quot;"/>
+					<Clean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 clean"/>
+					<DistClean command="/usr/bin/make -j4 -f &quot;/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lib/Makefile&quot;  VERBOSE=1 clean"/>
+				</MakeCommands>
+			</Target>
+		</Build>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake-build-debug/lws_config.h">
+			<Option target="GENHDR"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/adopt.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/client/client.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/client/connect.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/client/connect2.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/client/connect3.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/client/connect4.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/close.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/dummy-callback.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/network.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/output.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/pollfd.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/sequencer.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/server.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/service.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/sorted-usec-list.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/state.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/vhost.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/wsi-timeout.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/wsi.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/alloc.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/buflist.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/context.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/libwebsockets.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/logs.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/lws_dll2.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/vfs.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/poll/poll.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/base64-decode.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/dir.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/lejp.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/lws-ring.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/lwsac/cached-file.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/lwsac/lwsac.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/sha-1.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-caps.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-fds.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-file.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-init.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-misc.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-pipe.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-service.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/unix-sockets.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/h1/ops-h1.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/client/client-http.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/date.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/header.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/parsers.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/server/lejp-conf.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/server/lws-spa.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/server/server.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/listen/ops-listen.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/pipe/ops-pipe.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/raw-skt/ops-raw-skt.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/client-parser-ws.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/client-ws.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/ops-ws.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/server-ws.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/smd/smd.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/system.c">
+			<Option target="websockets"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/CMakeLists-implied-options.txt">
+			<Option virtualFolder="CMake Files\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake/libwebsockets-config-version.cmake.in">
+			<Option virtualFolder="CMake Files\cmake\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake/libwebsockets-config.cmake.in">
+			<Option virtualFolder="CMake Files\cmake\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake/lws_config.h.in">
+			<Option virtualFolder="CMake Files\cmake\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/cmake/lws_config_private.h.in">
+			<Option virtualFolder="CMake Files\cmake\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/plat/unix/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\plat\unix\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\core\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/misc/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\misc\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\system\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/system/smd/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\system\smd\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/core-net/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\core-net\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/http/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\http\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/h1/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\h1\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/ws/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\ws\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/raw-skt/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\raw-skt\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/roles/listen/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\roles\listen\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\event-libs\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lib/event-libs/poll/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lib\event-libs\poll\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/plugins/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\plugins\"/>
+		</Unit>
+		<Unit filename="/Users/arnislielturks/playground/Urho3D-Original/Source/ThirdParty/libwebsockets/lwsws/CMakeLists.txt">
+			<Option virtualFolder="CMake Files\lwsws\"/>
+		</Unit>
+	</Project>
+</CodeBlocks_project_file>

+ 12 - 0
Source/ThirdParty/libwebsockets/cmake-build-debug/libwebsockets_static.pc

@@ -0,0 +1,12 @@
+prefix="/usr/local"
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libwebsockets_static
+Description: Websockets server and client static library
+Version: 4.1.99-1.8-ALPHA-201-gdc271bf22
+
+Libs: -L${libdir} -lwebsockets_static
+Libs.private:
+Cflags: -I${includedir}

+ 197 - 0
Source/ThirdParty/libwebsockets/cmake-build-debug/lws_config.h

@@ -0,0 +1,197 @@
+/* lws_config.h  Generated from lws_config.h.in  */
+
+#ifndef NDEBUG
+	#ifndef _DEBUG
+		#define _DEBUG
+	#endif
+#endif
+
+#define LWS_INSTALL_DATADIR "/usr/local/share"
+#define LWS_INSTALL_LIBDIR "/usr/local/lib"
+#define LWS_LIBRARY_VERSION_MAJOR 4
+#define LWS_LIBRARY_VERSION_MINOR 1
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 99-1.8-ALPHA-201-gdc271bf22
+#define LWS_LIBRARY_VERSION_PATCH 99
+
+/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
+#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
+					(LWS_LIBRARY_VERSION_MINOR * 1000) + \
+					LWS_LIBRARY_VERSION_PATCH
+#define LWS_MAX_SMP 1
+
+/* #undef LWS_ESP_PLATFORM */
+/* #undef LWS_LIBRARY_VERSION_NUMBER */
+
+/* #undef LWS_EXT_PTHREAD_LIBRARIES */
+
+/* #undef LWS_AVOID_SIGPIPE_IGN */
+#define LWS_BUILD_HASH "1.8-ALPHA-201-gdc271bf22"
+/* #undef LWS_BUILTIN_GETIFADDRS */
+#define LWS_CLIENT_HTTP_PROXYING
+/* #undef LWS_DETECTED_PLAT_IOS */
+/* #undef LWS_FALLBACK_GETHOSTBYNAME */
+#define LWS_HAS_INTPTR_T
+#define LWS_HAS_GETOPT_LONG
+/* #undef LWS_HAVE__ATOI64 */
+#define LWS_HAVE_ATOLL
+/* #undef LWS_HAVE_BN_bn2binpad */
+#define LWS_HAVE_CLOCK_GETTIME
+/* #undef LWS_HAVE_EC_POINT_get_affine_coordinates */
+/* #undef LWS_HAVE_ECDSA_SIG_set0 */
+/* #undef LWS_HAVE_EVP_MD_CTX_free */
+/* #undef LWS_HAVE_EVP_aes_128_wrap */
+/* #undef LWS_HAVE_EVP_aes_128_cfb8 */
+/* #undef LWS_HAVE_EVP_aes_128_cfb128 */
+/* #undef LWS_HAVE_EVP_aes_192_cfb8 */
+/* #undef LWS_HAVE_EVP_aes_192_cfb128 */
+/* #undef LWS_HAVE_EVP_aes_256_cfb8 */
+/* #undef LWS_HAVE_EVP_aes_256_cfb128 */
+/* #undef LWS_HAVE_EVP_aes_128_xts */
+/* #undef LWS_HAVE_EVP_PKEY_new_raw_private_key */
+/* #undef LWS_HAVE_EXECVPE */
+/* #undef LWS_HAVE_LIBCAP */
+/* #undef LWS_HAVE_HMAC_CTX_new */
+/* #undef LWS_HAVE_MALLOC_H */
+/* #undef LWS_HAVE_MALLOC_TRIM */
+/* #undef LWS_HAVE_MALLOC_USABLE_SIZE */
+/* #undef LWS_HAVE_mbedtls_md_setup */
+/* #undef LWS_HAVE_mbedtls_net_init */
+/* #undef LWS_HAVE_mbedtls_rsa_complete */
+/* #undef LWS_HAVE_mbedtls_internal_aes_encrypt */
+/* #undef LWS_HAVE_mbedtls_ssl_conf_alpn_protocols */
+/* #undef LWS_HAVE_mbedtls_ssl_get_alpn_protocol */
+/* #undef LWS_HAVE_mbedtls_ssl_conf_sni */
+/* #undef LWS_HAVE_mbedtls_ssl_set_hs_ca_chain */
+/* #undef LWS_HAVE_mbedtls_ssl_set_hs_own_cert */
+/* #undef LWS_HAVE_mbedtls_ssl_set_hs_authmode */
+/* #undef LWS_HAVE_MBEDTLS_NET_SOCKETS */
+/* #undef LWS_HAVE_NEW_UV_VERSION_H */
+/* #undef LWS_HAVE_OPENSSL_ECDH_H */
+/* #undef LWS_HAVE_PIPE2 */
+/* #undef LWS_HAVE_EVENTFD */
+#define LWS_HAVE_PTHREAD_H
+/* #undef LWS_HAVE_RSA_SET0_KEY */
+/* #undef LWS_HAVE_RSA_verify_pss_mgf1 */
+/* #undef LWS_HAVE_SSL_CTX_get0_certificate */
+/* #undef LWS_HAVE_SSL_CTX_load_verify_file */
+/* #undef LWS_HAVE_SSL_CTX_load_verify_dir */
+/* #undef LWS_HAVE_SSL_CTX_set1_param */
+/* #undef LWS_HAVE_SSL_CTX_set_ciphersuites */
+/* #undef LWS_HAVE_SSL_EXTRA_CHAIN_CERTS */
+/* #undef LWS_HAVE_SSL_get0_alpn_selected */
+/* #undef LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key */
+/* #undef LWS_HAVE_SSL_set_alpn_protos */
+/* #undef LWS_HAVE_SSL_SET_INFO_CALLBACK */
+/* #undef LWS_HAVE__STAT32I64 */
+#define LWS_HAVE_STDINT_H
+/* #undef LWS_HAVE_SYS_CAPABILITY_H */
+/* #undef LWS_HAVE_TLS_CLIENT_METHOD */
+/* #undef LWS_HAVE_TLSV1_2_CLIENT_METHOD */
+/* #undef LWS_HAVE_UV_VERSION_H */
+#define LWS_HAVE_VFORK
+/* #undef LWS_HAVE_X509_get_key_usage */
+/* #undef LWS_HAVE_X509_VERIFY_PARAM_set1_host */
+#define LWS_LIBRARY_VERSION "4.1.99-1.8-ALPHA-201-gdc271bf22"
+#define LWS_LOGGING_BITFIELD_CLEAR 0
+#define LWS_LOGGING_BITFIELD_SET 0
+/* #undef LWS_MINGW_SUPPORT */
+/* #undef LWS_NO_CLIENT */
+#define LWS_NO_DAEMONIZE
+/* #undef LWS_OPENSSL_CLIENT_CERTS */
+/* #undef LWS_OPENSSL_SUPPORT */
+/* #undef LWS_PLAT_OPTEE */
+#define LWS_PLAT_UNIX
+/* #undef LWS_PLAT_FREERTOS */
+/* #undef LWS_ROLE_CGI */
+/* #undef LWS_ROLE_DBUS */
+#define LWS_ROLE_H1
+/* #undef LWS_ROLE_H2 */
+#define LWS_ROLE_RAW
+/* #undef LWS_ROLE_RAW_FILE */
+/* #undef LWS_ROLE_RAW_PROXY */
+#define LWS_ROLE_WS
+/* #undef LWS_ROLE_MQTT */
+/* #undef LWS_SHA1_USE_OPENSSL_NAME */
+/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */
+/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
+/* #undef LWS_WITH_ABSTRACT */
+/* #undef LWS_WITH_ACCESS_LOG */
+/* #undef LWS_WITH_ACME */
+/* #undef LWS_WITH_ALSA */
+/* #undef LWS_WITH_SYS_ASYNC_DNS */
+/* #undef LWS_WITH_BORINGSSL */
+/* #undef LWS_WITH_CGI */
+#define LWS_WITH_CUSTOM_HEADERS
+/* #undef LWS_WITH_DEPRECATED_LWS_DLL */
+/* #undef LWS_WITH_DETAILED_LATENCY */
+#define LWS_WITH_DIR
+/* #undef LWS_WITH_DRIVERS */
+/* #undef LWS_WITH_ESP32 */
+/* #undef LWS_HAVE_EVBACKEND_LINUXAIO */
+/* #undef LWS_HAVE_EVBACKEND_IOURING */
+/* #undef LWS_WITH_EXTERNAL_POLL */
+#define LWS_WITH_FILE_OPS
+/* #undef LWS_WITH_FSMOUNT */
+/* #undef LWS_WITH_FTS */
+/* #undef LWS_WITH_GENCRYPTO */
+/* #undef LWS_WITH_GENERIC_SESSIONS */
+/* #undef LWS_WITH_GLIB */
+/* #undef LWS_WITH_GTK */
+/* #undef LWS_WITH_HTTP2 */
+/* #undef LWS_WITH_HTTP_BASIC_AUTH */
+/* #undef LWS_WITH_HTTP_BROTLI */
+/* #undef LWS_HTTP_HEADERS_ALL */
+/* #undef LWS_WITH_HTTP_PROXY */
+/* #undef LWS_WITH_HTTP_STREAM_COMPRESSION */
+#define LWS_WITH_HTTP_UNCOMMON_HEADERS
+/* #undef LWS_WITH_IPV6 */
+/* #undef LWS_WITH_JOSE */
+#define LWS_WITH_LEJP
+/* #undef LWS_WITH_LIBEV */
+/* #undef LWS_WITH_LIBEVENT */
+/* #undef LWS_WITH_LIBUV */
+#define LWS_WITH_LWSAC
+#define LWS_LOGS_TIMESTAMP
+/* #undef LWS_WITH_MBEDTLS */
+/* #undef LWS_WITH_MINIZ */
+#define LWS_WITH_NETWORK
+/* #undef LWS_WITH_NO_LOGS */
+#define LWS_WITH_CLIENT
+#define LWS_WITHOUT_EXTENSIONS
+#define LWS_WITH_SERVER
+/* #undef LWS_WITH_SPAWN */
+/* #undef LWS_WITH_PEER_LIMITS */
+/* #undef LWS_WITH_PLUGINS */
+/* #undef LWS_WITH_POLARSSL */
+#define LWS_WITH_POLL
+/* #undef LWS_WITH_RANGES */
+/* #undef LWS_WITH_SECURE_STREAMS */
+/* #undef LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM */
+/* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
+/* #undef LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY */
+/* #undef LWS_WITH_SELFTESTS */
+#define LWS_WITH_SEQUENCER
+/* #undef LWS_WITH_SERVER_STATUS */
+#define LWS_WITH_SYS_SMD
+/* #undef LWS_WITH_SMTP */
+/* #undef LWS_WITH_SOCKS5 */
+/* #undef LWS_WITH_STATEFUL_URLDECODE */
+/* #undef LWS_WITH_STATS */
+/* #undef LWS_WITH_STRUCT_SQLITE3 */
+/* #undef LWS_WITH_STRUCT_JSON */
+/* #undef LWS_WITH_SQLITE3 */
+/* #undef LWS_WITH_SYS_NTPCLIENT */
+/* #undef LWS_WITH_SYS_DHCP_CLIENT */
+#define LWS_WITH_SYS_STATE
+/* #undef LWS_WITH_THREADPOOL */
+/* #undef LWS_WITH_TLS */
+#define LWS_WITH_UDP
+#define LWS_WITH_UNIX_SOCK
+/* #undef LWS_WITH_ZIP_FOPS */
+/* #undef USE_OLD_CYASSL */
+/* #undef USE_WOLFSSL */
+/* #undef LWS_WITH_EVENT_LIBS */
+/* #undef LWS_WITH_EVLIB_PLUGINS */
+/* #undef LWS_WITH_LIBUV_INTERNAL */
+/* #undef LWS_WITH_PLUGINS_API */
+

+ 108 - 0
Source/ThirdParty/libwebsockets/cmake-build-debug/lws_config_private.h

@@ -0,0 +1,108 @@
+/* lws_config_private.h.in. Private compilation options. */
+
+#ifndef NDEBUG
+	#ifndef _DEBUG
+		#define _DEBUG
+	#endif
+#endif
+/* #undef LWIP_PROVIDE_ERRNO */
+
+/* Define to 1 to use CyaSSL as a replacement for OpenSSL. 
+ * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
+/* #undef USE_CYASSL */
+
+/* Define to 1 if you have the `fork' function. */
+#define LWS_HAVE_FORK
+
+/* Define to 1 if you have the `getenv' function. */
+#define LWS_HAVE_GETENV
+
+/* Define to 1 if you have the <in6addr.h> header file. */
+/* #undef LWS_HAVE_IN6ADDR_H */
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#define LWS_HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define LWS_HAVE_MEMORY_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define LWS_HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define LWS_HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define LWS_HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#define LWS_HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define LWS_HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define LWS_HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+/* #undef LWS_HAVE_SYS_PRCTL_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define LWS_HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#define LWS_HAVE_SYS_SOCKIO_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define LWS_HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define LWS_HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define LWS_HAVE_UNISTD_H
+
+/* #undef LWS_HAVE_TCP_USER_TIMEOUT */
+
+/* Define to 1 if you have the `vfork' function. */
+#define LWS_HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef LWS_HAVE_VFORK_H */
+
+/* Define to 1 if `fork' works. */
+/* #undef LWS_HAVE_WORKING_FORK */
+
+/* Define to 1 if `vfork' works. */
+/* #undef LWS_HAVE_WORKING_VFORK */
+
+/* Define to 1 if execvpe() exists */
+/* #undef LWS_HAVE_EXECVPE */
+
+/* Define to 1 if you have the <zlib.h> header file. */
+/* #undef LWS_HAVE_ZLIB_H */
+
+#define LWS_HAVE_GETLOADAVG
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR // We're not using libtool
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
+
+/* Define to rpl_realloc if the replacement function should be used. */
+/* #undef realloc */
+
+/* Define to 1 if we have getifaddrs */
+#define LWS_HAVE_GETIFADDRS
+
+/* Define if the inline keyword doesn't exist. */
+/* #undef inline */
+
+/* #undef LWS_WITH_ZLIB */
+/* #undef LWS_HAS_PTHREAD_SETNAME_NP */
+
+/* Defined if you have the <inttypes.h> header file. */
+#define LWS_HAVE_INTTYPES_H

+ 11 - 0
Source/ThirdParty/libwebsockets/cmake/libwebsockets-config-version.cmake.in

@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@CPACK_PACKAGE_VERSION@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()	

+ 23 - 0
Source/ThirdParty/libwebsockets/cmake/libwebsockets-config.cmake.in

@@ -0,0 +1,23 @@
+# - Config file for lws
+
+# It defines the following variables
+#  LIBWEBSOCKETS_INCLUDE_DIRS - include directories for FooBar
+#  LIBWEBSOCKETS_LIBRARIES    - libraries to link against
+
+# Get the path of the current file.
+get_filename_component(LWS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+# Set the include directories.
+set(LIBWEBSOCKETS_INCLUDE_DIRS "@LWS__INCLUDE_DIRS@")
+
+# Include the project Targets file, this contains definitions for IMPORTED targets.
+include(${LWS_CMAKE_DIR}/LibwebsocketsTargets.cmake)
+
+# IMPORTED targets from LibwebsocketsTargets.cmake
+set(LIBWEBSOCKETS_LIBRARIES websockets websockets_shared)
+
+# These are additional libs that lws wants your app to also link to
+foreach(item "@LIB_LIST_AT_END@")
+	list(APPEND LIBWEBSOCKETS_DEP_LIBS ${item})
+endforeach()
+

+ 197 - 0
Source/ThirdParty/libwebsockets/cmake/lws_config.h.in

@@ -0,0 +1,197 @@
+/* lws_config.h  Generated from lws_config.h.in  */
+
+#ifndef NDEBUG
+	#ifndef _DEBUG
+		#define _DEBUG
+	#endif
+#endif
+
+#define LWS_INSTALL_DATADIR "${CMAKE_INSTALL_PREFIX}/share"
+#define LWS_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}"
+#define LWS_LIBRARY_VERSION_MAJOR ${LWS_LIBRARY_VERSION_MAJOR}
+#define LWS_LIBRARY_VERSION_MINOR ${LWS_LIBRARY_VERSION_MINOR}
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED ${LWS_LIBRARY_VERSION_PATCH_ELABORATED}
+#define LWS_LIBRARY_VERSION_PATCH ${LWS_LIBRARY_VERSION_PATCH}
+
+/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
+#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
+					(LWS_LIBRARY_VERSION_MINOR * 1000) + \
+					LWS_LIBRARY_VERSION_PATCH
+#define LWS_MAX_SMP ${LWS_MAX_SMP}
+
+#cmakedefine LWS_ESP_PLATFORM
+#cmakedefine LWS_LIBRARY_VERSION_NUMBER
+
+#cmakedefine LWS_EXT_PTHREAD_LIBRARIES
+
+#cmakedefine LWS_AVOID_SIGPIPE_IGN
+#cmakedefine LWS_BUILD_HASH "${LWS_BUILD_HASH}"
+#cmakedefine LWS_BUILTIN_GETIFADDRS
+#cmakedefine LWS_CLIENT_HTTP_PROXYING
+#cmakedefine LWS_DETECTED_PLAT_IOS
+#cmakedefine LWS_FALLBACK_GETHOSTBYNAME
+#cmakedefine LWS_HAS_INTPTR_T
+#cmakedefine LWS_HAS_GETOPT_LONG
+#cmakedefine LWS_HAVE__ATOI64
+#cmakedefine LWS_HAVE_ATOLL
+#cmakedefine LWS_HAVE_BN_bn2binpad
+#cmakedefine LWS_HAVE_CLOCK_GETTIME
+#cmakedefine LWS_HAVE_EC_POINT_get_affine_coordinates
+#cmakedefine LWS_HAVE_ECDSA_SIG_set0
+#cmakedefine LWS_HAVE_EVP_MD_CTX_free
+#cmakedefine LWS_HAVE_EVP_aes_128_wrap
+#cmakedefine LWS_HAVE_EVP_aes_128_cfb8
+#cmakedefine LWS_HAVE_EVP_aes_128_cfb128
+#cmakedefine LWS_HAVE_EVP_aes_192_cfb8
+#cmakedefine LWS_HAVE_EVP_aes_192_cfb128
+#cmakedefine LWS_HAVE_EVP_aes_256_cfb8
+#cmakedefine LWS_HAVE_EVP_aes_256_cfb128
+#cmakedefine LWS_HAVE_EVP_aes_128_xts
+#cmakedefine LWS_HAVE_EVP_PKEY_new_raw_private_key
+#cmakedefine LWS_HAVE_EXECVPE
+#cmakedefine LWS_HAVE_LIBCAP
+#cmakedefine LWS_HAVE_HMAC_CTX_new
+#cmakedefine LWS_HAVE_MALLOC_H
+#cmakedefine LWS_HAVE_MALLOC_TRIM
+#cmakedefine LWS_HAVE_MALLOC_USABLE_SIZE
+#cmakedefine LWS_HAVE_mbedtls_md_setup
+#cmakedefine LWS_HAVE_mbedtls_net_init
+#cmakedefine LWS_HAVE_mbedtls_rsa_complete
+#cmakedefine LWS_HAVE_mbedtls_internal_aes_encrypt
+#cmakedefine LWS_HAVE_mbedtls_ssl_conf_alpn_protocols
+#cmakedefine LWS_HAVE_mbedtls_ssl_get_alpn_protocol
+#cmakedefine LWS_HAVE_mbedtls_ssl_conf_sni
+#cmakedefine LWS_HAVE_mbedtls_ssl_set_hs_ca_chain
+#cmakedefine LWS_HAVE_mbedtls_ssl_set_hs_own_cert
+#cmakedefine LWS_HAVE_mbedtls_ssl_set_hs_authmode
+#cmakedefine LWS_HAVE_MBEDTLS_NET_SOCKETS
+#cmakedefine LWS_HAVE_NEW_UV_VERSION_H
+#cmakedefine LWS_HAVE_OPENSSL_ECDH_H
+#cmakedefine LWS_HAVE_PIPE2
+#cmakedefine LWS_HAVE_EVENTFD
+#cmakedefine LWS_HAVE_PTHREAD_H
+#cmakedefine LWS_HAVE_RSA_SET0_KEY
+#cmakedefine LWS_HAVE_RSA_verify_pss_mgf1
+#cmakedefine LWS_HAVE_SSL_CTX_get0_certificate
+#cmakedefine LWS_HAVE_SSL_CTX_load_verify_file
+#cmakedefine LWS_HAVE_SSL_CTX_load_verify_dir
+#cmakedefine LWS_HAVE_SSL_CTX_set1_param
+#cmakedefine LWS_HAVE_SSL_CTX_set_ciphersuites
+#cmakedefine LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
+#cmakedefine LWS_HAVE_SSL_get0_alpn_selected
+#cmakedefine LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
+#cmakedefine LWS_HAVE_SSL_set_alpn_protos
+#cmakedefine LWS_HAVE_SSL_SET_INFO_CALLBACK
+#cmakedefine LWS_HAVE__STAT32I64
+#cmakedefine LWS_HAVE_STDINT_H
+#cmakedefine LWS_HAVE_SYS_CAPABILITY_H
+#cmakedefine LWS_HAVE_TLS_CLIENT_METHOD
+#cmakedefine LWS_HAVE_TLSV1_2_CLIENT_METHOD
+#cmakedefine LWS_HAVE_UV_VERSION_H
+#cmakedefine LWS_HAVE_VFORK
+#cmakedefine LWS_HAVE_X509_get_key_usage
+#cmakedefine LWS_HAVE_X509_VERIFY_PARAM_set1_host
+#cmakedefine LWS_LIBRARY_VERSION "${LWS_LIBRARY_VERSION}"
+#define LWS_LOGGING_BITFIELD_CLEAR ${LWS_LOGGING_BITFIELD_CLEAR}
+#define LWS_LOGGING_BITFIELD_SET ${LWS_LOGGING_BITFIELD_SET}
+#cmakedefine LWS_MINGW_SUPPORT
+#cmakedefine LWS_NO_CLIENT
+#cmakedefine LWS_NO_DAEMONIZE
+#cmakedefine LWS_OPENSSL_CLIENT_CERTS "${LWS_OPENSSL_CLIENT_CERTS}"
+#cmakedefine LWS_OPENSSL_SUPPORT
+#cmakedefine LWS_PLAT_OPTEE
+#cmakedefine LWS_PLAT_UNIX
+#cmakedefine LWS_PLAT_FREERTOS
+#cmakedefine LWS_ROLE_CGI
+#cmakedefine LWS_ROLE_DBUS
+#cmakedefine LWS_ROLE_H1
+#cmakedefine LWS_ROLE_H2
+#cmakedefine LWS_ROLE_RAW
+#cmakedefine LWS_ROLE_RAW_FILE
+#cmakedefine LWS_ROLE_RAW_PROXY
+#cmakedefine LWS_ROLE_WS
+#cmakedefine LWS_ROLE_MQTT
+#cmakedefine LWS_SHA1_USE_OPENSSL_NAME
+#cmakedefine LWS_SSL_CLIENT_USE_OS_CA_CERTS
+#cmakedefine LWS_SSL_SERVER_WITH_ECDH_CERT
+#cmakedefine LWS_WITH_ABSTRACT
+#cmakedefine LWS_WITH_ACCESS_LOG
+#cmakedefine LWS_WITH_ACME
+#cmakedefine LWS_WITH_ALSA
+#cmakedefine LWS_WITH_SYS_ASYNC_DNS
+#cmakedefine LWS_WITH_BORINGSSL
+#cmakedefine LWS_WITH_CGI
+#cmakedefine LWS_WITH_CUSTOM_HEADERS
+#cmakedefine LWS_WITH_DEPRECATED_LWS_DLL
+#cmakedefine LWS_WITH_DETAILED_LATENCY
+#cmakedefine LWS_WITH_DIR
+#cmakedefine LWS_WITH_DRIVERS
+#cmakedefine LWS_WITH_ESP32
+#cmakedefine LWS_HAVE_EVBACKEND_LINUXAIO
+#cmakedefine LWS_HAVE_EVBACKEND_IOURING
+#cmakedefine LWS_WITH_EXTERNAL_POLL
+#cmakedefine LWS_WITH_FILE_OPS
+#cmakedefine LWS_WITH_FSMOUNT
+#cmakedefine LWS_WITH_FTS
+#cmakedefine LWS_WITH_GENCRYPTO
+#cmakedefine LWS_WITH_GENERIC_SESSIONS
+#cmakedefine LWS_WITH_GLIB
+#cmakedefine LWS_WITH_GTK
+#cmakedefine LWS_WITH_HTTP2
+#cmakedefine LWS_WITH_HTTP_BASIC_AUTH
+#cmakedefine LWS_WITH_HTTP_BROTLI
+#cmakedefine LWS_HTTP_HEADERS_ALL
+#cmakedefine LWS_WITH_HTTP_PROXY
+#cmakedefine LWS_WITH_HTTP_STREAM_COMPRESSION
+#cmakedefine LWS_WITH_HTTP_UNCOMMON_HEADERS
+#cmakedefine LWS_WITH_IPV6
+#cmakedefine LWS_WITH_JOSE
+#cmakedefine LWS_WITH_LEJP
+#cmakedefine LWS_WITH_LIBEV
+#cmakedefine LWS_WITH_LIBEVENT
+#cmakedefine LWS_WITH_LIBUV
+#cmakedefine LWS_WITH_LWSAC
+#cmakedefine LWS_LOGS_TIMESTAMP
+#cmakedefine LWS_WITH_MBEDTLS
+#cmakedefine LWS_WITH_MINIZ
+#cmakedefine LWS_WITH_NETWORK
+#cmakedefine LWS_WITH_NO_LOGS
+#cmakedefine LWS_WITH_CLIENT
+#cmakedefine LWS_WITHOUT_EXTENSIONS
+#cmakedefine LWS_WITH_SERVER
+#cmakedefine LWS_WITH_SPAWN
+#cmakedefine LWS_WITH_PEER_LIMITS
+#cmakedefine LWS_WITH_PLUGINS
+#cmakedefine LWS_WITH_POLARSSL
+#cmakedefine LWS_WITH_POLL
+#cmakedefine LWS_WITH_RANGES
+#cmakedefine LWS_WITH_SECURE_STREAMS
+#cmakedefine LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM
+#cmakedefine LWS_WITH_SECURE_STREAMS_PROXY_API
+#cmakedefine LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY
+#cmakedefine LWS_WITH_SELFTESTS
+#cmakedefine LWS_WITH_SEQUENCER
+#cmakedefine LWS_WITH_SERVER_STATUS
+#cmakedefine LWS_WITH_SYS_SMD
+#cmakedefine LWS_WITH_SMTP
+#cmakedefine LWS_WITH_SOCKS5
+#cmakedefine LWS_WITH_STATEFUL_URLDECODE
+#cmakedefine LWS_WITH_STATS
+#cmakedefine LWS_WITH_STRUCT_SQLITE3
+#cmakedefine LWS_WITH_STRUCT_JSON
+#cmakedefine LWS_WITH_SQLITE3
+#cmakedefine LWS_WITH_SYS_NTPCLIENT
+#cmakedefine LWS_WITH_SYS_DHCP_CLIENT
+#cmakedefine LWS_WITH_SYS_STATE
+#cmakedefine LWS_WITH_THREADPOOL
+#cmakedefine LWS_WITH_TLS
+#cmakedefine LWS_WITH_UDP
+#cmakedefine LWS_WITH_UNIX_SOCK
+#cmakedefine LWS_WITH_ZIP_FOPS
+#cmakedefine USE_OLD_CYASSL
+#cmakedefine USE_WOLFSSL
+#cmakedefine LWS_WITH_EVENT_LIBS
+#cmakedefine LWS_WITH_EVLIB_PLUGINS
+#cmakedefine LWS_WITH_LIBUV_INTERNAL
+#cmakedefine LWS_WITH_PLUGINS_API
+

+ 108 - 0
Source/ThirdParty/libwebsockets/cmake/lws_config_private.h.in

@@ -0,0 +1,108 @@
+/* lws_config_private.h.in. Private compilation options. */
+
+#ifndef NDEBUG
+	#ifndef _DEBUG
+		#define _DEBUG
+	#endif
+#endif
+#cmakedefine LWIP_PROVIDE_ERRNO
+
+/* Define to 1 to use CyaSSL as a replacement for OpenSSL. 
+ * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
+#cmakedefine USE_CYASSL
+
+/* Define to 1 if you have the `fork' function. */
+#cmakedefine LWS_HAVE_FORK
+
+/* Define to 1 if you have the `getenv' function. */
+#cmakedefine LWS_HAVE_GETENV
+
+/* Define to 1 if you have the <in6addr.h> header file. */
+#cmakedefine LWS_HAVE_IN6ADDR_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#cmakedefine LWS_HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine LWS_HAVE_MEMORY_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine LWS_HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine LWS_HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine LWS_HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#cmakedefine LWS_HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine LWS_HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine LWS_HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#cmakedefine LWS_HAVE_SYS_PRCTL_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#cmakedefine LWS_HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#cmakedefine LWS_HAVE_SYS_SOCKIO_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine LWS_HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine LWS_HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine LWS_HAVE_UNISTD_H
+
+#cmakedefine LWS_HAVE_TCP_USER_TIMEOUT
+
+/* Define to 1 if you have the `vfork' function. */
+#cmakedefine LWS_HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#cmakedefine LWS_HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#cmakedefine LWS_HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#cmakedefine LWS_HAVE_WORKING_VFORK
+
+/* Define to 1 if execvpe() exists */
+#cmakedefine LWS_HAVE_EXECVPE
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#cmakedefine LWS_HAVE_ZLIB_H
+
+#cmakedefine LWS_HAVE_GETLOADAVG
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR // We're not using libtool
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#cmakedefine malloc
+
+/* Define to rpl_realloc if the replacement function should be used. */
+#cmakedefine realloc
+
+/* Define to 1 if we have getifaddrs */
+#cmakedefine LWS_HAVE_GETIFADDRS
+
+/* Define if the inline keyword doesn't exist. */
+#cmakedefine inline ${inline}
+
+#cmakedefine LWS_WITH_ZLIB
+#cmakedefine LWS_HAS_PTHREAD_SETNAME_NP
+
+/* Defined if you have the <inttypes.h> header file. */
+#cmakedefine LWS_HAVE_INTTYPES_H

+ 45 - 0
Source/ThirdParty/libwebsockets/component.mk

@@ -0,0 +1,45 @@
+COMPONENT_DEPENDS := mbedtls openssl
+#COMPONENT_ADD_INCLUDEDIRS := ../../../../../../../../../../../../../../../../../../../../$(COMPONENT_BUILD_DIR)/include
+
+COMPONENT_OWNBUILDTARGET := 1
+
+CROSS_PATH1 := $(shell which xtensa-esp32-elf-gcc )
+CROSS_PATH := $(shell dirname $(CROSS_PATH1) )/..
+
+# detect MSYS2 environment and set generator flag if found
+# also set executable extension to .exe so that tools can be properly found
+# and disable bundled zlib
+MSYS_VERSION = $(if $(findstring Msys, $(shell uname -o)),$(word 1, $(subst ., ,$(shell uname -r))),0)
+ifneq ($(MSYS_VERSION),0)
+	MSYS_FLAGS = -DLWS_WITH_BUNDLED_ZLIB=0 -DEXECUTABLE_EXT=.exe -G'MSYS Makefiles'
+endif
+
+# -DNDEBUG=1 after cflags stops debug etc being built
+.PHONY: build
+build:
+	cd $(COMPONENT_BUILD_DIR) ; \
+	echo "doing lws cmake" ; \
+	cmake $(COMPONENT_PATH)  -DLWS_C_FLAGS="$(CFLAGS) -DNDEBUG=1" \
+		-DIDF_PATH=$(IDF_PATH) \
+		-DCROSS_PATH=$(CROSS_PATH) \
+		-DBUILD_DIR_BASE=$(BUILD_DIR_BASE) \
+		-DCMAKE_TOOLCHAIN_FILE=$(COMPONENT_PATH)/contrib/cross-esp32.cmake \
+		-DCMAKE_BUILD_TYPE=RELEASE \
+		-DLWS_MBEDTLS_INCLUDE_DIRS="${IDF_PATH}/components/openssl/include;${IDF_PATH}/components/mbedtls/mbedtls/include;${IDF_PATH}/components/mbedtls/port/include" \
+		-DLWS_WITH_STATS=0 \
+		-DLWS_WITH_HTTP2=1 \
+		-DLWS_WITH_RANGES=1 \
+		-DLWS_WITH_ACME=1 \
+		-DLWS_WITH_ZLIB=1 \
+		-DLWS_WITH_ZIP_FOPS=1 \
+		-DZLIB_LIBRARY=$(BUILD_DIR_BASE)/zlib/libzlib.a \
+		-DZLIB_INCLUDE_DIR=$(COMPONENT_PATH)/../zlib \
+		-DLWS_WITH_ESP32=1 \
+		$(MSYS_FLAGS) ; \
+	make && \
+	cp ${COMPONENT_BUILD_DIR}/lib/libwebsockets.a ${COMPONENT_BUILD_DIR}/liblibwebsockets.a
+
+clean: myclean
+
+myclean:
+	rm -rf ./build

+ 29 - 0
Source/ThirdParty/libwebsockets/contrib/Android.mk

@@ -0,0 +1,29 @@
+# example Android Native Library makefile
+# contributed by Gregory Junker <[email protected]>
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libwebsockets
+LOCAL_CFLAGS    := -DLWS_BUILTIN_GETIFADDRS
+LWS_LIB_PATH	:= ../../../shared/libwebsockets/lib
+LOCAL_C_INCLUDES:= $(LOCAL_PATH)/$(LWS_LIB_PATH)
+LOCAL_SRC_FILES := \
+	$(LWS_LIB_PATH)/base64-decode.c \
+	$(LWS_LIB_PATH)/client.c \
+	$(LWS_LIB_PATH)/client-handshake.c \
+	$(LWS_LIB_PATH)/client-parser.c \
+	$(LWS_LIB_PATH)/daemonize.c \
+	$(LWS_LIB_PATH)/extension.c \
+	$(LWS_LIB_PATH)/extension-deflate-frame.c \
+	$(LWS_LIB_PATH)/extension-deflate-stream.c \
+	$(LWS_LIB_PATH)/getifaddrs.c \
+	$(LWS_LIB_PATH)/handshake.c \
+	$(LWS_LIB_PATH)/libwebsockets.c \
+	$(LWS_LIB_PATH)/md5.c \
+	$(LWS_LIB_PATH)/output.c \
+	$(LWS_LIB_PATH)/parsers.c \
+	$(LWS_LIB_PATH)/sha-1.c
+
+include $(BUILD_STATIC_LIBRARY)

+ 58 - 0
Source/ThirdParty/libwebsockets/contrib/abi/README.md

@@ -0,0 +1,58 @@
+ABI Compatility Tracking
+========================
+
+This directory contains files that can be used to generate an ABI compatibility
+timeline for libwebsockets. This gives users an idea of where the library has
+changed and can be used by the developers to see when incompatible changes have
+been introduced and either increase the library SO version or fix the changes.
+
+The tools used are the abi-\* family available at https://github.com/lvc/ and
+some example output is here: http://abi-laboratory.pro/tracker/timeline/libuv/
+
+The tools download existing source tarballs and git repository to generate this
+data, so past versions are compared and in-development code can be compared as
+well.
+
+Although the application is not being included here, FYI the license is dual
+LGPL2 / GPL2 at your choice.
+
+
+Installation
+------------
+
+The abi monitoring stuff is now packaged in, eg, fedora, which is a lot
+easier than using the helper script.
+
+```
+# dnf install abi-tracker vtable-dumper
+
+Otherwise, the author provides an "easy way" to install the various tools he provides:
+
+    git clone https://github.com/lvc/installer
+	cd installer
+	make prefix=/usr/local target=abi-tracker
+
+It will also list any dependencies that you need to install through normal
+means.  (Although in the case of needing "elfutils-libelf-devel", it may
+crash during install of vtable-dumper without giving a nice list)
+
+
+Generating the output
+---------------------
+
+Use the `lws-abi-update.sh` script to download the source files, build them and
+generate the output html. The output can be deployed to a directory on a web
+server for example. Modify the commented line in lws-abi-update.sh to do this.
+
+As it is configured, lws-abi-update.sh will only download new source - ones
+that it hasn't built before - so is suitable for use with a cron job.
+
+
+Viewing the output
+------------------
+
+The best place to start looking at the data is the `timeline/libwebsockets`
+directory. If your path is on a web server, navigate there, otherwise you could
+try:
+
+    lynx timeline/libwebsockets/

+ 257 - 0
Source/ThirdParty/libwebsockets/contrib/abi/libwebsockets.json

@@ -0,0 +1,257 @@
+{
+  "Name":           "libwebsockets",
+  "SourceUrl":      "https://github.com/warmcat/libwebsockets/releases",
+  "Git":            "https://github.com/warmcat/libwebsockets",
+
+  "Versions": [
+  {
+    "Number":         "current",
+    "Installed":      "installed/libwebsockets/current",
+    "Source":         "src/libwebsockets/current",
+    "Changelog":      "On",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "3.0.0",
+    "Installed":      "installed/libwebsockets/3.0.0",
+    "Source":         "src/libwebsockets/3.0.0/libwebsockets-3.0.0.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.4.2",
+    "Installed":      "installed/libwebsockets/2.4.2",
+    "Source":         "src/libwebsockets/2.4.2/libwebsockets-2.4.2.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.4.1",
+    "Installed":      "installed/libwebsockets/2.4.1",
+    "Source":         "src/libwebsockets/2.4.1/libwebsockets-2.4.1.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.4.0",
+    "Installed":      "installed/libwebsockets/2.4.0",
+    "Source":         "src/libwebsockets/2.4.0/libwebsockets-2.4.0.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.3.0",
+    "Installed":      "installed/libwebsockets/2.3.0",
+    "Source":         "src/libwebsockets/2.3.0/libwebsockets-2.3.0.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.2.2",
+    "Installed":      "installed/libwebsockets/2.2.2",
+    "Source":         "src/libwebsockets/2.2.2/libwebsockets-2.2.2.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.2.1",
+    "Installed":      "installed/libwebsockets/2.2.1",
+    "Source":         "src/libwebsockets/2.2.1/libwebsockets-2.2.1.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.2.0",
+    "Installed":      "installed/libwebsockets/2.2.0",
+    "Source":         "src/libwebsockets/2.2.0/libwebsockets-2.2.0.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.1.1",
+    "Installed":      "installed/libwebsockets/2.1.1",
+    "Source":         "src/libwebsockets/2.1.1/libwebsockets-2.1.1.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "2.1.0",
+    "Installed":      "installed/libwebsockets/2.1.0",
+    "Source":         "src/libwebsockets/2.1.0/libwebsockets-2.1.0.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.9",
+    "Installed":      "installed/libwebsockets/1.7.9",
+    "Source":         "src/libwebsockets/1.7.9/libwebsockets-1.7.9.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.8",
+    "Installed":      "installed/libwebsockets/1.7.8",
+    "Source":         "src/libwebsockets/1.7.8/libwebsockets-1.7.8.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.7",
+    "Installed":      "installed/libwebsockets/1.7.7",
+    "Source":         "src/libwebsockets/1.7.7/libwebsockets-1.7.7.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.6",
+    "Installed":      "installed/libwebsockets/1.7.6",
+    "Source":         "src/libwebsockets/1.7.6/libwebsockets-1.7.6.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.5",
+    "Installed":      "installed/libwebsockets/1.7.5",
+    "Source":         "src/libwebsockets/1.7.5/libwebsockets-1.7.5.tar.gz",
+    "Changelog":      "changelog",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.4",
+    "Installed":      "installed/libwebsockets/1.7.4",
+    "Source":         "src/libwebsockets/1.7.4/libwebsockets-1.7.4.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.3",
+    "Installed":      "installed/libwebsockets/1.7.3",
+    "Source":         "src/libwebsockets/1.7.3/libwebsockets-1.7.3.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.2",
+    "Installed":      "installed/libwebsockets/1.7.2",
+    "Source":         "src/libwebsockets/1.7.2/libwebsockets-1.7.2.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.1",
+    "Installed":      "installed/libwebsockets/1.7.1",
+    "Source":         "src/libwebsockets/1.7.1/libwebsockets-1.7.1.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.7.0",
+    "Installed":      "installed/libwebsockets/1.7.0",
+    "Source":         "src/libwebsockets/1.7.0/libwebsockets-1.7.0.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.6.3",
+    "Installed":      "installed/libwebsockets/1.6.3",
+    "Source":         "src/libwebsockets/1.6.3/libwebsockets-1.6.3.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.6.2",
+    "Installed":      "installed/libwebsockets/1.6.2",
+    "Source":         "src/libwebsockets/1.6.2/libwebsockets-1.6.2.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.6.1",
+    "Installed":      "installed/libwebsockets/1.6.1",
+    "Source":         "src/libwebsockets/1.6.1/libwebsockets-1.6.1.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  },
+  {
+    "Number":         "1.5.1",
+    "Installed":      "installed/libwebsockets/1.5.1",
+    "Source":         "src/libwebsockets/1.5.1/libwebsockets-1.5.1.tar.gz",
+    "Changelog":      "Off",
+    "HeadersDiff":    "On",
+    "PkgDiff":        "Off",
+    "ABIView":        "Off",
+    "ABIDiff":        "Off"
+  }]
+}

+ 17 - 0
Source/ThirdParty/libwebsockets/contrib/abi/lws-abi-update.sh

@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if [ ! -z "$1" ] ; then
+ OUT=$1
+else
+ OUT="/tmp/lws-abi-track-htdocs"
+fi
+
+D=`dirname $0`
+if [ ! -z "$D" ] ; then
+ D=$D/
+fi
+J=$D"libwebsockets.json"
+
+abi-monitor -get -build-new $J
+abi-tracker -build $J
+abi-tracker -deploy $OUT $J

+ 97 - 0
Source/ThirdParty/libwebsockets/contrib/cross-openwrt-makefile

@@ -0,0 +1,97 @@
+#
+# libwebsockets makefile for openwrt
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libwebsockets
+PKG_VERSION:=2014-03-01
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/warmcat/libwebsockets.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=388dc7d201d8d123841869fb49ec4d94d6dd7f54
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += -DLWS_OPENSSL_CLIENT_CERTS=/etc/ssl/certs
+CMAKE_OPTIONS += -DLWS_OPENSSL_SUPPORT=ON
+CMAKE_OPTIONS += -DLWS_WITH_SSL=ON
+CMAKE_OPTIONS += -DLWS_WITHOUT_TESTAPPS=$(if $(CONFIG_PACKAGE_libwebsockets-examples),"OFF","ON")
+
+# for wolfssl, define these in addition to LWS_OPENSSL_SUPPORT and
+# edit package/libs/wolfssl/Makefile to include --enable-opensslextra
+# CMAKE_OPTIONS += -DLWS_WITH_WOLFSSL=ON
+# CMAKE_OPTIONS += -DLWS_WOLFSSL_LIBRARIES=$(STAGING_DIR)/usr/lib/libwolfssl.so
+# CMAKE_OPTIONS += -DLWS_WOLFSSL_INCLUDE_DIRS=$(STAGING_DIR)/usr/include
+
+# for cyassl, define these in addition to LWS_OPENSSL_SUPPORT and
+# edit package/libs/wolfssl/Makefile to include --enable-opensslextra
+# CMAKE_OPTIONS += -DLWS_WITH_CYASSL=ON
+# CMAKE_OPTIONS += -DLWS_CYASSL_LIBRARIES=$(STAGING_DIR)/usr/lib/libcyassl.so
+# CMAKE_OPTIONS += -DLWS_CYASSL_INCLUDE_DIRS=$(STAGING_DIR)/usr/include
+
+# other options worth noting
+# CMAKE_OPTIONS += -DLWS_WITHOUT_EXTENSIONS=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_DAEMONIZE=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_SERVER=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_DEBUG=ON
+
+
+define Package/libwebsockets/Default
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=libwebsockets
+	DEPENDS:=+zlib +libopenssl
+endef
+
+define Package/libwebsockets
+	$(call Package/libwebsockets/Default)
+	TITLE+= (libraries)
+endef
+
+define Package/libwebsockets/description
+	libwebsockets
+	This package contains libwebsocket libraries
+endef
+
+define Package/libwebsockets-examples
+	$(call Package/libwebsockets/Default)
+	DEPENDS:=libwebsockets
+	TITLE+= (examples)
+endef
+
+define Package/libwebsockets-examples/description
+	libwebsockets examples
+	This package contains libwebsockets examples
+endef
+
+define Package/libwebsockets/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libwebsockets.so* $(1)/usr/lib/
+endef
+
+define Package/libwebsockets-examples/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-client $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-echo $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-fraggle $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-ping $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-server $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libwebsockets-test-server-extpoll $(1)/usr/bin/
+
+	$(INSTALL_DIR) $(1)/usr/share/libwebsockets-test-server
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/favicon.ico $(1)/usr/share/libwebsockets-test-server/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/leaf.jpg $(1)/usr/share/libwebsockets-test-server/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/libwebsockets.org-logo.png $(1)/usr/share/libwebsockets-test-server/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/libwebsockets-test-server.key.pem $(1)/usr/share/libwebsockets-test-server/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/libwebsockets-test-server.pem $(1)/usr/share/libwebsockets-test-server/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libwebsockets-test-server/test.html $(1)/usr/share/libwebsockets-test-server/
+endef
+
+$(eval $(call BuildPackage,libwebsockets))
+$(eval $(call BuildPackage,libwebsockets-examples))

+ 653 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets.h

@@ -0,0 +1,653 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** @file */
+
+#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
+#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdarg>
+
+extern "C" {
+#else
+#include <stdarg.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "lws_config.h"
+
+/* place for one-shot opaque forward references */
+
+struct lws_sequencer;
+struct lws_dsh;
+
+/*
+ * CARE: everything using cmake defines needs to be below here
+ */
+
+#define LWS_US_PER_SEC ((lws_usec_t)1000000)
+#define LWS_MS_PER_SEC ((lws_usec_t)1000)
+#define LWS_US_PER_MS ((lws_usec_t)1000)
+#define LWS_NS_PER_US ((lws_usec_t)1000)
+
+#define LWS_KI (1024)
+#define LWS_MI (LWS_KI * 1024)
+#define LWS_GI (LWS_MI * 1024)
+#define LWS_TI ((uint64_t)LWS_GI * 1024)
+#define LWS_PI ((uint64_t)LWS_TI * 1024)
+
+#define LWS_US_TO_MS(x) ((x + (LWS_US_PER_MS / 2)) / LWS_US_PER_MS)
+
+#if defined(LWS_HAS_INTPTR_T)
+#include <stdint.h>
+#define lws_intptr_t intptr_t
+#else
+typedef unsigned long long lws_intptr_t;
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <stddef.h>
+#include <basetsd.h>
+#include <io.h>
+#ifndef _WIN32_WCE
+#include <fcntl.h>
+#else
+#define _O_RDONLY	0x0000
+#define O_RDONLY	_O_RDONLY
+#endif
+
+#define LWS_INLINE __inline
+#define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
+#define LWS_FORMAT(string_index)
+
+#if !defined(LWS_EXTERN) && defined(LWS_BUILDING_SHARED)
+#ifdef LWS_DLL
+#ifdef LWS_INTERNAL
+#define LWS_EXTERN extern __declspec(dllexport)
+#else
+#define LWS_EXTERN extern __declspec(dllimport)
+#endif
+#endif
+#endif
+
+#if !defined(LWS_INTERNAL) && !defined(LWS_EXTERN)
+#define LWS_EXTERN
+#define LWS_VISIBLE
+#endif
+
+#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
+#define LWS_SOCK_INVALID (INVALID_SOCKET)
+#define LWS_O_RDONLY _O_RDONLY
+#define LWS_O_WRONLY _O_WRONLY
+#define LWS_O_CREAT _O_CREAT
+#define LWS_O_TRUNC _O_TRUNC
+
+#ifndef __func__
+#define __func__ __FUNCTION__
+#endif
+
+#else /* NOT WIN32 */
+#include <unistd.h>
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+#include <sys/capability.h>
+#endif
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defined(__OpenBSD__)
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#define LWS_INLINE inline
+#define LWS_O_RDONLY O_RDONLY
+#define LWS_O_WRONLY O_WRONLY
+#define LWS_O_CREAT O_CREAT
+#define LWS_O_TRUNC O_TRUNC
+
+#if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_TA) && !defined(LWS_PLAT_FREERTOS)
+#include <poll.h>
+#include <netdb.h>
+#define LWS_INVALID_FILE -1
+#define LWS_SOCK_INVALID (-1)
+#else
+#define getdtablesize() (30)
+#if defined(LWS_PLAT_FREERTOS)
+#define LWS_INVALID_FILE NULL
+#define LWS_SOCK_INVALID (-1)
+#else
+#define LWS_INVALID_FILE NULL
+#define LWS_SOCK_INVALID (-1)
+#endif
+#endif
+
+#if defined(__FreeBSD__)
+#include <sys/signal.h>
+#endif
+#if defined(__GNUC__)
+
+/* warn_unused_result attribute only supported by GCC 3.4 or later */
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define LWS_WARN_UNUSED_RESULT
+#endif
+
+#if defined(LWS_BUILDING_SHARED)
+/* this is only set when we're building lws itself shared */
+#define LWS_VISIBLE __attribute__((visibility("default")))
+#define LWS_EXTERN extern
+
+#else /* not shared */
+#if defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
+#define LWS_VISIBLE
+#define LWS_EXTERN extern
+#else
+/*
+ * If we explicitly say hidden here, symbols exist as T but
+ * cannot be imported at link-time.
+ */
+#define LWS_VISIBLE
+#define LWS_EXTERN
+#endif
+
+#endif /* not shared */
+
+#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
+#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1)))
+#else /* not GNUC */
+
+#define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
+#define LWS_FORMAT(string_index)
+#if !defined(LWS_EXTERN)
+#define LWS_EXTERN extern
+#endif
+#endif
+
+
+#if defined(__ANDROID__)
+#include <netinet/in.h>
+#include <unistd.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#define random rand
+#else
+#if !defined(LWS_PLAT_OPTEE)
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+#endif
+
+#if defined(LWS_WITH_LIBUV_INTERNAL)
+#include <uv.h>
+
+#ifdef LWS_HAVE_UV_VERSION_H
+#include <uv-version.h>
+#endif
+
+#ifdef LWS_HAVE_NEW_UV_VERSION_H
+#include <uv/version.h>
+#endif
+#endif
+
+#if defined(LWS_WITH_TLS)
+
+#ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+#ifdef _WIN32
+/*
+ * Include user-controlled settings for windows from
+ * <wolfssl-root>/IDE/WIN/user_settings.h
+ */
+#include <IDE/WIN/user_settings.h>
+#include <cyassl/ctaocrypt/settings.h>
+#else
+#include <cyassl/options.h>
+#endif
+#include <cyassl/openssl/ssl.h>
+#include <cyassl/error-ssl.h>
+
+#else
+#ifdef _WIN32
+/*
+ * Include user-controlled settings for windows from
+ * <wolfssl-root>/IDE/WIN/user_settings.h
+ */
+#include <IDE/WIN/user_settings.h>
+#include <wolfssl/wolfcrypt/settings.h>
+#else
+#include <wolfssl/options.h>
+#endif
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/error-ssl.h>
+#endif /* not USE_OLD_CYASSL */
+#else
+#if defined(LWS_WITH_MBEDTLS)
+#if defined(LWS_PLAT_FREERTOS)
+/* this filepath is passed to us but without quotes or <> */
+#if !defined(LWS_AMAZON_RTOS)
+/* AMAZON RTOS has its own setting via MTK_MBEDTLS_CONFIG_FILE */
+#undef MBEDTLS_CONFIG_FILE
+#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h>
+#endif
+#endif
+#if defined(LWS_WITH_TLS)
+#include <mbedtls/ssl.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+#endif
+#else
+#include <openssl/ssl.h>
+#if !defined(LWS_WITH_MBEDTLS)
+#include <openssl/err.h>
+#endif
+#endif
+#endif /* not USE_WOLFSSL */
+#endif
+
+/*
+ * Helpers for pthread mutex in user code... if lws is built for
+ * multiple service threads, these resolve to pthread mutex
+ * operations.  In the case LWS_MAX_SMP is 1 (the default), they
+ * are all NOPs and no pthread type or api is referenced.
+ */
+
+#if LWS_MAX_SMP > 1
+
+#include <pthread.h>
+
+#define lws_pthread_mutex(name) pthread_mutex_t name;
+
+static LWS_INLINE void
+lws_pthread_mutex_init(pthread_mutex_t *lock)
+{
+	pthread_mutex_init(lock, NULL);
+}
+
+static LWS_INLINE void
+lws_pthread_mutex_destroy(pthread_mutex_t *lock)
+{
+	pthread_mutex_destroy(lock);
+}
+
+static LWS_INLINE void
+lws_pthread_mutex_lock(pthread_mutex_t *lock)
+{
+	pthread_mutex_lock(lock);
+}
+
+static LWS_INLINE void
+lws_pthread_mutex_unlock(pthread_mutex_t *lock)
+{
+	pthread_mutex_unlock(lock);
+}
+
+#else
+#define lws_pthread_mutex(name)
+#define lws_pthread_mutex_init(_a)
+#define lws_pthread_mutex_destroy(_a)
+#define lws_pthread_mutex_lock(_a)
+#define lws_pthread_mutex_unlock(_a)
+#endif
+
+
+#define CONTEXT_PORT_NO_LISTEN -1
+#define CONTEXT_PORT_NO_LISTEN_SERVER -2
+
+#include <libwebsockets/lws-logs.h>
+
+
+#include <stddef.h>
+
+#ifndef lws_container_of
+#define lws_container_of(P,T,M)	((T *)((char *)(P) - offsetof(T, M)))
+#endif
+#define LWS_ALIGN_TO(x, bou) x += ((bou) - ((x) % (bou))) % (bou)
+
+struct lws;
+
+/* api change list for user code to test against */
+
+#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG
+
+/* the struct lws_protocols has the id field present */
+#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD
+
+/* you can call lws_get_peer_write_allowance */
+#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE
+
+/* extra parameter introduced in 917f43ab821 */
+#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN
+
+/* File operations stuff exists */
+#define LWS_FEATURE_FOPS
+
+
+#if defined(_WIN32)
+#if !defined(LWS_WIN32_HANDLE_TYPES)
+typedef SOCKET lws_sockfd_type;
+typedef HANDLE lws_filefd_type;
+#endif
+
+struct lws_pollfd {
+	lws_sockfd_type fd; /**< file descriptor */
+	SHORT events; /**< which events to respond to */
+	SHORT revents; /**< which events happened */
+};
+#define LWS_POLLHUP (FD_CLOSE)
+#define LWS_POLLIN (FD_READ | FD_ACCEPT)
+#define LWS_POLLOUT (FD_WRITE)
+
+#else
+
+
+#if defined(LWS_PLAT_FREERTOS)
+#include <libwebsockets/lws-freertos.h>
+#else
+typedef int lws_sockfd_type;
+typedef int lws_filefd_type;
+#endif
+
+#if defined(LWS_PLAT_OPTEE)
+#include <time.h>
+struct timeval {
+	time_t         	tv_sec;
+	unsigned int    tv_usec;
+};
+#if defined(LWS_WITH_NETWORK)
+// #include <poll.h>
+#define lws_pollfd pollfd
+
+struct timezone;
+
+int gettimeofday(struct timeval *tv, struct timezone *tz);
+
+    /* Internet address. */
+    struct in_addr {
+        uint32_t       s_addr;     /* address in network byte order */
+    };
+
+typedef unsigned short sa_family_t;
+typedef unsigned short in_port_t;
+typedef uint32_t socklen_t;
+
+#include <libwebsockets/lws-optee.h>
+
+#if !defined(TEE_SE_READER_NAME_MAX)
+           struct addrinfo {
+               int              ai_flags;
+               int              ai_family;
+               int              ai_socktype;
+               int              ai_protocol;
+               socklen_t        ai_addrlen;
+               struct sockaddr *ai_addr;
+               char            *ai_canonname;
+               struct addrinfo *ai_next;
+           };
+#endif
+
+ssize_t recv(int sockfd, void *buf, size_t len, int flags);
+ssize_t send(int sockfd, const void *buf, size_t len, int flags);
+ssize_t read(int fd, void *buf, size_t count);
+int getsockopt(int sockfd, int level, int optname,
+                      void *optval, socklen_t *optlen);
+       int setsockopt(int sockfd, int level, int optname,
+                      const void *optval, socklen_t optlen);
+int connect(int sockfd, const struct sockaddr *addr,
+                   socklen_t addrlen);
+
+extern int errno;
+
+uint16_t ntohs(uint16_t netshort);
+uint16_t htons(uint16_t hostshort);
+
+int bind(int sockfd, const struct sockaddr *addr,
+                socklen_t addrlen);
+
+
+#define  MSG_NOSIGNAL 0x4000
+#define	EAGAIN		11
+#define EINTR		4
+#define EWOULDBLOCK	EAGAIN
+#define	EADDRINUSE	98	
+#define INADDR_ANY	0
+#define AF_INET		2
+#define SHUT_WR 1
+#define AF_UNSPEC	0
+#define PF_UNSPEC	0
+#define SOCK_STREAM	1
+#define SOCK_DGRAM	2
+# define AI_PASSIVE	0x0001
+#define IPPROTO_UDP	17
+#define SOL_SOCKET	1
+#define SO_SNDBUF	7
+#define	EISCONN		106	
+#define	EALREADY	114
+#define	EINPROGRESS	115
+int shutdown(int sockfd, int how);
+int close(int fd);
+int atoi(const char *nptr);
+long long atoll(const char *nptr);
+
+int socket(int domain, int type, int protocol);
+       int getaddrinfo(const char *node, const char *service,
+                       const struct addrinfo *hints,
+                       struct addrinfo **res);
+
+       void freeaddrinfo(struct addrinfo *res);
+
+#if !defined(TEE_SE_READER_NAME_MAX)
+struct lws_pollfd
+{
+        int fd;                     /* File descriptor to poll.  */
+        short int events;           /* Types of events poller cares about.  */
+        short int revents;          /* Types of events that actually occurred.  */
+};
+#endif
+
+int poll(struct pollfd *fds, int nfds, int timeout);
+
+#define LWS_POLLHUP (0x18)
+#define LWS_POLLIN (1)
+#define LWS_POLLOUT (4)
+#else
+struct lws_pollfd;
+struct sockaddr_in;
+#endif
+#else
+#define lws_pollfd pollfd
+#define LWS_POLLHUP (POLLHUP | POLLERR)
+#define LWS_POLLIN (POLLIN)
+#define LWS_POLLOUT (POLLOUT)
+#endif
+#endif
+
+
+#if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__)
+/* ... */
+#define ssize_t SSIZE_T
+#endif
+
+#if defined(WIN32) && defined(LWS_HAVE__STAT32I64)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#if defined(LWS_HAVE_STDINT_H)
+#include <stdint.h>
+#else
+#if defined(WIN32) || defined(_WIN32)
+/* !!! >:-[  */
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int8 uint8_t;
+#else
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+#endif
+#endif
+
+typedef int64_t lws_usec_t;
+typedef unsigned long long lws_filepos_t;
+typedef long long lws_fileofs_t;
+typedef uint32_t lws_fop_flags_t;
+
+#define lws_concat_temp(_t, _l) (_t + sizeof(_t) - _l)
+#define lws_concat_used(_t, _l) (sizeof(_t) - _l)
+
+/** struct lws_pollargs - argument structure for all external poll related calls
+ * passed in via 'in' */
+struct lws_pollargs {
+	lws_sockfd_type fd;	/**< applicable socket descriptor */
+	int events;		/**< the new event mask */
+	int prev_events;	/**< the previous event mask */
+};
+
+struct lws_extension; /* needed even with ws exts disabled for create context */
+struct lws_token_limits;
+struct lws_protocols;
+struct lws_context;
+struct lws_tokens;
+struct lws_vhost;
+struct lws;
+
+#include <libwebsockets/lws-dll2.h>
+#include <libwebsockets/lws-timeout-timer.h>
+#if defined(LWS_WITH_SYS_SMD)
+#include <libwebsockets/lws-smd.h>
+#endif
+#include <libwebsockets/lws-state.h>
+#include <libwebsockets/lws-retry.h>
+#include <libwebsockets/lws-adopt.h>
+#include <libwebsockets/lws-network-helper.h>
+#include <libwebsockets/lws-system.h>
+#include <libwebsockets/lws-detailed-latency.h>
+#include <libwebsockets/lws-ws-close.h>
+#include <libwebsockets/lws-callbacks.h>
+#include <libwebsockets/lws-ws-state.h>
+#include <libwebsockets/lws-ws-ext.h>
+#include <libwebsockets/lws-protocols-plugins.h>
+
+#include <libwebsockets/lws-context-vhost.h>
+
+#if defined(LWS_ROLE_MQTT)
+#include <libwebsockets/lws-mqtt.h>
+#endif
+#include <libwebsockets/lws-client.h>
+#include <libwebsockets/lws-http.h>
+#include <libwebsockets/lws-spa.h>
+#include <libwebsockets/lws-purify.h>
+#include <libwebsockets/lws-misc.h>
+#include <libwebsockets/lws-dsh.h>
+#include <libwebsockets/lws-service.h>
+#include <libwebsockets/lws-write.h>
+#include <libwebsockets/lws-writeable.h>
+#include <libwebsockets/lws-ring.h>
+#include <libwebsockets/lws-sha1-base64.h>
+#include <libwebsockets/lws-x509.h>
+#include <libwebsockets/lws-cgi.h>
+#if defined(LWS_WITH_FILE_OPS)
+#include <libwebsockets/lws-vfs.h>
+#endif
+#include <libwebsockets/lws-lejp.h>
+#include <libwebsockets/lws-stats.h>
+#include <libwebsockets/lws-struct.h>
+#include <libwebsockets/lws-threadpool.h>
+#include <libwebsockets/lws-tokenize.h>
+#include <libwebsockets/lws-lwsac.h>
+#include <libwebsockets/lws-fts.h>
+#include <libwebsockets/lws-diskcache.h>
+#include <libwebsockets/lws-sequencer.h>
+#include <libwebsockets/lws-secure-streams.h>
+#include <libwebsockets/lws-secure-streams-policy.h>
+#include <libwebsockets/lws-secure-streams-client.h>
+
+#if !defined(LWS_PLAT_FREERTOS)
+#include <libwebsockets/abstract/abstract.h>
+
+#include <libwebsockets/lws-test-sequencer.h>
+#endif
+#include <libwebsockets/lws-async-dns.h>
+
+#if defined(LWS_WITH_TLS)
+
+#if defined(LWS_WITH_MBEDTLS)
+#include <mbedtls/md5.h>
+#include <mbedtls/sha1.h>
+#include <mbedtls/sha256.h>
+#include <mbedtls/sha512.h>
+#endif
+
+#include <libwebsockets/lws-gencrypto.h>
+#include <libwebsockets/lws-genhash.h>
+#include <libwebsockets/lws-genrsa.h>
+#include <libwebsockets/lws-genaes.h>
+#include <libwebsockets/lws-genec.h>
+
+#include <libwebsockets/lws-jwk.h>
+#include <libwebsockets/lws-jose.h>
+#include <libwebsockets/lws-jws.h>
+#include <libwebsockets/lws-jwe.h>
+
+#endif
+
+#include <libwebsockets/lws-eventlib-exports.h>
+#include <libwebsockets/lws-i2c.h>
+#include <libwebsockets/lws-spi.h>
+#include <libwebsockets/lws-gpio.h>
+#include <libwebsockets/lws-bb-i2c.h>
+#include <libwebsockets/lws-bb-spi.h>
+#include <libwebsockets/lws-button.h>
+#include <libwebsockets/lws-led.h>
+#include <libwebsockets/lws-pwm.h>
+#include <libwebsockets/lws-display.h>
+#include <libwebsockets/lws-ssd1306-i2c.h>
+#include <libwebsockets/lws-ili9341-spi.h>
+#include <libwebsockets/lws-settings.h>
+#include <libwebsockets/lws-netdev.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 138 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/abstract.h

@@ -0,0 +1,138 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * These are used to optionally pass an array of index = C string, binary array,
+ * or ulong tokens to the abstract transport or protocol.  For example if it's
+ * raw socket transport, then the DNS address to connect to and the port are
+ * passed using these when the client created and bound to the transport.
+ */
+
+typedef struct lws_token_map {
+	union {
+		const char	*value;
+		uint8_t		*bvalue;
+		unsigned long	lvalue;
+	} u;
+	short			name_index;  /* 0 here indicates end of array */
+	short			length_or_zero;
+} lws_token_map_t;
+
+/*
+ * The indvidual protocols and transports define their own name_index-es which
+ * are meaningful to them.  Define index 0 globally as the end of an array of
+ * them, and provide bases so user protocol and transport ones don't overlap.
+ */
+
+enum {
+	LTMI_END_OF_ARRAY,
+
+	LTMI_PROTOCOL_BASE	= 2048,
+
+	LTMI_TRANSPORT_BASE	= 4096
+};
+
+struct lws_abs_transport;
+struct lws_abs_protocol;
+typedef struct lws_abs lws_abs_t;
+
+LWS_VISIBLE LWS_EXTERN const lws_token_map_t *
+lws_abs_get_token(const lws_token_map_t *token_map, short name_index);
+
+/*
+ * the combination of a protocol, transport, and token maps for each
+ */
+
+typedef void lws_abs_transport_inst_t;
+typedef void lws_abs_protocol_inst_t;
+
+/**
+ * lws_abstract_alloc() - allocate and configure an lws_abs_t
+ *
+ * \param vhost: the struct lws_vhost to bind to
+ * \param user: opaque user pointer
+ * \param abstract_path: "protocol.transport" names
+ * \param ap_tokens: tokens for protocol options
+ * \param at_tokens: tokens for transport
+ * \param seq: optional sequencer we should bind to, or NULL
+ * \param opaque_user_data: data given in sequencer callback, if any
+ *
+ * Returns an allocated lws_abs_t pointer set up with the other arguments.
+ *
+ * Doesn't create a connection instance, just allocates the lws_abs_t and
+ * sets it up with the arguments.
+ *
+ * Returns NULL is there's any problem.
+ */
+LWS_VISIBLE LWS_EXTERN lws_abs_t *
+lws_abstract_alloc(struct lws_vhost *vhost, void *user,
+		   const char *abstract_path, const lws_token_map_t *ap_tokens,
+		   const lws_token_map_t *at_tokens, struct lws_sequencer *seq,
+		   void *opaque_user_data);
+
+/**
+ * lws_abstract_free() - free an allocated lws_abs_t
+ *
+ * \param pabs: pointer to the lws_abs_t * to free
+ *
+ * Frees and sets the pointer to NULL.
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_abstract_free(lws_abs_t **pabs);
+
+/**
+ * lws_abs_bind_and_create_instance - use an abstract protocol and transport
+ *
+ * \param abs: the lws_abs_t describing the combination desired
+ *
+ * This instantiates an abstract protocol and abstract transport bound together.
+ * A single heap allocation is made for the combination and the protocol and
+ * transport creation ops are called on it.  The ap_tokens and at_tokens
+ * are consulted by the creation ops to decide the details of the protocol and
+ * transport for the instance.
+ */
+LWS_VISIBLE LWS_EXTERN lws_abs_t *
+lws_abs_bind_and_create_instance(const lws_abs_t *ai);
+
+/**
+ * lws_abs_destroy_instance() - destroys an instance
+ *
+ * \param ai: pointer to the ai pointer to destroy
+ *
+ * This is for destroying an instance created by
+ * lws_abs_bind_and_create_instance() above.
+ *
+ * Calls the protocol and transport destroy operations on the instance, then
+ * frees the combined allocation in one step.  The pointer ai is set to NULL.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_abs_destroy_instance(lws_abs_t **ai);
+
+/*
+ * bring in all the protocols and transports definitions
+ */
+
+#include <libwebsockets/abstract/protocols.h>
+#include <libwebsockets/abstract/transports.h>

+ 88 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/protocols.h

@@ -0,0 +1,88 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * Information about how this protocol handles multiple use of connections.
+ *
+ * .flags of 0 indicates each connection must start with a fresh transport.
+ *
+ * Flags can be used to indicate the protocol itself supports different
+ * kinds of multiple use.  However the actual use or not of these may depend on
+ * negotiation with the remote peer.
+ *
+ * LWS_AP_FLAG_PIPELINE_TRANSACTIONS:	other instances can be queued on one
+ *					with an existing connection and get a
+ *					chance to "hot take over" the existing
+ *					transport in turn, like h1 keepalive
+ *					pipelining
+ *
+ * LWS_AP_FLAG_MUXABLE_STREAM:	an existing connection can absorb more child
+ *				connections and mux them as separate child
+ *				streams ongoing, like h2
+ */
+
+enum {
+	LWS_AP_FLAG_PIPELINE_TRANSACTIONS			= (1 << 0),
+	LWS_AP_FLAG_MUXABLE_STREAM				= (1 << 1),
+};
+
+typedef struct lws_abs_protocol {
+	const char	*name;
+	int		alloc;
+	int		flags;
+
+	int		(*create)(const struct lws_abs *ai);
+	void		(*destroy)(lws_abs_protocol_inst_t **d);
+	int		(*compare)(lws_abs_t *abs1, lws_abs_t *abs2);
+
+	/* events the transport invokes (handled by abstract protocol) */
+
+	int		(*accept)(lws_abs_protocol_inst_t *d);
+	int		(*rx)(lws_abs_protocol_inst_t *d, const uint8_t *b, size_t l);
+	int		(*writeable)(lws_abs_protocol_inst_t *d, size_t budget);
+	int		(*closed)(lws_abs_protocol_inst_t *d);
+	int		(*heartbeat)(lws_abs_protocol_inst_t *d);
+
+	/* as parent, we get a notification a new child / queue entry
+	 * bound to us... this is the parent lws_abs_t as arg */
+	int		(*child_bind)(lws_abs_t *abs);
+} lws_abs_protocol_t;
+
+/**
+ * lws_abs_protocol_get_by_name() - returns a pointer to the named protocol ops
+ *
+ * \param name: the name of the abstract protocol
+ *
+ * Returns a pointer to the named protocol ops struct if available, otherwise
+ * NULL.
+ */
+LWS_VISIBLE LWS_EXTERN const lws_abs_protocol_t *
+lws_abs_protocol_get_by_name(const char *name);
+
+/*
+ * bring in public api pieces from protocols
+ */
+
+#include <libwebsockets/abstract/protocols/smtp.h>
+

+ 115 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/protocols/smtp.h

@@ -0,0 +1,115 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup smtp SMTP related functions
+ * ##SMTP related functions
+ * \ingroup lwsapi
+ *
+ * These apis let you communicate with a local SMTP server to send email from
+ * lws.  It handles all the SMTP sequencing and protocol actions.
+ *
+ * Your system should have postfix, sendmail or another MTA listening on port
+ * 25 and able to send email using the "mail" commandline app.  Usually distro
+ * MTAs are configured for this by default.
+ *
+ * You can either use the abstract protocol layer directly, or instead use the
+ * provided smtp sequencer... this takes care of creating the protocol
+ * connections, and provides and email queue and retry management.
+ */
+//@{
+
+#if defined(LWS_WITH_SMTP)
+
+enum {
+	LTMI_PSMTP_V_HELO = LTMI_PROTOCOL_BASE,		/* u.value */
+
+	LTMI_PSMTP_V_LWS_SMTP_EMAIL_T,			/* u.value */
+};
+
+enum {
+	LWS_SMTP_DISPOSITION_SENT,
+	LWS_SMTP_DISPOSITION_FAILED,
+	LWS_SMTP_DISPOSITION_FAILED_DESTROY
+};
+
+typedef struct lws_smtp_sequencer_args {
+	const char		helo[32];
+	struct lws_vhost	*vhost;
+	time_t			retry_interval;
+	time_t			delivery_timeout;
+	size_t			email_queue_max;
+	size_t			max_content_size;
+} lws_smtp_sequencer_args_t;
+
+typedef struct lws_smtp_sequencer lws_smtp_sequencer_t;
+typedef struct lws_smtp_email lws_smtp_email_t;
+
+LWS_VISIBLE LWS_EXTERN lws_smtp_sequencer_t *
+lws_smtp_sequencer_create(const lws_smtp_sequencer_args_t *args);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_smtp_sequencer_destroy(lws_smtp_sequencer_t *s);
+
+typedef int (*lws_smtp_cb_t)(void *e, void *d, int disp, const void *b, size_t l);
+typedef struct lws_smtp_email lws_smtp_email_t;
+
+/**
+ * lws_smtpc_add_email() - Allocates and queues an email object
+ *
+ * \param s: smtp sequencer to queue on
+ * \param payload: the email payload string, with headers and terminating .
+ * \param payload_len: size in bytes of the payload string
+ * \param sender: the sender name and email
+ * \param recipient: the recipient name and email
+ * \param data: opaque user data returned in the done callback
+ * \param done: callback called when the email send succeeded or failed
+ *
+ * Allocates an email object and copies the payload, sender and recipient into
+ * it and initializes it.  Returns NULL if OOM, otherwise the allocated email
+ * object.
+ *
+ * Because it copies the arguments into an allocated buffer, the original
+ * arguments can be safely destroyed after calling this.
+ *
+ * The done() callback must free the email object.  It doesn't have to free any
+ * individual members.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_smtpc_add_email(lws_smtp_sequencer_t *s, const char *payload,
+		    size_t payload_len, const char *sender,
+		    const char *recipient, void *data, lws_smtp_cb_t done);
+
+/**
+ * lws_smtpc_free_email() - Add email to the list of ones being sent
+ *
+ * \param e: email to queue for sending on \p c
+ *
+ * Adds an email to the linked-list of emails to send
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_smtpc_free_email(lws_smtp_email_t *e);
+
+
+#endif
+//@}

+ 65 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports.h

@@ -0,0 +1,65 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * Abstract transport ops
+ */
+
+typedef struct lws_abs_transport {
+	const char *name;
+	int alloc;
+
+	int (*create)(lws_abs_t *abs);
+	void (*destroy)(lws_abs_transport_inst_t **d);
+
+	/* check if the transport settings for these connections are the same */
+	int (*compare)(lws_abs_t *abs1, lws_abs_t *abs2);
+
+	/* events the abstract protocol invokes (handled by transport) */
+
+	int (*tx)(lws_abs_transport_inst_t *d, uint8_t *buf, size_t len);
+	int (*client_conn)(const lws_abs_t *abs);
+	int (*close)(lws_abs_transport_inst_t *d);
+	int (*ask_for_writeable)(lws_abs_transport_inst_t *d);
+	int (*set_timeout)(lws_abs_transport_inst_t *d, int reason, int secs);
+	int (*state)(lws_abs_transport_inst_t *d);
+} lws_abs_transport_t;
+
+/**
+ * lws_abs_protocol_get_by_name() - returns a pointer to the named protocol ops
+ *
+ * \param name: the name of the abstract protocol
+ *
+ * Returns a pointer to the named protocol ops struct if available, otherwise
+ * NULL.
+ */
+LWS_VISIBLE LWS_EXTERN const lws_abs_transport_t *
+lws_abs_transport_get_by_name(const char *name);
+
+/*
+ * bring in public api pieces from transports
+ */
+
+#include <libwebsockets/abstract/transports/raw-skt.h>
+#include <libwebsockets/abstract/transports/unit-test.h>

+ 29 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports/raw-skt.h

@@ -0,0 +1,29 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+enum {
+	LTMI_PEER_V_DNS_ADDRESS = LTMI_TRANSPORT_BASE,	/* u.value */
+	LTMI_PEER_LV_PORT,				/* u.lvalue */
+	LTMI_PEER_LV_TLS_FLAGS,				/* u.lvalue */
+};

+ 81 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/abstract/transports/unit-test.h

@@ -0,0 +1,81 @@
+ /*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * This is an abstract transport useful for unit testing abstract protocols.
+ *
+ * Instead of passing data anywhere, you give the transport a list of packets
+ * to deliver and packets you expect back from the abstract protocol it's
+ * bound to.
+ */
+
+enum {
+	LWS_AUT_EXPECT_TEST_END					= (1 << 0),
+	LWS_AUT_EXPECT_LOCAL_CLOSE				= (1 << 1),
+	LWS_AUT_EXPECT_DO_REMOTE_CLOSE				= (1 << 2),
+	LWS_AUT_EXPECT_TX /* expect this as tx from protocol */	= (1 << 3),
+	LWS_AUT_EXPECT_RX /* present this as rx to protocol */	= (1 << 4),
+	LWS_AUT_EXPECT_SHOULD_FAIL				= (1 << 5),
+	LWS_AUT_EXPECT_SHOULD_TIMEOUT				= (1 << 6),
+};
+
+typedef enum {
+	LPE_CONTINUE,
+	LPE_SUCCEEDED,
+	LPE_FAILED,
+	LPE_FAILED_UNEXPECTED_TIMEOUT,
+	LPE_FAILED_UNEXPECTED_PASS,
+	LPE_FAILED_UNEXPECTED_CLOSE,
+	LPE_SKIPPED,
+	LPE_CLOSING
+} lws_unit_test_packet_disposition;
+
+typedef int (*lws_unit_test_packet_test_cb)(const void *cb_user, int disposition);
+typedef int (*lws_unit_test_packet_cb)(lws_abs_t *instance);
+
+/* each step in the unit test */
+
+typedef struct lws_unit_test_packet {
+	void				*buffer;
+	lws_unit_test_packet_cb		pre;
+	size_t				len;
+
+	uint32_t			flags;
+} lws_unit_test_packet_t;
+
+/* each unit test */
+
+typedef struct lws_unit_test {
+	const char *		name; /* NULL indicates end of test array */
+	lws_unit_test_packet_t *		expect_array;
+	int			max_secs;
+} lws_unit_test_t;
+
+enum {
+	LTMI_PEER_V_EXPECT_TEST = LTMI_TRANSPORT_BASE,	/* u.value */
+	LTMI_PEER_V_EXPECT_RESULT_CB,			/* u.value */
+	LTMI_PEER_V_EXPECT_RESULT_CB_ARG,		/* u.value */
+};
+
+LWS_VISIBLE LWS_EXTERN const char *
+lws_unit_test_result_name(int in);
+

+ 233 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-adopt.h

@@ -0,0 +1,233 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup sock-adopt Socket adoption helpers
+ * ##Socket adoption helpers
+ *
+ * When integrating with an external app with its own event loop, these can
+ * be used to accept connections from someone else's listening socket.
+ *
+ * When using lws own event loop, these are not needed.
+ */
+///@{
+
+/**
+ * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it
+ * for the default vhost of context.
+ *
+ * \param context: lws context
+ * \param accept_fd: fd of already-accepted socket to adopt
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
+/**
+ * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted
+ * it for vhost
+ *
+ * \param vh: lws vhost
+ * \param accept_fd: fd of already-accepted socket to adopt
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
+
+typedef enum {
+	LWS_ADOPT_RAW_FILE_DESC = 0,	/* convenience constant */
+	LWS_ADOPT_HTTP = 1,		/* flag: absent implies RAW */
+	LWS_ADOPT_SOCKET = 2,		/* flag: absent implies file descr */
+	LWS_ADOPT_ALLOW_SSL = 4,	/* flag: if set requires LWS_ADOPT_SOCKET */
+	LWS_ADOPT_FLAG_UDP = 16,	/* flag: socket is UDP */
+	LWS_ADOPT_FLAG_RAW_PROXY = 32,	/* flag: raw proxy */
+
+	LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP,
+} lws_adoption_type;
+
+typedef union {
+	lws_sockfd_type sockfd;
+	lws_filefd_type filefd;
+} lws_sock_file_fd_type;
+
+#if defined(LWS_WITH_UDP)
+struct lws_udp {
+	struct sockaddr		sa;
+	socklen_t		salen;
+
+	struct sockaddr		sa_pending;
+	socklen_t		salen_pending;
+};
+#endif
+
+/**
+* lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor
+* if socket descriptor, should already have been accepted from listen socket
+*
+* \param vh: lws vhost
+* \param type: OR-ed combinations of lws_adoption_type flags
+* \param fd: union with either .sockfd or .filefd set
+* \param vh_prot_name: NULL or vh protocol name to bind raw connection to
+* \param parent: NULL or struct lws to attach new_wsi to as a child
+*
+* Either returns new wsi bound to accept_fd, or closes accept_fd and
+* returns NULL, having cleaned up any new wsi pieces.
+*
+* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
+* ready to accept an upgrade to ws or just serve http.
+*
+* parent may be NULL, if given it should be an existing wsi that will become the
+* parent of the new wsi created by this call.
+*/
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
+			   lws_sock_file_fd_type fd, const char *vh_prot_name,
+			   struct lws *parent);
+
+typedef struct lws_adopt_desc {
+	struct lws_vhost *vh;		/**< vhost the wsi should belong to */
+	lws_adoption_type type;		/**< OR-ed combinations of lws_adoption_type flags */
+	lws_sock_file_fd_type fd;	/**< union with either .sockfd or .filefd set */
+	const char *vh_prot_name;	/**< NULL or vh protocol name to bind raw connection to */
+	struct lws *parent;		/**< NULL or struct lws to attach new_wsi to as a child */
+	void *opaque;			/**< opaque pointer to set on created wsi */
+} lws_adopt_desc_t;
+
+/**
+* lws_adopt_descriptor_vhost_via_info() - adopt foreign socket or file descriptor
+* if socket descriptor, should already have been accepted from listen socket
+*
+* \param info: the struct containing the parameters
+*
+*  - vh: lws vhost
+*  - type: OR-ed combinations of lws_adoption_type flags
+*  - fd: union with either .sockfd or .filefd set
+*  - vh_prot_name: NULL or vh protocol name to bind raw connection to
+*  - parent: NULL or struct lws to attach new_wsi to as a child
+*  - opaque: opaque pointer to set on created wsi
+*
+* Either returns new wsi bound to accept_fd, or closes accept_fd and
+* returns NULL, having cleaned up any new wsi pieces.
+*
+* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
+* ready to accept an upgrade to ws or just serve http.
+*
+* parent may be NULL, if given it should be an existing wsi that will become the
+* parent of the new wsi created by this call.
+*/
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info);
+
+/**
+ * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
+ * for the default vhost of context.
+ * \param context:	lws context
+ * \param accept_fd:	fd of already-accepted socket to adopt
+ * \param readbuf:	NULL or pointer to data that must be drained before reading from
+ *		accept_fd
+ * \param len:	The length of the data held at \p readbuf
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ *
+ * If your external code did not already read from the socket, you can use
+ * lws_adopt_socket() instead.
+ *
+ * This api is guaranteed to use the data at \p readbuf first, before reading from
+ * the socket.
+ *
+ * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
+                         const char *readbuf, size_t len);
+/**
+ * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket
+ * accepted it for vhost.
+ * \param vhost:	lws vhost
+ * \param accept_fd:	fd of already-accepted socket to adopt
+ * \param readbuf:	NULL or pointer to data that must be drained before reading from accept_fd
+ * \param len:		The length of the data held at \p readbuf
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ *
+ * If your external code did not already read from the socket, you can use
+ * lws_adopt_socket() instead.
+ *
+ * This api is guaranteed to use the data at \p readbuf first, before reading from
+ * the socket.
+ *
+ * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
+			       lws_sockfd_type accept_fd, const char *readbuf,
+			       size_t len);
+
+#define LWS_CAUDP_BIND (1 << 0)
+#define LWS_CAUDP_BROADCAST (1 << 1)
+#define LWS_CAUDP_PF_PACKET (1 << 2)
+
+#if defined(LWS_WITH_UDP)
+/**
+ * lws_create_adopt_udp() - create, bind and adopt a UDP socket
+ *
+ * \param vhost:	 lws vhost
+ * \param ads:		 NULL or address to do dns lookup on
+ * \param port:		 UDP port to bind to, -1 means unbound
+ * \param flags:	 0 or LWS_CAUDP_NO_BIND
+ * \param protocol_name: Name of protocol on vhost to bind wsi to
+ * \param ifname:	 NULL, for network interface name to bind socket to
+ * \param parent_wsi:	 NULL or parent wsi new wsi will be a child of
+ * \param opaque:	 set created wsi opaque ptr to this
+ * \param retry_policy:	 NULL for vhost default policy else wsi specific policy
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ * */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
+		     int flags, const char *protocol_name, const char *ifname,
+		     struct lws *parent_wsi, void *opaque,
+		     const lws_retry_bo_t *retry_policy);
+#endif
+
+
+
+///@}

+ 87 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-async-dns.h

@@ -0,0 +1,87 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#if defined(LWS_WITH_UDP)
+
+typedef enum dns_query_type {
+	LWS_ADNS_RECORD_A					= 0x01,
+	LWS_ADNS_RECORD_CNAME					= 0x05,
+	LWS_ADNS_RECORD_MX					= 0x0f,
+	LWS_ADNS_RECORD_AAAA					= 0x1c,
+} adns_query_type_t;
+
+typedef enum {
+	LADNS_RET_FAILED_WSI_CLOSED				= -4,
+	LADNS_RET_NXDOMAIN					= -3,
+	LADNS_RET_TIMEDOUT					= -2,
+	LADNS_RET_FAILED					= -1,
+	LADNS_RET_FOUND,
+	LADNS_RET_CONTINUING
+} lws_async_dns_retcode_t;
+
+struct addrinfo;
+
+typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
+					   const struct addrinfo *result, int n,
+					   void *opaque);
+
+/**
+ * lws_async_dns_query() - perform a dns lookup using async dns
+ *
+ * \param context: the lws_context
+ * \param tsi: thread service index (usually 0)
+ * \param name: DNS name to look up
+ * \param qtype: type of query (A, AAAA etc)
+ * \param cb: query completion callback
+ * \param wsi: wsi if the query is related to one
+ *
+ * Starts an asynchronous DNS lookup, on completion the \p cb callback will
+ * be called.
+ *
+ * The reference count on the cached object is incremented for every callback
+ * that was called with the cached addrinfo results.
+ *
+ * The cached object can't be evicted until the reference count reaches zero...
+ * use lws_async_dns_freeaddrinfo() to indicate you're finsihed with the
+ * results for each callback that happened with them.
+ */
+LWS_VISIBLE LWS_EXTERN lws_async_dns_retcode_t
+lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
+		    adns_query_type_t qtype, lws_async_dns_cb_t cb,
+		    struct lws *wsi, void *opaque);
+
+/**
+ * lws_async_dns_freeaddrinfo() - decrement refcount on cached addrinfo results
+ *
+ * \param pai: a pointert to a pointer to first addrinfo returned as result in the callback
+ *
+ * Decrements the cache object's reference count.  When it reaches zero, the
+ * cached object may be reaped subject to LRU rules.
+ *
+ * The pointer to the first addrinfo give in the argument is set to NULL.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_async_dns_freeaddrinfo(const struct addrinfo **ai);
+
+#endif

+ 66 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-bb-i2c.h

@@ -0,0 +1,66 @@
+/*
+ * I2C - bitbanged generic gpio implementation
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * This is like an abstract class for gpio, a real implementation provides
+ * functions for the ops that use the underlying OS gpio arrangements.
+ */
+
+typedef struct lws_bb_i2c {
+	lws_i2c_ops_t		bb_ops; /* init to lws_bb_i2c_ops */
+
+	/* implementation-specific members */
+
+	_lws_plat_gpio_t	scl;
+	_lws_plat_gpio_t	sda;
+
+	const lws_gpio_ops_t	*gpio;
+	void (*delay)(void);
+} lws_bb_i2c_t;
+
+#define lws_bb_i2c_ops \
+	{ \
+		.init = lws_bb_i2c_init, \
+		.start = lws_bb_i2c_start, \
+		.stop = lws_bb_i2c_stop, \
+		.write = lws_bb_i2c_write, \
+		.read = lws_bb_i2c_read, \
+		.set_ack = lws_bb_i2c_set_ack, \
+	}
+
+int
+lws_bb_i2c_init(const lws_i2c_ops_t *octx);
+
+int
+lws_bb_i2c_start(const lws_i2c_ops_t *octx);
+
+void
+lws_bb_i2c_stop(const lws_i2c_ops_t *octx);
+
+int
+lws_bb_i2c_write(const lws_i2c_ops_t *octx, uint8_t data);
+
+int
+lws_bb_i2c_read(const lws_i2c_ops_t *octx);
+
+void
+lws_bb_i2c_set_ack(const lws_i2c_ops_t *octx, int ack);

+ 62 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-bb-spi.h

@@ -0,0 +1,62 @@
+/*
+ * I2C - bitbanged generic gpio implementation
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * This is like an abstract class for gpio, a real implementation provides
+ * functions for the ops that use the underlying OS gpio arrangements.
+ */
+
+#define LWSBBSPI_FLAG_USE_NCMD3		(1 << 7)
+#define LWSBBSPI_FLAG_USE_NCMD2		(1 << 6)
+#define LWSBBSPI_FLAG_USE_NCMD1		(1 << 5)
+#define LWSBBSPI_FLAG_USE_NCMD0		(1 << 4)
+#define LWSBBSPI_FLAG_USE_NCS3		(1 << 3)
+#define LWSBBSPI_FLAG_USE_NCS2		(1 << 2)
+#define LWSBBSPI_FLAG_USE_NCS1		(1 << 1)
+#define LWSBBSPI_FLAG_USE_NCS0		(1 << 0)
+
+#define LWS_SPI_BB_MAX_CH		4
+
+typedef struct lws_bb_spi {
+	lws_spi_ops_t		bb_ops; /* init to lws_bb_spi_ops */
+
+	/* implementation-specific members */
+	const lws_gpio_ops_t	*gpio;
+
+	_lws_plat_gpio_t	clk;
+	_lws_plat_gpio_t	ncs[LWS_SPI_BB_MAX_CH];
+	_lws_plat_gpio_t	ncmd[LWS_SPI_BB_MAX_CH];
+	_lws_plat_gpio_t	mosi;
+	_lws_plat_gpio_t	miso;
+
+	uint8_t			flags;
+} lws_bb_spi_t;
+
+#define lws_bb_spi_ops \
+		.init		= lws_bb_spi_init, \
+		.queue		= lws_bb_spi_queue
+
+int
+lws_bb_spi_init(const lws_spi_ops_t *octx);
+
+int
+lws_bb_spi_queue(const lws_spi_ops_t *octx, const lws_spi_desc_t *desc);

+ 120 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-button.h

@@ -0,0 +1,120 @@
+/*
+ * Generic button ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Leverages the lws generic gpio pieces to bind gpio buttons to smd events
+ */
+
+#if !defined(__LWS_BUTTON_H__)
+#define __LWS_BUTTON_H__
+
+typedef uint16_t lws_button_idx_t;
+
+/* actual minimum may be 1 x RTOS tick depending on platform */
+#define LWS_BUTTON_MON_TIMER_MS 5
+
+typedef void (*lws_button_cb_t)(void *opaque, lws_button_idx_t idx, int state);
+
+/* These are specified in ms but the granularity is LWS_BUTTON_MON_TIMER_MS,
+ * which may have been rounded up to an RTOS tick depending on platform */
+
+enum {
+	LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK = (1 << 0)
+};
+
+typedef struct lws_button_regime {
+	uint16_t			ms_min_down;
+	uint16_t			ms_min_down_longpress;
+	uint16_t			ms_up_settle;
+	uint16_t			ms_doubleclick_grace;
+	uint16_t			ms_repeat_down;
+	uint8_t				flags;
+	/**< when double-click classification is enabled, clicks are delayed
+	 * by ms_min_down + ms_doubleclick_grace to wait and see if it will
+	 * become a double-click.  Set LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK to
+	 * enable it or leave that bit at 0 to get faster single-click
+	 * classification.
+	 */
+} lws_button_regime_t;
+
+/*
+ * This is the const part of the button controller, describing the static
+ * bindings to gpio, and lws_smd event name information
+ */
+
+typedef struct lws_button_map {
+	_lws_plat_gpio_t		gpio;
+	const char			*smd_interaction_name;
+	const lws_button_regime_t	*regime;
+	/**< a default regime is applied if this is left NULL */
+} lws_button_map_t;
+
+typedef struct lws_button_controller {
+	const char			*smd_bc_name;
+	const lws_gpio_ops_t		*gpio_ops;
+	const lws_button_map_t		*button_map;
+	lws_button_idx_t		active_state_bitmap;
+	uint8_t				count_buttons;
+} lws_button_controller_t;
+
+struct lws_button_state; /* opaque */
+
+/**
+ * lws_button_controller_create() - instantiate a button controller
+ *
+ * \param ctx: the lws_context
+ * \param controller: the static controller definition
+ *
+ * Instantiates a button controller from a static definition of the buttons
+ * and their smd names, and active levels, and binds it to a gpio implementation
+ */
+
+LWS_VISIBLE LWS_EXTERN struct lws_button_state *
+lws_button_controller_create(struct lws_context *ctx,
+			     const lws_button_controller_t *controller);
+
+/**
+ * lws_button_controller_destroy() - destroys a button controller
+ *
+ * \param bcs: button controller state previously created
+ *
+ * Disables all buttons and then destroys and frees a previously created
+ * button controller.
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_button_controller_destroy(struct lws_button_state *bcs);
+
+
+LWS_VISIBLE LWS_EXTERN lws_button_idx_t
+lws_button_get_bit(struct lws_button_state *bcs, const char *name);
+
+/*
+ * lws_button_enable() - enable and disable buttons
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_button_enable(struct lws_button_state *bcs,
+		  lws_button_idx_t _reset, lws_button_idx_t _set);
+
+#endif
+

+ 910 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-callbacks.h

@@ -0,0 +1,910 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup usercb User Callback
+ *
+ * ##User protocol callback
+ *
+ * The protocol callback is the primary way lws interacts with
+ * user code.  For one of a list of a few dozen reasons the callback gets
+ * called at some event to be handled.
+ *
+ * All of the events can be ignored, returning 0 is taken as "OK" and returning
+ * nonzero in most cases indicates that the connection should be closed.
+ */
+///@{
+
+struct lws_ssl_info {
+	int where;
+	int ret;
+};
+
+enum lws_cert_update_state {
+	LWS_CUS_IDLE,
+	LWS_CUS_STARTING,
+	LWS_CUS_SUCCESS,
+	LWS_CUS_FAILED,
+
+	LWS_CUS_CREATE_KEYS,
+	LWS_CUS_REG,
+	LWS_CUS_AUTH,
+	LWS_CUS_CHALLENGE,
+	LWS_CUS_CREATE_REQ,
+	LWS_CUS_REQ,
+	LWS_CUS_CONFIRM,
+	LWS_CUS_ISSUE,
+};
+
+enum {
+	LWS_TLS_REQ_ELEMENT_COUNTRY,
+	LWS_TLS_REQ_ELEMENT_STATE,
+	LWS_TLS_REQ_ELEMENT_LOCALITY,
+	LWS_TLS_REQ_ELEMENT_ORGANIZATION,
+	LWS_TLS_REQ_ELEMENT_COMMON_NAME,
+	LWS_TLS_REQ_ELEMENT_SUBJECT_ALT_NAME,
+	LWS_TLS_REQ_ELEMENT_EMAIL,
+
+	LWS_TLS_REQ_ELEMENT_COUNT,
+
+	LWS_TLS_SET_DIR_URL = LWS_TLS_REQ_ELEMENT_COUNT,
+	LWS_TLS_SET_AUTH_PATH,
+	LWS_TLS_SET_CERT_PATH,
+	LWS_TLS_SET_KEY_PATH,
+
+	LWS_TLS_TOTAL_COUNT
+};
+
+struct lws_acme_cert_aging_args {
+	struct lws_vhost *vh;
+	const char *element_overrides[LWS_TLS_TOTAL_COUNT]; /* NULL = use pvo */
+};
+
+/*
+ * With LWS_CALLBACK_FILTER_NETWORK_CONNECTION callback, user_data pointer
+ * points to one of these
+ */
+
+struct lws_filter_network_conn_args {
+	struct sockaddr_storage		cli_addr;
+	socklen_t			clilen;
+	lws_sockfd_type			accept_fd;
+};
+
+/*
+ * NOTE: These public enums are part of the abi.  If you want to add one,
+ * add it at where specified so existing users are unaffected.
+ */
+/** enum lws_callback_reasons - reason you're getting a protocol callback */
+enum lws_callback_reasons {
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to wsi and protocol binding lifecycle -----
+	 */
+
+	LWS_CALLBACK_PROTOCOL_INIT				= 27,
+	/**< One-time call per protocol, per-vhost using it, so it can
+	 * do initial setup / allocations etc */
+
+	LWS_CALLBACK_PROTOCOL_DESTROY				= 28,
+	/**< One-time call per protocol, per-vhost using it, indicating
+	 * this protocol won't get used at all after this callback, the
+	 * vhost is getting destroyed.  Take the opportunity to
+	 * deallocate everything that was allocated by the protocol. */
+
+	LWS_CALLBACK_WSI_CREATE					= 29,
+	/**< outermost (earliest) wsi create notification to protocols[0] */
+
+	LWS_CALLBACK_WSI_DESTROY				= 30,
+	/**< outermost (latest) wsi destroy notification to protocols[0] */
+
+	LWS_CALLBACK_WSI_TX_CREDIT_GET				= 103,
+	/**< manually-managed connection received TX credit (len is int32) */
+
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to Server TLS -----
+	 */
+
+	LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS	= 21,
+	/**< if configured for
+	 * including OpenSSL support, this callback allows your user code
+	 * to perform extra SSL_CTX_load_verify_locations() or similar
+	 * calls to direct OpenSSL where to find certificates the client
+	 * can use to confirm the remote server identity.  user is the
+	 * OpenSSL SSL_CTX* */
+
+	LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS	= 22,
+	/**< if configured for
+	 * including OpenSSL support, this callback allows your user code
+	 * to load extra certificates into the server which allow it to
+	 * verify the validity of certificates returned by clients.  user
+	 * is the server's OpenSSL SSL_CTX* and in is the lws_vhost */
+
+	LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION	= 23,
+	/**< if the libwebsockets vhost was created with the option
+	 * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
+	 * callback is generated during OpenSSL verification of the cert
+	 * sent from the client.  It is sent to protocol[0] callback as
+	 * no protocol has been negotiated on the connection yet.
+	 * Notice that the libwebsockets context and wsi are both NULL
+	 * during this callback.  See
+	 *  http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
+	 * to understand more detail about the OpenSSL callback that
+	 * generates this libwebsockets callback and the meanings of the
+	 * arguments passed.  In this callback, user is the x509_ctx,
+	 * in is the ssl pointer and len is preverify_ok
+	 * Notice that this callback maintains libwebsocket return
+	 * conventions, return 0 to mean the cert is OK or 1 to fail it.
+	 * This also means that if you don't handle this callback then
+	 * the default callback action of returning 0 allows the client
+	 * certificates. */
+
+	LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY	= 37,
+	/**< if configured for including OpenSSL support but no private key
+	 * file has been specified (ssl_private_key_filepath is NULL), this is
+	 * called to allow the user to set the private key directly via
+	 * libopenssl and perform further operations if required; this might be
+	 * useful in situations where the private key is not directly accessible
+	 * by the OS, for example if it is stored on a smartcard.
+	 * user is the server's OpenSSL SSL_CTX* */
+
+	LWS_CALLBACK_SSL_INFO					= 67,
+	/**< SSL connections only.  An event you registered an
+	 * interest in at the vhost has occurred on a connection
+	 * using the vhost.  in is a pointer to a
+	 * struct lws_ssl_info containing information about the
+	 * event*/
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to Client TLS -----
+	 */
+
+	LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION = 58,
+	/**< Similar to LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION
+	 * this callback is called during OpenSSL verification of the cert
+	 * sent from the server to the client. It is sent to protocol[0]
+	 * callback as no protocol has been negotiated on the connection yet.
+	 * Notice that the wsi is set because lws_client_connect_via_info was
+	 * successful.
+	 *
+	 * See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
+	 * to understand more detail about the OpenSSL callback that
+	 * generates this libwebsockets callback and the meanings of the
+	 * arguments passed. In this callback, user is the x509_ctx,
+	 * in is the ssl pointer and len is preverify_ok.
+	 *
+	 * THIS IS NOT RECOMMENDED BUT if a cert validation error shall be
+	 * overruled and cert shall be accepted as ok,
+	 * X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK); must be
+	 * called and return value must be 0 to mean the cert is OK;
+	 * returning 1 will fail the cert in any case.
+	 *
+	 * This also means that if you don't handle this callback then
+	 * the default callback action of returning 0 will not accept the
+	 * certificate in case of a validation error decided by the SSL lib.
+	 *
+	 * This is expected and secure behaviour when validating certificates.
+	 *
+	 * Note: LCCSCF_ALLOW_SELFSIGNED and
+	 * LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK still work without this
+	 * callback being implemented.
+	 */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to HTTP Server  -----
+	 */
+
+	LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED		= 19,
+	/**< A new client has been accepted by the ws server.  This
+	 * callback allows setting any relevant property to it. Because this
+	 * happens immediately after the instantiation of a new client,
+	 * there's no websocket protocol selected yet so this callback is
+	 * issued only to protocol 0. Only wsi is defined, pointing to the
+	 * new client, and the return value is ignored. */
+
+	LWS_CALLBACK_HTTP					= 12,
+	/**< an http request has come from a client that is not
+	 * asking to upgrade the connection to a websocket
+	 * one.  This is a chance to serve http content,
+	 * for example, to send a script to the client
+	 * which will then open the websockets connection.
+	 * in points to the URI path requested and
+	 * lws_serve_http_file() makes it very
+	 * simple to send back a file to the client.
+	 * Normally after sending the file you are done
+	 * with the http connection, since the rest of the
+	 * activity will come by websockets from the script
+	 * that was delivered by http, so you will want to
+	 * return 1; to close and free up the connection. */
+
+	LWS_CALLBACK_HTTP_BODY					= 13,
+	/**< the next len bytes data from the http
+	 * request body HTTP connection is now available in in. */
+
+	LWS_CALLBACK_HTTP_BODY_COMPLETION			= 14,
+	/**< the expected amount of http request body has been delivered */
+
+	LWS_CALLBACK_HTTP_FILE_COMPLETION			= 15,
+	/**< a file requested to be sent down http link has completed. */
+
+	LWS_CALLBACK_HTTP_WRITEABLE				= 16,
+	/**< you can write more down the http protocol link now. */
+
+	LWS_CALLBACK_CLOSED_HTTP				=  5,
+	/**< when a HTTP (non-websocket) session ends */
+
+	LWS_CALLBACK_FILTER_HTTP_CONNECTION			= 18,
+	/**< called when the request has
+	 * been received and parsed from the client, but the response is
+	 * not sent yet.  Return non-zero to disallow the connection.
+	 * user is a pointer to the connection user space allocation,
+	 * in is the URI, eg, "/"
+	 * In your handler you can use the public APIs
+	 * lws_hdr_total_length() / lws_hdr_copy() to access all of the
+	 * headers using the header enums lws_token_indexes from
+	 * libwebsockets.h to check for and read the supported header
+	 * presence and content before deciding to allow the http
+	 * connection to proceed or to kill the connection. */
+
+	LWS_CALLBACK_ADD_HEADERS				= 53,
+	/**< This gives your user code a chance to add headers to a server
+	 * transaction bound to your protocol.  `in` points to a
+	 * `struct lws_process_html_args` describing a buffer and length
+	 * you can add headers into using the normal lws apis.
+	 *
+	 * (see LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to add headers to
+	 * a client transaction)
+	 *
+	 * Only `args->p` and `args->len` are valid, and `args->p` should
+	 * be moved on by the amount of bytes written, if any.  Eg
+	 *
+	 * 	case LWS_CALLBACK_ADD_HEADERS:
+	 *
+	 *          struct lws_process_html_args *args =
+	 *          		(struct lws_process_html_args *)in;
+	 *
+	 *	    if (lws_add_http_header_by_name(wsi,
+	 *			(unsigned char *)"set-cookie:",
+	 *			(unsigned char *)cookie, cookie_len,
+	 *			(unsigned char **)&args->p,
+	 *			(unsigned char *)args->p + args->max_len))
+	 *		return 1;
+	 *
+	 *          break;
+	 */
+
+	LWS_CALLBACK_VERIFY_BASIC_AUTHORIZATION = 102,
+	/**< This gives the user code a chance to accept or reject credentials
+	 * provided HTTP to basic authorization. It will only be called if the
+	 * http mount's authentication_mode is set to LWSAUTHM_BASIC_AUTH_CALLBACK
+	 * `in` points to a credential string of the form `username:password` If
+	 * the callback returns zero (the default if unhandled), then the
+	 * transaction ends with HTTP_STATUS_UNAUTHORIZED, otherwise the request
+	 * will be processed */
+
+	LWS_CALLBACK_CHECK_ACCESS_RIGHTS			= 51,
+	/**< This gives the user code a chance to forbid an http access.
+	 * `in` points to a `struct lws_process_html_args`, which
+	 * describes the URL, and a bit mask describing the type of
+	 * authentication required.  If the callback returns nonzero,
+	 * the transaction ends with HTTP_STATUS_UNAUTHORIZED. */
+
+	LWS_CALLBACK_PROCESS_HTML				= 52,
+	/**< This gives your user code a chance to mangle outgoing
+	 * HTML.  `in` points to a `struct lws_process_html_args`
+	 * which describes the buffer containing outgoing HTML.
+	 * The buffer may grow up to `.max_len` (currently +128
+	 * bytes per buffer).
+	 */
+
+	LWS_CALLBACK_HTTP_BIND_PROTOCOL				= 49,
+	/**< By default, all HTTP handling is done in protocols[0].
+	 * However you can bind different protocols (by name) to
+	 * different parts of the URL space using callback mounts.  This
+	 * callback occurs in the new protocol when a wsi is bound
+	 * to that protocol.  Any protocol allocation related to the
+	 * http transaction processing should be created then.
+	 * These specific callbacks are necessary because with HTTP/1.1,
+	 * a single connection may perform at series of different
+	 * transactions at different URLs, thus the lifetime of the
+	 * protocol bind is just for one transaction, not connection. */
+
+	LWS_CALLBACK_HTTP_DROP_PROTOCOL				= 50,
+	/**< This is called when a transaction is unbound from a protocol.
+	 * It indicates the connection completed its transaction and may
+	 * do something different now.  Any protocol allocation related
+	 * to the http transaction processing should be destroyed. */
+
+	LWS_CALLBACK_HTTP_CONFIRM_UPGRADE			= 86,
+	/**< This is your chance to reject an HTTP upgrade action.  The
+	 * name of the protocol being upgraded to is in 'in', and the ah
+	 * is still bound to the wsi, so you can look at the headers.
+	 *
+	 * The default of returning 0 (ie, also if not handled) means the
+	 * upgrade may proceed.  Return <0 to just hang up the connection,
+	 * or >0 if you have rejected the connection by returning http headers
+	 * and response code yourself.
+	 *
+	 * There is no need for you to call transaction_completed() as the
+	 * caller will take care of it when it sees you returned >0.
+	 */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to HTTP Client  -----
+	 */
+
+	LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP			= 44,
+	/**< The HTTP client connection has succeeded, and is now
+	 * connected to the server */
+
+	LWS_CALLBACK_CLOSED_CLIENT_HTTP				= 45,
+	/**< The HTTP client connection is closing */
+
+	LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ			= 48,
+	/**< This is generated by lws_http_client_read() used to drain
+	 * incoming data.  In the case the incoming data was chunked, it will
+	 * be split into multiple smaller callbacks for each chunk block,
+	 * removing the chunk headers. If not chunked, it will appear all in
+	 * one callback. */
+
+	LWS_CALLBACK_RECEIVE_CLIENT_HTTP			= 46,
+	/**< This indicates data was received on the HTTP client connection.  It
+	 * does NOT actually drain or provide the data, so if you are doing
+	 * http client, you MUST handle this and call lws_http_client_read().
+	 * Failure to deal with it as in the minimal examples may cause spinning
+	 * around the event loop as it's continuously signalled the same data
+	 * is available for read.  The related minimal examples show how to
+	 * handle it.
+	 *
+	 * It's possible to defer calling lws_http_client_read() if you use
+	 * rx flow control to stop further rx handling on the connection until
+	 * you did deal with it.  But normally you would call it in the handler.
+	 *
+	 * lws_http_client_read() strips any chunked framing and calls back
+	 * with only payload data to LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ.  The
+	 * chunking is the reason this is not just all done in one callback for
+	 * http.
+	 */
+	LWS_CALLBACK_COMPLETED_CLIENT_HTTP			= 47,
+	/**< The client transaction completed... at the moment this
+	 * is the same as closing since transaction pipelining on
+	 * client side is not yet supported.  */
+
+	LWS_CALLBACK_CLIENT_HTTP_WRITEABLE			= 57,
+	/**< when doing an HTTP type client connection, you can call
+	 * lws_client_http_body_pending(wsi, 1) from
+	 * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callbacks
+	 * sending the HTTP headers.
+	 *
+	 * From this callback, when you have sent everything, you should let
+	 * lws know by calling lws_client_http_body_pending(wsi, 0)
+	 */
+
+	LWS_CALLBACK_CLIENT_HTTP_REDIRECT			= 104,
+	/**< we're handling a 3xx redirect... return nonzero to hang up */
+
+	LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL			= 85,
+	LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL			= 76,
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to Websocket Server -----
+	 */
+
+	LWS_CALLBACK_ESTABLISHED				=  0,
+	/**< (VH) after the server completes a handshake with an incoming
+	 * client.  If you built the library with ssl support, in is a
+	 * pointer to the ssl struct associated with the connection or NULL.
+	 *
+	 * b0 of len is set if the connection was made using ws-over-h2
+	 */
+
+	LWS_CALLBACK_CLOSED					=  4,
+	/**< when the websocket session ends */
+
+	LWS_CALLBACK_SERVER_WRITEABLE				= 11,
+	/**< See LWS_CALLBACK_CLIENT_WRITEABLE */
+
+	LWS_CALLBACK_RECEIVE					=  6,
+	/**< data has appeared for this server endpoint from a
+	 * remote client, it can be found at *in and is
+	 * len bytes long */
+
+	LWS_CALLBACK_RECEIVE_PONG				=  7,
+	/**< servers receive PONG packets with this callback reason */
+
+	LWS_CALLBACK_WS_PEER_INITIATED_CLOSE			= 38,
+	/**< The peer has sent an unsolicited Close WS packet.  in and
+	 * len are the optional close code (first 2 bytes, network
+	 * order) and the optional additional information which is not
+	 * defined in the standard, and may be a string or non human-readable
+	 * data.
+	 * If you return 0 lws will echo the close and then close the
+	 * connection.  If you return nonzero lws will just close the
+	 * connection. */
+
+	LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION			= 20,
+	/**< called when the handshake has
+	 * been received and parsed from the client, but the response is
+	 * not sent yet.  Return non-zero to disallow the connection.
+	 * user is a pointer to the connection user space allocation,
+	 * in is the requested protocol name
+	 * In your handler you can use the public APIs
+	 * lws_hdr_total_length() / lws_hdr_copy() to access all of the
+	 * headers using the header enums lws_token_indexes from
+	 * libwebsockets.h to check for and read the supported header
+	 * presence and content before deciding to allow the handshake
+	 * to proceed or to kill the connection. */
+
+	LWS_CALLBACK_CONFIRM_EXTENSION_OKAY			= 25,
+	/**< When the server handshake code
+	 * sees that it does support a requested extension, before
+	 * accepting the extension by additing to the list sent back to
+	 * the client it gives this callback just to check that it's okay
+	 * to use that extension.  It calls back to the requested protocol
+	 * and with in being the extension name, len is 0 and user is
+	 * valid.  Note though at this time the ESTABLISHED callback hasn't
+	 * happened yet so if you initialize user content there, user
+	 * content during this callback might not be useful for anything. */
+
+	LWS_CALLBACK_WS_SERVER_BIND_PROTOCOL			= 77,
+	LWS_CALLBACK_WS_SERVER_DROP_PROTOCOL			= 78,
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to Websocket Client -----
+	 */
+
+	LWS_CALLBACK_CLIENT_CONNECTION_ERROR			=  1,
+	/**< the request client connection has been unable to complete a
+	 * handshake with the remote server.  If in is non-NULL, you can
+	 * find an error string of length len where it points to
+	 *
+	 * Diagnostic strings that may be returned include
+	 *
+	 *     	"getaddrinfo (ipv6) failed"
+	 *     	"unknown address family"
+	 *     	"getaddrinfo (ipv4) failed"
+	 *     	"set socket opts failed"
+	 *     	"insert wsi failed"
+	 *     	"lws_ssl_client_connect1 failed"
+	 *     	"lws_ssl_client_connect2 failed"
+	 *     	"Peer hung up"
+	 *     	"read failed"
+	 *     	"HS: URI missing"
+	 *     	"HS: Redirect code but no Location"
+	 *     	"HS: URI did not parse"
+	 *     	"HS: Redirect failed"
+	 *     	"HS: Server did not return 200"
+	 *     	"HS: OOM"
+	 *     	"HS: disallowed by client filter"
+	 *     	"HS: disallowed at ESTABLISHED"
+	 *     	"HS: ACCEPT missing"
+	 *     	"HS: ws upgrade response not 101"
+	 *     	"HS: UPGRADE missing"
+	 *     	"HS: Upgrade to something other than websocket"
+	 *     	"HS: CONNECTION missing"
+	 *     	"HS: UPGRADE malformed"
+	 *     	"HS: PROTOCOL malformed"
+	 *     	"HS: Cannot match protocol"
+	 *     	"HS: EXT: list too big"
+	 *     	"HS: EXT: failed setting defaults"
+	 *     	"HS: EXT: failed parsing defaults"
+	 *     	"HS: EXT: failed parsing options"
+	 *     	"HS: EXT: Rejects server options"
+	 *     	"HS: EXT: unknown ext"
+	 *     	"HS: Accept hash wrong"
+	 *     	"HS: Rejected by filter cb"
+	 *     	"HS: OOM"
+	 *     	"HS: SO_SNDBUF failed"
+	 *     	"HS: Rejected at CLIENT_ESTABLISHED"
+	 */
+
+	LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH		=  2,
+	/**< this is the last chance for the client user code to examine the
+	 * http headers and decide to reject the connection.  If the
+	 * content in the headers is interesting to the
+	 * client (url, etc) it needs to copy it out at
+	 * this point since it will be destroyed before
+	 * the CLIENT_ESTABLISHED call */
+
+	LWS_CALLBACK_CLIENT_ESTABLISHED				=  3,
+	/**< after your client connection completed the websocket upgrade
+	 * handshake with the remote server */
+
+	LWS_CALLBACK_CLIENT_CLOSED				= 75,
+	/**< when a client websocket session ends */
+
+	LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER		= 24,
+	/**< this callback happens
+	 * when a client handshake is being compiled.  user is NULL,
+	 * in is a char **, it's pointing to a char * which holds the
+	 * next location in the header buffer where you can add
+	 * headers, and len is the remaining space in the header buffer,
+	 * which is typically some hundreds of bytes.  So, to add a canned
+	 * cookie, your handler code might look similar to:
+	 *
+	 *	char **p = (char **)in, *end = (*p) + len;
+	 *
+	 *	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_COOKIE,
+	 *			(unsigned char)"a=b", 3, p, end))
+	 *		return -1;
+	 *
+	 * See LWS_CALLBACK_ADD_HEADERS for adding headers to server
+	 * transactions.
+	 */
+
+	LWS_CALLBACK_CLIENT_RECEIVE				=  8,
+	/**< data has appeared from the server for the client connection, it
+	 * can be found at *in and is len bytes long */
+
+	LWS_CALLBACK_CLIENT_RECEIVE_PONG			=  9,
+	/**< clients receive PONG packets with this callback reason */
+
+	LWS_CALLBACK_CLIENT_WRITEABLE				= 10,
+	/**<  If you call lws_callback_on_writable() on a connection, you will
+	 * get one of these callbacks coming when the connection socket
+	 * is able to accept another write packet without blocking.
+	 * If it already was able to take another packet without blocking,
+	 * you'll get this callback at the next call to the service loop
+	 * function.  Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
+	 * and servers get LWS_CALLBACK_SERVER_WRITEABLE. */
+
+	LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED		= 26,
+	/**< When a ws client
+	 * connection is being prepared to start a handshake to a server,
+	 * each supported extension is checked with protocols[0] callback
+	 * with this reason, giving the user code a chance to suppress the
+	 * claim to support that extension by returning non-zero.  If
+	 * unhandled, by default 0 will be returned and the extension
+	 * support included in the header to the server.  Notice this
+	 * callback comes to protocols[0]. */
+
+	LWS_CALLBACK_WS_EXT_DEFAULTS				= 39,
+	/**< Gives client connections an opportunity to adjust negotiated
+	 * extension defaults.  `user` is the extension name that was
+	 * negotiated (eg, "permessage-deflate").  `in` points to a
+	 * buffer and `len` is the buffer size.  The user callback can
+	 * set the buffer to a string describing options the extension
+	 * should parse.  Or just ignore for defaults. */
+
+
+	LWS_CALLBACK_FILTER_NETWORK_CONNECTION			= 17,
+	/**< called when a client connects to
+	 * the server at network level; the connection is accepted but then
+	 * passed to this callback to decide whether to hang up immediately
+	 * or not, based on the client IP.
+	 *
+	 * user_data in the callback points to a
+	 * struct lws_filter_network_conn_args that is prepared with the
+	 * sockfd, and the peer's address information.
+	 *
+	 * in contains the connection socket's descriptor.
+	 *
+	 * Since the client connection information is not available yet,
+	 * wsi still pointing to the main server socket.
+	 *
+	 * Return non-zero to terminate the connection before sending or
+	 * receiving anything. Because this happens immediately after the
+	 * network connection from the client, there's no websocket protocol
+	 * selected yet so this callback is issued only to protocol 0. */
+
+	LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL			= 79,
+	LWS_CALLBACK_WS_CLIENT_DROP_PROTOCOL			= 80,
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to external poll loop integration  -----
+	 */
+
+	LWS_CALLBACK_GET_THREAD_ID				= 31,
+	/**< lws can accept callback when writable requests from other
+	 * threads, if you implement this callback and return an opaque
+	 * current thread ID integer. */
+
+	/* external poll() management support */
+	LWS_CALLBACK_ADD_POLL_FD				= 32,
+	/**< lws normally deals with its poll() or other event loop
+	 * internally, but in the case you are integrating with another
+	 * server you will need to have lws sockets share a
+	 * polling array with the other server.  This and the other
+	 * POLL_FD related callbacks let you put your specialized
+	 * poll array interface code in the callback for protocol 0, the
+	 * first protocol you support, usually the HTTP protocol in the
+	 * serving case.
+	 * This callback happens when a socket needs to be
+	 * added to the polling loop: in points to a struct
+	 * lws_pollargs; the fd member of the struct is the file
+	 * descriptor, and events contains the active events
+	 *
+	 * If you are using the internal lws polling / event loop
+	 * you can just ignore these callbacks. */
+
+	LWS_CALLBACK_DEL_POLL_FD				= 33,
+	/**< This callback happens when a socket descriptor
+	 * needs to be removed from an external polling array.  in is
+	 * again the struct lws_pollargs containing the fd member
+	 * to be removed.  If you are using the internal polling
+	 * loop, you can just ignore it. */
+
+	LWS_CALLBACK_CHANGE_MODE_POLL_FD			= 34,
+	/**< This callback happens when lws wants to modify the events for
+	 * a connection.
+	 * in is the struct lws_pollargs with the fd to change.
+	 * The new event mask is in events member and the old mask is in
+	 * the prev_events member.
+	 * If you are using the internal polling loop, you can just ignore
+	 * it. */
+
+	LWS_CALLBACK_LOCK_POLL					= 35,
+	/**< These allow the external poll changes driven
+	 * by lws to participate in an external thread locking
+	 * scheme around the changes, so the whole thing is threadsafe.
+	 * These are called around three activities in the library,
+	 *	- inserting a new wsi in the wsi / fd table (len=1)
+	 *	- deleting a wsi from the wsi / fd table (len=1)
+	 *	- changing a wsi's POLLIN/OUT state (len=0)
+	 * Locking and unlocking external synchronization objects when
+	 * len == 1 allows external threads to be synchronized against
+	 * wsi lifecycle changes if it acquires the same lock for the
+	 * duration of wsi dereference from the other thread context. */
+
+	LWS_CALLBACK_UNLOCK_POLL				= 36,
+	/**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to CGI serving -----
+	 */
+
+	LWS_CALLBACK_CGI					= 40,
+	/**< CGI: CGI IO events on stdin / out / err are sent here on
+	 * protocols[0].  The provided `lws_callback_http_dummy()`
+	 * handles this and the callback should be directed there if
+	 * you use CGI. */
+
+	LWS_CALLBACK_CGI_TERMINATED				= 41,
+	/**< CGI: The related CGI process ended, this is called before
+	 * the wsi is closed.  Used to, eg, terminate chunking.
+	 * The provided `lws_callback_http_dummy()`
+	 * handles this and the callback should be directed there if
+	 * you use CGI.  The child PID that terminated is in len. */
+
+	LWS_CALLBACK_CGI_STDIN_DATA				= 42,
+	/**< CGI: Data is, to be sent to the CGI process stdin, eg from
+	 * a POST body.  The provided `lws_callback_http_dummy()`
+	 * handles this and the callback should be directed there if
+	 * you use CGI. */
+
+	LWS_CALLBACK_CGI_STDIN_COMPLETED			= 43,
+	/**< CGI: no more stdin is coming.  The provided
+	 * `lws_callback_http_dummy()` handles this and the callback
+	 * should be directed there if you use CGI. */
+
+	LWS_CALLBACK_CGI_PROCESS_ATTACH				= 70,
+	/**< CGI: Sent when the CGI process is spawned for the wsi.  The
+	 * len parameter is the PID of the child process */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to Generic Sessions -----
+	 */
+
+	LWS_CALLBACK_SESSION_INFO				= 54,
+	/**< This is only generated by user code using generic sessions.
+	 * It's used to get a `struct lws_session_info` filled in by
+	 * generic sessions with information about the logged-in user.
+	 * See the messageboard sample for an example of how to use. */
+
+	LWS_CALLBACK_GS_EVENT					= 55,
+	/**< Indicates an event happened to the Generic Sessions session.
+	 * `in` contains a `struct lws_gs_event_args` describing the event. */
+
+	LWS_CALLBACK_HTTP_PMO					= 56,
+	/**< per-mount options for this connection, called before
+	 * the normal LWS_CALLBACK_HTTP when the mount has per-mount
+	 * options.
+	 */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to RAW PROXY -----
+	 */
+
+	LWS_CALLBACK_RAW_PROXY_CLI_RX				= 89,
+	/**< RAW mode client (outgoing) RX */
+
+	LWS_CALLBACK_RAW_PROXY_SRV_RX				= 90,
+	/**< RAW mode server (listening) RX */
+
+	LWS_CALLBACK_RAW_PROXY_CLI_CLOSE			= 91,
+	/**< RAW mode client (outgoing) is closing */
+
+	LWS_CALLBACK_RAW_PROXY_SRV_CLOSE			= 92,
+	/**< RAW mode server (listening) is closing */
+
+	LWS_CALLBACK_RAW_PROXY_CLI_WRITEABLE			= 93,
+	/**< RAW mode client (outgoing) may be written */
+
+	LWS_CALLBACK_RAW_PROXY_SRV_WRITEABLE			= 94,
+	/**< RAW mode server (listening) may be written */
+
+	LWS_CALLBACK_RAW_PROXY_CLI_ADOPT			= 95,
+	/**< RAW mode client (onward) accepted socket was adopted
+	 *   (equivalent to 'wsi created') */
+
+	LWS_CALLBACK_RAW_PROXY_SRV_ADOPT			= 96,
+	/**< RAW mode server (listening) accepted socket was adopted
+	 *   (equivalent to 'wsi created') */
+
+	LWS_CALLBACK_RAW_PROXY_CLI_BIND_PROTOCOL		= 97,
+	LWS_CALLBACK_RAW_PROXY_SRV_BIND_PROTOCOL		= 98,
+	LWS_CALLBACK_RAW_PROXY_CLI_DROP_PROTOCOL		= 99,
+	LWS_CALLBACK_RAW_PROXY_SRV_DROP_PROTOCOL		= 100,
+
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to RAW sockets -----
+	 */
+
+	LWS_CALLBACK_RAW_RX					= 59,
+	/**< RAW mode connection RX */
+
+	LWS_CALLBACK_RAW_CLOSE					= 60,
+	/**< RAW mode connection is closing */
+
+	LWS_CALLBACK_RAW_WRITEABLE				= 61,
+	/**< RAW mode connection may be written */
+
+	LWS_CALLBACK_RAW_ADOPT					= 62,
+	/**< RAW mode connection was adopted (equivalent to 'wsi created') */
+
+	LWS_CALLBACK_RAW_CONNECTED				= 101,
+	/**< outgoing client RAW mode connection was connected */
+
+	LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL			= 81,
+	LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL			= 82,
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to RAW file handles -----
+	 */
+
+	LWS_CALLBACK_RAW_ADOPT_FILE				= 63,
+	/**< RAW mode file was adopted (equivalent to 'wsi created') */
+
+	LWS_CALLBACK_RAW_RX_FILE				= 64,
+	/**< This is the indication the RAW mode file has something to read.
+	 *   This doesn't actually do the read of the file and len is always
+	 *   0... your code should do the read having been informed there is
+	 *   something to read now. */
+
+	LWS_CALLBACK_RAW_WRITEABLE_FILE				= 65,
+	/**< RAW mode file is writeable */
+
+	LWS_CALLBACK_RAW_CLOSE_FILE				= 66,
+	/**< RAW mode wsi that adopted a file is closing */
+
+	LWS_CALLBACK_RAW_FILE_BIND_PROTOCOL			= 83,
+	LWS_CALLBACK_RAW_FILE_DROP_PROTOCOL			= 84,
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to generic wsi events -----
+	 */
+
+	LWS_CALLBACK_TIMER					= 73,
+	/**< When the time elapsed after a call to
+	 * lws_set_timer_usecs(wsi, usecs) is up, the wsi will get one of
+	 * these callbacks.  The deadline can be continuously extended into the
+	 * future by later calls to lws_set_timer_usecs() before the deadline
+	 * expires, or cancelled by lws_set_timer_usecs(wsi, -1);
+	 */
+
+	LWS_CALLBACK_EVENT_WAIT_CANCELLED			= 71,
+	/**< This is sent to every protocol of every vhost in response
+	 * to lws_cancel_service() or lws_cancel_service_pt().  This
+	 * callback is serialized in the lws event loop normally, even
+	 * if the lws_cancel_service[_pt]() call was from a different
+	 * thread. */
+
+	LWS_CALLBACK_CHILD_CLOSING				= 69,
+	/**< Sent to parent to notify them a child is closing / being
+	 * destroyed.  in is the child wsi.
+	 */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to TLS certificate management -----
+	 */
+
+	LWS_CALLBACK_VHOST_CERT_AGING				= 72,
+	/**< When a vhost TLS cert has its expiry checked, this callback
+	 * is broadcast to every protocol of every vhost in case the
+	 * protocol wants to take some action with this information.
+	 * \p in is a pointer to a struct lws_acme_cert_aging_args,
+	 * and \p len is the number of days left before it expires, as
+	 * a (ssize_t).  In the struct lws_acme_cert_aging_args, vh
+	 * points to the vhost the cert aging information applies to,
+	 * and element_overrides[] is an optional way to update information
+	 * from the pvos... NULL in an index means use the information from
+	 * from the pvo for the cert renewal, non-NULL in the array index
+	 * means use that pointer instead for the index. */
+
+	LWS_CALLBACK_VHOST_CERT_UPDATE				= 74,
+	/**< When a vhost TLS cert is being updated, progress is
+	 * reported to the vhost in question here, including completion
+	 * and failure.  in points to optional JSON, and len represents the
+	 * connection state using enum lws_cert_update_state */
+
+	/* ---------------------------------------------------------------------
+	 * ----- Callbacks related to MQTT Client  -----
+	 */
+
+	LWS_CALLBACK_MQTT_NEW_CLIENT_INSTANTIATED		= 200,
+	LWS_CALLBACK_MQTT_IDLE					= 201,
+	LWS_CALLBACK_MQTT_CLIENT_ESTABLISHED			= 202,
+	LWS_CALLBACK_MQTT_SUBSCRIBED				= 203,
+	LWS_CALLBACK_MQTT_CLIENT_WRITEABLE			= 204,
+	LWS_CALLBACK_MQTT_CLIENT_RX				= 205,
+	LWS_CALLBACK_MQTT_UNSUBSCRIBED				= 206,
+	LWS_CALLBACK_MQTT_DROP_PROTOCOL				= 207,
+	LWS_CALLBACK_MQTT_CLIENT_CLOSED				= 208,
+	LWS_CALLBACK_MQTT_ACK					= 209,
+	/**< When a message is fully sent, if QoS0 this callback is generated
+	 * to locally "acknowledge" it.  For QoS1, this callback is only
+	 * generated when the matching PUBACK is received.  Return nonzero to
+	 * close the wsi.
+	 */
+	LWS_CALLBACK_MQTT_RESEND				= 210,
+	/**< In QoS1, this callback is generated instead of the _ACK one if
+	 * we timed out waiting for a PUBACK and we must resend the message.
+	 * Return nonzero to close the wsi.
+	 */
+
+	/****** add new things just above ---^ ******/
+
+	LWS_CALLBACK_USER = 1000,
+	/**<  user code can use any including above without fear of clashes */
+};
+
+
+
+/**
+ * typedef lws_callback_function() - User server actions
+ * \param wsi:	Opaque websocket instance pointer
+ * \param reason:	The reason for the call
+ * \param user:	Pointer to per-session user data allocated by library
+ * \param in:		Pointer used for some callback reasons
+ * \param len:	Length set for some callback reasons
+ *
+ *	This callback is the way the user controls what is served.  All the
+ *	protocol detail is hidden and handled by the library.
+ *
+ *	For each connection / session there is user data allocated that is
+ *	pointed to by "user".  You set the size of this user data area when
+ *	the library is initialized with lws_create_server.
+ */
+typedef int
+lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason,
+		    void *user, void *in, size_t len);
+
+#define LWS_CB_REASON_AUX_BF__CGI		1
+#define LWS_CB_REASON_AUX_BF__PROXY		2
+#define LWS_CB_REASON_AUX_BF__CGI_CHUNK_END	4
+#define LWS_CB_REASON_AUX_BF__CGI_HEADERS	8
+#define LWS_CB_REASON_AUX_BF__PROXY_TRANS_END	16
+#define LWS_CB_REASON_AUX_BF__PROXY_HEADERS	32
+///@}

+ 104 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-cgi.h

@@ -0,0 +1,104 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup cgi cgi handling
+ *
+ * ##CGI handling
+ *
+ * These functions allow low-level control over stdin/out/err of the cgi.
+ *
+ * However for most cases, binding the cgi to http in and out, the default
+ * lws implementation already does the right thing.
+ */
+
+enum lws_enum_stdinouterr {
+	LWS_STDIN = 0,
+	LWS_STDOUT = 1,
+	LWS_STDERR = 2,
+};
+
+enum lws_cgi_hdr_state {
+	LCHS_HEADER,
+	LCHS_CR1,
+	LCHS_LF1,
+	LCHS_CR2,
+	LCHS_LF2,
+	LHCS_RESPONSE,
+	LHCS_DUMP_HEADERS,
+	LHCS_PAYLOAD,
+	LCHS_SINGLE_0A,
+};
+
+struct lws_cgi_args {
+	struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */
+	enum lws_enum_stdinouterr ch; /**< channel index */
+	unsigned char *data; /**< for messages with payload */
+	enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi headers */
+	int len; /**< length */
+};
+
+#ifdef LWS_WITH_CGI
+/**
+ * lws_cgi: spawn network-connected cgi process
+ *
+ * \param wsi: connection to own the process
+ * \param exec_array: array of "exec-name" "arg1" ... "argn" NULL
+ * \param script_uri_path_len: how many chars on the left of the uri are the
+ *        path to the cgi, or -1 to spawn without URL-related env vars
+ * \param timeout_secs: seconds script should be allowed to run
+ * \param mp_cgienv: pvo list with per-vhost cgi options to put in env
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cgi(struct lws *wsi, const char * const *exec_array,
+	int script_uri_path_len, int timeout_secs,
+	const struct lws_protocol_vhost_options *mp_cgienv);
+
+/**
+ * lws_cgi_write_split_stdout_headers: write cgi output accounting for header part
+ *
+ * \param wsi: connection to own the process
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cgi_write_split_stdout_headers(struct lws *wsi);
+
+/**
+ * lws_cgi_kill: terminate cgi process associated with wsi
+ *
+ * \param wsi: connection to own the process
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cgi_kill(struct lws *wsi);
+
+/**
+ * lws_cgi_get_stdwsi: get wsi for stdin, stdout, or stderr
+ *
+ * \param wsi: parent wsi that has cgi
+ * \param ch: which of LWS_STDIN, LWS_STDOUT or LWS_STDERR
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_cgi_get_stdwsi(struct lws *wsi, enum lws_enum_stdinouterr ch);
+
+#endif
+///@}
+

+ 343 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-client.h

@@ -0,0 +1,343 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup client Client related functions
+ * ##Client releated functions
+ * \ingroup lwsapi
+ *
+ * */
+///@{
+
+/** enum lws_client_connect_ssl_connection_flags - flags that may be used
+ * with struct lws_client_connect_info ssl_connection member to control if
+ * and how SSL checks apply to the client connection being created
+ */
+
+enum lws_client_connect_ssl_connection_flags {
+	LCCSCF_USE_SSL 				= (1 << 0),
+	LCCSCF_ALLOW_SELFSIGNED			= (1 << 1),
+	LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK	= (1 << 2),
+	LCCSCF_ALLOW_EXPIRED			= (1 << 3),
+	LCCSCF_ALLOW_INSECURE			= (1 << 4),
+	LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM	= (1 << 5),
+	LCCSCF_H2_QUIRK_OVERFLOWS_TXCR		= (1 << 6),
+	LCCSCF_H2_AUTH_BEARER			= (1 << 7),
+	LCCSCF_H2_HEXIFY_AUTH_TOKEN		= (1 << 8),
+	LCCSCF_H2_MANUAL_RXFLOW			= (1 << 9),
+	LCCSCF_HTTP_MULTIPART_MIME		= (1 << 10),
+	LCCSCF_HTTP_X_WWW_FORM_URLENCODED	= (1 << 11),
+	LCCSCF_HTTP_NO_FOLLOW_REDIRECT		= (1 << 12),
+
+	LCCSCF_PIPELINE				= (1 << 16),
+		/**< Serialize / pipeline multiple client connections
+		 * on a single connection where possible.
+		 *
+		 * HTTP/1.0: possible if Keep-Alive: yes sent by server
+		 * HTTP/1.1: always possible... uses pipelining
+		 * HTTP/2:   always possible... uses parallel streams
+		 */
+	LCCSCF_MUXABLE_STREAM			= (1 << 17),
+	LCCSCF_H2_PRIOR_KNOWLEDGE		= (1 << 18),
+	LCCSCF_WAKE_SUSPEND__VALIDITY		= (1 << 19),
+	/* our validity checks are important enough to wake from suspend */
+	LCCSCF_PRIORITIZE_READS			= (1 << 20),
+	/**<
+	 * Normally lws balances reads and writes on all connections, so both
+	 * are possible even on busy connections, and we go around the event
+	 * loop more often to facilitate that, even if there is pending data.
+	 *
+	 * This flag indicates that you want to handle any pending reads on this
+	 * connection without yielding the service loop for anything else.  This
+	 * means you may block other connection processing in favour of incoming
+	 * data processing on this one if it receives back to back incoming rx.
+	 */
+};
+
+/** struct lws_client_connect_info - parameters to connect with when using
+ *				    lws_client_connect_via_info() */
+
+struct lws_client_connect_info {
+	struct lws_context *context;
+	/**< lws context to create connection in */
+	const char *address;
+	/**< remote address to connect to */
+	int port;
+	/**< remote port to connect to */
+	int ssl_connection;
+	/**< 0, or a combination of LCCSCF_ flags */
+	const char *path;
+	/**< uri path */
+	const char *host;
+	/**< content of host header */
+	const char *origin;
+	/**< content of origin header */
+	const char *protocol;
+	/**< list of ws protocols we could accept */
+	int ietf_version_or_minus_one;
+	/**< deprecated: currently leave at 0 or -1 */
+	void *userdata;
+	/**< if non-NULL, use this as wsi user_data instead of malloc it */
+	const void *client_exts;
+	/**< UNUSED... provide in info.extensions at context creation time */
+	const char *method;
+	/**< if non-NULL, do this http method instead of ws[s] upgrade.
+	 * use "GET" to be a simple http client connection.  "RAW" gets
+	 * you a connected socket that lws itself will leave alone once
+	 * connected. */
+	struct lws *parent_wsi;
+	/**< if another wsi is responsible for this connection, give it here.
+	 * this is used to make sure if the parent closes so do any
+	 * child connections first. */
+	const char *uri_replace_from;
+	/**< if non-NULL, when this string is found in URIs in
+	 * text/html content-encoding, it's replaced with uri_replace_to */
+	const char *uri_replace_to;
+	/**< see uri_replace_from */
+	struct lws_vhost *vhost;
+	/**< vhost to bind to (used to determine related SSL_CTX) */
+	struct lws **pwsi;
+	/**< if not NULL, store the new wsi here early in the connection
+	 * process.  Although we return the new wsi, the call to create the
+	 * client connection does progress the connection somewhat and may
+	 * meet an error that will result in the connection being scrubbed and
+	 * NULL returned.  While the wsi exists though, he may process a
+	 * callback like CLIENT_CONNECTION_ERROR with his wsi: this gives the
+	 * user callback a way to identify which wsi it is that faced the error
+	 * even before the new wsi is returned and even if ultimately no wsi
+	 * is returned.
+	 */
+	const char *iface;
+	/**< NULL to allow routing on any interface, or interface name or IP
+	 * to bind the socket to */
+	const char *local_protocol_name;
+	/**< NULL: .protocol is used both to select the local protocol handler
+	 *         to bind to and as the list of remote ws protocols we could
+	 *         accept.
+	 *   non-NULL: this protocol name is used to bind the connection to
+	 *             the local protocol handler.  .protocol is used for the
+	 *             list of remote ws protocols we could accept */
+	const char *alpn;
+	/**< NULL: allow lws default ALPN list, from vhost if present or from
+	 *       list of roles built into lws
+	 * non-NULL: require one from provided comma-separated list of alpn
+	 *           tokens
+	 */
+
+	struct lws_sequencer *seq;
+	/**< NULL, or an lws_seq_t that wants to be given messages about
+	 * this wsi's lifecycle as it connects, errors or closes.
+	 */
+
+	void *opaque_user_data;
+	/**< This data has no meaning to lws but is applied to the client wsi
+	 *   and can be retrieved by user code with lws_get_opaque_user_data().
+	 *   It's also provided with sequencer messages if the wsi is bound to
+	 *   an lws_seq_t.
+	 */
+
+	const lws_retry_bo_t *retry_and_idle_policy;
+	/**< optional retry and idle policy to apply to this connection.
+	 *   Currently only the idle parts are applied to the connection.
+	 */
+
+	int		manual_initial_tx_credit;
+	/**< if LCCSCF_H2_MANUAL_REFLOW is set, this becomes the initial tx
+	 * credit for the stream.
+	 */
+
+	uint8_t		sys_tls_client_cert;
+	/**< 0 means no client cert.  1+ means apply lws_system client cert 0+
+	 * to the client connection.
+	 */
+
+#if defined(LWS_ROLE_MQTT)
+	const lws_mqtt_client_connect_param_t *mqtt_cp;
+#else
+	void		*mqtt_cp;
+#endif
+
+	uint16_t	keep_warm_secs;
+	/**< 0 means 5s.  If the client connection to the endpoint becomes idle,
+	 * defer closing it for this many seconds in case another outgoing
+	 * connection to the same endpoint turns up.
+	 */
+
+	/* Add new things just above here ---^
+	 * This is part of the ABI, don't needlessly break compatibility
+	 *
+	 * The below is to ensure later library versions with new
+	 * members added above will see 0 (default) even if the app
+	 * was not built against the newer headers.
+	 */
+
+	void *_unused[4]; /**< dummy */
+};
+
+/**
+ * lws_client_connect_via_info() - Connect to another websocket server
+ * \param ccinfo: pointer to lws_client_connect_info struct
+ *
+ *	This function creates a connection to a remote server using the
+ *	information provided in ccinfo.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_client_connect_via_info(const struct lws_client_connect_info *ccinfo);
+
+/**
+ * lws_init_vhost_client_ssl() - also enable client SSL on an existing vhost
+ *
+ * \param info: client ssl related info
+ * \param vhost: which vhost to initialize client ssl operations on
+ *
+ * You only need to call this if you plan on using SSL client connections on
+ * the vhost.  For non-SSL client connections, it's not necessary to call this.
+ *
+ * The following members of info are used during the call
+ *
+ *	 - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set,
+ *	     otherwise the call does nothing
+ *	 - provided_client_ssl_ctx must be NULL to get a generated client
+ *	     ssl context, otherwise you can pass a prepared one in by setting it
+ *	 - ssl_cipher_list may be NULL or set to the client valid cipher list
+ *	 - ssl_ca_filepath may be NULL or client cert filepath
+ *	 - ssl_cert_filepath may be NULL or client cert filepath
+ *	 - ssl_private_key_filepath may be NULL or client cert private key
+ *
+ * You must create your vhost explicitly if you want to use this, so you have
+ * a pointer to the vhost.  Create the context first with the option flag
+ * LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with
+ * the same info struct.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,
+			  struct lws_vhost *vhost);
+/**
+ * lws_http_client_read() - consume waiting received http client data
+ *
+ * \param wsi: client connection
+ * \param buf: pointer to buffer pointer - fill with pointer to your buffer
+ * \param len: pointer to chunk length - fill with max length of buffer
+ *
+ * This is called when the user code is notified client http data has arrived.
+ * The user code may choose to delay calling it to consume the data, for example
+ * waiting until an onward connection is writeable.
+ *
+ * For non-chunked connections, up to len bytes of buf are filled with the
+ * received content.  len is set to the actual amount filled before return.
+ *
+ * For chunked connections, the linear buffer content contains the chunking
+ * headers and it cannot be passed in one lump.  Instead, this function will
+ * call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the
+ * chunk start and len set to the chunk length.  There will be as many calls
+ * as there are chunks or partial chunks in the buffer.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_client_read(struct lws *wsi, char **buf, int *len);
+
+/**
+ * lws_http_client_http_response() - get last HTTP response code
+ *
+ * \param wsi: client connection
+ *
+ * Returns the last server response code, eg, 200 for client http connections.
+ *
+ * You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP
+ * callback, because after that the memory reserved for storing the related
+ * headers is freed and this value is lost.
+ */
+LWS_VISIBLE LWS_EXTERN unsigned int
+lws_http_client_http_response(struct lws *wsi);
+
+/**
+ * lws_tls_client_vhost_extra_cert_mem() - add more certs to vh client tls ctx
+ *
+ * \param vh: the vhost to give more client certs to
+ * \param der: pointer to der format additional cert
+ * \param der_len: size in bytes of der
+ *
+ * After the vhost is created with one cert for client verification, you
+ * can add additional, eg, intermediate, certs to the client tls context
+ * of the vhost, for use with validating the incoming server cert(s).
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh,
+		const uint8_t *der, size_t der_len);
+
+/**
+ * lws_client_http_body_pending() - control if client connection needs to send body
+ *
+ * \param wsi: client connection
+ * \param something_left_to_send: nonzero if need to send more body, 0 (default)
+ * 				if nothing more to send
+ *
+ * If you will send payload data with your HTTP client connection, eg, for POST,
+ * when you set the related http headers in
+ * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call
+ * this API with something_left_to_send nonzero, and call
+ * lws_callback_on_writable(wsi);
+ *
+ * After sending the headers, lws will call your callback with
+ * LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable.  You can send the
+ * next part of the http body payload, calling lws_callback_on_writable(wsi);
+ * if there is more to come, or lws_client_http_body_pending(wsi, 0); to
+ * let lws know the last part is sent and the connection can move on.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_client_http_body_pending(struct lws *wsi, int something_left_to_send);
+
+/**
+ * lws_client_http_multipart() - issue appropriate multipart header or trailer
+ *
+ * \param wsi: client connection
+ * \param name: multipart header name field, or NULL if end of multipart
+ * \param filename: multipart header filename field, or NULL if none
+ * \param content_type: multipart header content-type part, or NULL if none
+ * \param p: pointer to position in buffer
+ * \param end: end of buffer
+ *
+ * This issues a multipart mime boundary, or terminator if name = NULL.
+ *
+ * Returns 0 if OK or nonzero if couldn't fit in buffer
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_client_http_multipart(struct lws *wsi, const char *name,
+			  const char *filename, const char *content_type,
+			  char **p, char *end);
+
+/**
+ * lws_http_basic_auth_gen() - helper to encode client basic auth string
+ *
+ * \param user: user name
+ * \param pw: password
+ * \param buf: where to store base64 result
+ * \param len: max usable size of buf
+ *
+ * Encodes a username and password in Basic Auth format for use with the
+ * Authorization header.  On return, buf is filled with something like
+ * "Basic QWxhZGRpbjpPcGVuU2VzYW1l".
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_basic_auth_gen(const char *user, const char *pw, char *buf, size_t len);
+
+///@}

+ 1215 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-context-vhost.h

@@ -0,0 +1,1215 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup context-and-vhost context and vhost related functions
+ * ##Context and Vhost releated functions
+ * \ingroup lwsapi
+ *
+ *
+ *  LWS requires that there is one context, in which you may define multiple
+ *  vhosts.  Each vhost is a virtual host, with either its own listen port
+ *  or sharing an existing one.  Each vhost has its own SSL context that can
+ *  be set up individually or left disabled.
+ *
+ *  If you don't care about multiple "site" support, you can ignore it and
+ *  lws will create a single default vhost at context creation time.
+ */
+///@{
+
+/*
+ * NOTE: These public enums are part of the abi.  If you want to add one,
+ * add it at where specified so existing users are unaffected.
+ */
+
+
+#define LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT	 ((1ll << 1) | \
+								  (1ll << 12))
+	/**< (VH) Don't allow the connection unless the client has a
+	 * client cert that we recognize; provides
+	 * LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */
+#define LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME		  (1ll << 2)
+	/**< (CTX) Don't try to get the server's hostname */
+#define LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT		 ((1ll << 3) | \
+								  (1ll << 12))
+	/**< (VH) Allow non-SSL (plaintext) connections on the same
+	 * port as SSL is listening.  If combined with
+	 * LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS it will try to
+	 * force http connections on an https listener (eg, http://x.com:443) to
+	 * redirect to an explicit https connection (eg, https://x.com)
+	 */
+#define LWS_SERVER_OPTION_LIBEV					 (1ll << 4)
+	/**< (CTX) Use libev event loop */
+#define LWS_SERVER_OPTION_DISABLE_IPV6				 (1ll << 5)
+	/**< (VH) Disable IPV6 support */
+#define LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS			 (1ll << 6)
+	/**< (VH) Don't load OS CA certs, you will need to load your
+	 * own CA cert(s) */
+#define LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED		 (1ll << 7)
+	/**< (VH) Accept connections with no valid Cert (eg, selfsigned) */
+#define LWS_SERVER_OPTION_VALIDATE_UTF8				 (1ll << 8)
+	/**< (VH) Check UT-8 correctness */
+#define LWS_SERVER_OPTION_SSL_ECDH				 ((1ll << 9) | \
+								  (1ll << 12))
+	/**< (VH)  initialize ECDH ciphers */
+#define LWS_SERVER_OPTION_LIBUV					(1ll << 10)
+	/**< (CTX)  Use libuv event loop */
+#define LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS		((1ll << 11) |\
+								 (1ll << 12))
+	/**< (VH) Use an http redirect to force the client to ask for https.
+	 * Notice if your http server issues the STS header and the client has
+	 * ever seen that, the client will fail the http connection before it
+	 * can actually do the redirect.
+	 *
+	 * Combine with LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS to handle, eg,
+	 * http://x.com:443 -> https://x.com
+	 *
+	 * (deprecated: use mount redirection) */
+#define LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT			 (1ll << 12)
+	/**< (CTX) Initialize the SSL library at all */
+#define LWS_SERVER_OPTION_EXPLICIT_VHOSTS			 (1ll << 13)
+	/**< (CTX) Only create the context when calling context
+	 * create api, implies user code will create its own vhosts */
+#define LWS_SERVER_OPTION_UNIX_SOCK				 (1ll << 14)
+	/**< (VH) Use Unix socket */
+#define LWS_SERVER_OPTION_STS					 (1ll << 15)
+	/**< (VH) Send Strict Transport Security header, making
+	 * clients subsequently go to https even if user asked for http */
+#define LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY			 (1ll << 16)
+	/**< (VH) Enable LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE to take effect */
+#define LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE			 (1ll << 17)
+	/**< (VH) if set, only ipv6 allowed on the vhost */
+#define LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN		 (1ll << 18)
+	/**< (CTX) Libuv only: Do not spin on SIGSEGV / SIGFPE.  A segfault
+	 * normally makes the lib spin so you can attach a debugger to it
+	 * even if it happened without a debugger in place.  You can disable
+	 * that by giving this option.
+	 */
+#define LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN			 (1ll << 19)
+	/**< For backwards-compatibility reasons, by default
+	 * lws prepends "http://" to the origin you give in the client
+	 * connection info struct.  If you give this flag when you create
+	 * the context, only the string you give in the client connect
+	 * info for .origin (if any) will be used directly.
+	 */
+#define LWS_SERVER_OPTION_FALLBACK_TO_RAW /* use below name */	 (1ll << 20)
+#define LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG (1ll << 20)
+	/**< (VH) if invalid http is coming in the first line, then abandon
+	 * trying to treat the connection as http, and belatedly apply the
+	 * .listen_accept_role / .listen_accept_protocol info struct members to
+	 * the connection.  If they are NULL, for backwards-compatibility the
+	 * connection is bound to "raw-skt" role, and in order of priority:
+	 * 1) the vh protocol with a pvo named "raw", 2) the vh protocol with a
+	 * pvo named "default", or 3) protocols[0].
+	 *
+	 * Must be combined with LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT
+	 * to work with a socket listening with tls.
+	 */
+
+#define LWS_SERVER_OPTION_LIBEVENT				(1ll << 21)
+	/**< (CTX) Use libevent event loop */
+
+#define LWS_SERVER_OPTION_ONLY_RAW /* Use below name instead */	(1ll << 22)
+#define LWS_SERVER_OPTION_ADOPT_APPLY_LISTEN_ACCEPT_CONFIG	(1ll << 22)
+	/**< (VH) All connections to this vhost / port are bound to the
+	 * role and protocol given in .listen_accept_role /
+	 * .listen_accept_protocol.
+	 *
+	 * If those explicit user-controlled names are NULL, for backwards-
+	 * compatibility the connection is bound to "raw-skt" role, and in order
+	 * of priority: 1) the vh protocol with a pvo named "raw", 2) the vh
+	 * protocol with a pvo named "default", or 3) protocols[0].
+	 *
+	 * It's much preferred to specify the role + protocol using the
+	 * .listen_accept_role and .listen_accept_protocol in the info struct.
+	 */
+#define LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE			(1ll << 23)
+	/**< (VH) Set to allow multiple listen sockets on one interface +
+	 * address + port.  The default is to strictly allow only one
+	 * listen socket at a time.  This is automatically selected if you
+	 * have multiple service threads.  Linux only.
+	 */
+#define LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX			(1ll << 24)
+	/**< (VH) Force setting up the vhost SSL_CTX, even though the user
+	 * code doesn't explicitly provide a cert in the info struct.  It
+	 * implies the user code is going to provide a cert at the
+	 * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS callback, which
+	 * provides the vhost SSL_CTX * in the user parameter.
+	 */
+#define LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT			(1ll << 25)
+	/**< (VH) You probably don't want this.  It forces this vhost to not
+	 * call LWS_CALLBACK_PROTOCOL_INIT on its protocols.  It's used in the
+	 * special case of a temporary vhost bound to a single protocol.
+	 */
+#define LWS_SERVER_OPTION_IGNORE_MISSING_CERT			(1ll << 26)
+	/**< (VH) Don't fail if the vhost TLS cert or key are missing, just
+	 * continue.  The vhost won't be able to serve anything, but if for
+	 * example the ACME plugin was configured to fetch a cert, this lets
+	 * you bootstrap your vhost from having no cert to start with.
+	 */
+#define LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK		(1ll << 27)
+	/**< (VH) On this vhost, if the connection is being upgraded, insist
+	 * that there's a Host: header and that the contents match the vhost
+	 * name + port (443 / 80 are assumed if no :port given based on if the
+	 * connection is using TLS).
+	 *
+	 * By default, without this flag, on upgrade lws just checks that the
+	 * Host: header was given without checking the contents... this is to
+	 * allow lax hostname mappings like localhost / 127.0.0.1, and CNAME
+	 * mappings like www.mysite.com / mysite.com
+	 */
+#define LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE (1ll << 28)
+	/**< (VH) Send lws default HTTP headers recommended by Mozilla
+	 * Observatory for security.  This is a helper option that sends canned
+	 * headers on each http response enabling a VERY strict Content Security
+	 * Policy.  The policy is so strict, for example it won't let the page
+	 * run its own inline JS nor show images or take CSS from a different
+	 * server.  In many cases your JS only comes from your server as do the
+	 * image sources and CSS, so that is what you want... attackers hoping
+	 * to inject JS into your DOM are completely out of luck since even if
+	 * they succeed, it will be rejected for execution by the browser
+	 * according to the strict CSP.  In other cases you have to deviate from
+	 * the complete strictness, in which case don't use this flag: use the
+	 * .headers member in the vhost init described in struct
+	 * lws_context_creation_info instead to send the adapted headers
+	 * yourself.
+	 */
+
+#define LWS_SERVER_OPTION_ALLOW_HTTP_ON_HTTPS_LISTENER		 (1ll << 29)
+	/**< (VH) If you really want to allow HTTP connections on a tls
+	 * listener, you can do it with this combined with
+	 * LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT.  But this is allowing
+	 * accidental loss of the security assurances provided by tls depending
+	 * on the client using http when he meant https... it's not
+	 * recommended.
+	 */
+#define LWS_SERVER_OPTION_FAIL_UPON_UNABLE_TO_BIND		 (1ll << 30)
+	/**< (VH) When instantiating a new vhost and the specified port is
+	 * already in use, a null value shall be return to signal the error.
+	 */
+
+#define LWS_SERVER_OPTION_H2_JUST_FIX_WINDOW_UPDATE_OVERFLOW	 (1ll << 31)
+	/**< (VH) Indicates the connections using this vhost should ignore
+	 * h2 WINDOW_UPDATE from broken peers and fix them up */
+
+#define LWS_SERVER_OPTION_VH_H2_HALF_CLOSED_LONG_POLL		 (1ll << 32)
+	/**< (VH) Tell the vhost to treat half-closed remote clients as
+	 * entered into an immortal (ie, not subject to normal timeouts) long
+	 * poll mode.
+	 */
+
+#define LWS_SERVER_OPTION_GLIB					 (1ll << 33)
+	/**< (CTX) Use glib event loop */
+
+#define LWS_SERVER_OPTION_H2_PRIOR_KNOWLEDGE			 (1ll << 34)
+	/**< (VH) Tell the vhost to treat plain text http connections as
+	 * H2 with prior knowledge (no upgrade request involved)
+	 */
+
+#define LWS_SERVER_OPTION_NO_LWS_SYSTEM_STATES			 (1ll << 35)
+	/**< (CTX) Disable lws_system state, eg, because we are a secure streams
+	 * proxy client that is not trying to track system state by itself. */
+
+	/****** add new things just above ---^ ******/
+
+
+#define lws_check_opt(c, f) ((((uint64_t)c) & ((uint64_t)f)) == ((uint64_t)f))
+
+struct lws_plat_file_ops;
+struct lws_ss_policy;
+struct lws_ss_plugin;
+
+typedef int (*lws_context_ready_cb_t)(struct lws_context *context);
+
+typedef int (*lws_peer_limits_notify_t)(struct lws_context *ctx,
+					lws_sockfd_type sockfd,
+					lws_sockaddr46 *sa46);
+
+/** struct lws_context_creation_info - parameters to create context and /or vhost with
+ *
+ * This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHOSTS
+ * is not given, then for backwards compatibility one vhost is created at
+ * context-creation time using the info from this struct.
+ *
+ * If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are created
+ * at the same time as the context, they are expected to be created afterwards.
+ */
+struct lws_context_creation_info {
+#if defined(LWS_WITH_NETWORK)
+	const char *iface;
+	/**< VHOST: NULL to bind the listen socket to all interfaces, or the
+	 * interface name, eg, "eth2"
+	 * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is
+	 * the pathname of a UNIX domain socket. you can use the UNIX domain
+	 * sockets in abstract namespace, by prepending an at symbol to the
+	 * socket name. */
+	const struct lws_protocols *protocols;
+	/**< VHOST: Array of structures listing supported protocols and a
+	 * protocol-specific callback for each one.  The list is ended with an
+	 * entry that has a NULL callback pointer.  SEE ALSO .pprotocols below,
+	 * which gives an alternative way to provide an array of pointers to
+	 * protocol structs. */
+#if defined(LWS_ROLE_WS)
+	const struct lws_extension *extensions;
+	/**< VHOST: NULL or array of lws_extension structs listing the
+	 * extensions this context supports. */
+#endif
+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
+	const struct lws_token_limits *token_limits;
+	/**< CONTEXT: NULL or struct lws_token_limits pointer which is
+	 * initialized with a token length limit for each possible WSI_TOKEN_ */
+	const char *http_proxy_address;
+	/**< VHOST: If non-NULL, attempts to proxy via the given address.
+	 * If proxy auth is required, use format
+	 * "username:password\@server:port" */
+	const struct lws_protocol_vhost_options *headers;
+		/**< VHOST: pointer to optional linked list of per-vhost
+		 * canned headers that are added to server responses */
+
+	const struct lws_protocol_vhost_options *reject_service_keywords;
+	/**< CONTEXT: Optional list of keywords and rejection codes + text.
+	 *
+	 * The keywords are checked for existing in the user agent string.
+	 *
+	 * Eg, "badrobot" "404 Not Found"
+	 */
+	const struct lws_protocol_vhost_options *pvo;
+	/**< VHOST: pointer to optional linked list of per-vhost
+	 * options made accessible to protocols */
+	const char *log_filepath;
+	/**< VHOST: filepath to append logs to... this is opened before
+	 *		any dropping of initial privileges */
+	const struct lws_http_mount *mounts;
+	/**< VHOST: optional linked list of mounts for this vhost */
+	const char *server_string;
+	/**< CONTEXT: string used in HTTP headers to identify server
+	 * software, if NULL, "libwebsockets". */
+
+	const char *error_document_404;
+	/**< VHOST: If non-NULL, when asked to serve a non-existent file,
+	 *          lws attempts to server this url path instead.  Eg,
+	 *          "/404.html" */
+	int port;
+	/**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress
+	 * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are
+	 * writing a server but you are using \ref sock-adopt instead of the
+	 * built-in listener.
+	 *
+	 * You can also set port to 0, in which case the kernel will pick
+	 * a random port that is not already in use.  You can find out what
+	 * port the vhost is listening on using lws_get_vhost_listen_port() */
+
+	unsigned int http_proxy_port;
+	/**< VHOST: If http_proxy_address was non-NULL, uses this port */
+	unsigned int max_http_header_data2;
+	/**< CONTEXT: if max_http_header_data is 0 and this
+	 * is nonzero, this will be used in place of the default.  It's
+	 * like this for compatibility with the original short version,
+	 * this is unsigned int length. */
+	unsigned int max_http_header_pool2;
+	/**< CONTEXT: if max_http_header_pool is 0 and this
+	 * is nonzero, this will be used in place of the default.  It's
+	 * like this for compatibility with the original short version:
+	 * this is unsigned int length. */
+
+	int keepalive_timeout;
+	/**< VHOST: (default = 0 = 5s, 31s for http/2) seconds to allow remote
+	 * client to hold on to an idle HTTP/1.1 connection.  Timeout lifetime
+	 * applied to idle h2 network connections */
+	uint32_t	http2_settings[7];
+	/**< VHOST:  if http2_settings[0] is nonzero, the values given in
+	 *	      http2_settings[1]..[6] are used instead of the lws
+	 *	      platform default values.
+	 *	      Just leave all at 0 if you don't care.
+	 */
+
+	unsigned short max_http_header_data;
+	/**< CONTEXT: The max amount of header payload that can be handled
+	 * in an http request (unrecognized header payload is dropped) */
+	unsigned short max_http_header_pool;
+	/**< CONTEXT: The max number of connections with http headers that
+	 * can be processed simultaneously (the corresponding memory is
+	 * allocated and deallocated dynamically as needed).  If the pool is
+	 * fully busy new incoming connections must wait for accept until one
+	 * becomes free. 0 = allow as many ah as number of availble fds for
+	 * the process */
+
+#endif
+
+#if defined(LWS_WITH_TLS)
+	const char *ssl_private_key_password;
+	/**< VHOST: NULL or the passphrase needed for the private key. (For
+	 * backwards compatibility, this can also be used to pass the client
+	 * cert passphrase when setting up a vhost client SSL context, but it is
+	 * preferred to use .client_ssl_private_key_password for that.) */
+	const char *ssl_cert_filepath;
+	/**< VHOST: If libwebsockets was compiled to use ssl, and you want
+	 * to listen using SSL, set to the filepath to fetch the
+	 * server cert from, otherwise NULL for unencrypted.  (For backwards
+	 * compatibility, this can also be used to pass the client certificate
+	 * when setting up a vhost client SSL context, but it is preferred to
+	 * use .client_ssl_cert_filepath for that.)
+	 *
+	 * Notice you can alternatively set a single DER or PEM from a memory
+	 * buffer as the vhost tls cert using \p server_ssl_cert_mem and
+	 * \p server_ssl_cert_mem_len.
+	 */
+	const char *ssl_private_key_filepath;
+	/**<  VHOST: filepath to private key if wanting SSL mode;
+	 * if this is set to NULL but ssl_cert_filepath is set, the
+	 * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called
+	 * to allow setting of the private key directly via openSSL
+	 * library calls.   (For backwards compatibility, this can also be used
+	 * to pass the client cert private key filepath when setting up a
+	 * vhost client SSL context, but it is preferred to use
+	 * .client_ssl_private_key_filepath for that.)
+	 *
+	 * Notice you can alternatively set a DER or PEM private key from a
+	 * memory buffer as the vhost tls private key using
+	 * \p server_ssl_private_key_mem and \p server_ssl_private_key_mem_len.
+	 */
+	const char *ssl_ca_filepath;
+	/**< VHOST: CA certificate filepath or NULL.  (For backwards
+	 * compatibility, this can also be used to pass the client CA
+	 * filepath when setting up a vhost client SSL context,
+	 * but it is preferred to use .client_ssl_ca_filepath for that.)
+	 *
+	 * Notice you can alternatively set a DER or PEM CA cert from a memory
+	 * buffer using \p server_ssl_ca_mem and \p server_ssl_ca_mem_len.
+	 */
+	const char *ssl_cipher_list;
+	/**< VHOST: List of valid ciphers to use ON TLS1.2 AND LOWER ONLY (eg,
+	 * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
+	 * or you can leave it as NULL to get "DEFAULT" (For backwards
+	 * compatibility, this can also be used to pass the client cipher
+	 * list when setting up a vhost client SSL context,
+	 * but it is preferred to use .client_ssl_cipher_list for that.)
+	 * SEE .tls1_3_plus_cipher_list and .client_tls_1_3_plus_cipher_list
+	 * for the equivalent for tls1.3.
+	 */
+	const char *ecdh_curve;
+	/**< VHOST: if NULL, defaults to initializing server with
+	 *   "prime256v1" */
+	const char *tls1_3_plus_cipher_list;
+	/**< VHOST: List of valid ciphers to use for incoming server connections
+	 * ON TLS1.3 AND ABOVE (eg, "TLS_CHACHA20_POLY1305_SHA256" on this vhost
+	 * or you can leave it as NULL to get "DEFAULT".
+	 * SEE .client_tls_1_3_plus_cipher_list to do the same on the vhost
+	 * client SSL_CTX.
+	 */
+
+	const void *server_ssl_cert_mem;
+	/**< VHOST: Alternative for \p ssl_cert_filepath that allows setting
+	 * from memory instead of from a file.  At most one of
+	 * \p ssl_cert_filepath or \p server_ssl_cert_mem should be non-NULL. */
+	const void *server_ssl_private_key_mem;
+	/**<  VHOST: Alternative for \p ssl_private_key_filepath allowing
+	 * init from a private key in memory instead of a file.  At most one
+	 * of \p ssl_private_key_filepath or \p server_ssl_private_key_mem
+	 * should be non-NULL. */
+	const void *server_ssl_ca_mem;
+	/**< VHOST: Alternative for \p ssl_ca_filepath allowing
+	 * init from a CA cert in memory instead of a file.  At most one
+	 * of \p ssl_ca_filepath or \p server_ssl_ca_mem should be non-NULL. */
+
+	long ssl_options_set;
+	/**< VHOST: Any bits set here will be set as server SSL options */
+	long ssl_options_clear;
+	/**< VHOST: Any bits set here will be cleared as server SSL options */
+	int simultaneous_ssl_restriction;
+	/**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions
+	 * possible.*/
+	int ssl_info_event_mask;
+	/**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO
+	 * callback for connections on this vhost.  The mask values are of
+	 * the form SSL_CB_ALERT, defined in openssl/ssl.h.  The default of
+	 * 0 means no info events will be reported.
+	 */
+	unsigned int server_ssl_cert_mem_len;
+	/**< VHOST: Server SSL context init: length of server_ssl_cert_mem in
+	 * bytes */
+	unsigned int server_ssl_private_key_mem_len;
+	/**< VHOST: length of \p server_ssl_private_key_mem in memory */
+	unsigned int server_ssl_ca_mem_len;
+	/**< VHOST: length of \p server_ssl_ca_mem in memory */
+
+	const char *alpn;
+	/**< CONTEXT: If non-NULL, default list of advertised alpn, comma-
+	 *	      separated
+	 *
+	 *     VHOST: If non-NULL, per-vhost list of advertised alpn, comma-
+	 *	      separated
+	 */
+
+
+#if defined(LWS_WITH_CLIENT)
+	const char *client_ssl_private_key_password;
+	/**< VHOST: Client SSL context init: NULL or the passphrase needed
+	 * for the private key */
+	const char *client_ssl_cert_filepath;
+	/**< VHOST: Client SSL context init: The certificate the client
+	 * should present to the peer on connection */
+	const void *client_ssl_cert_mem;
+	/**< VHOST: Client SSL context init: client certificate memory buffer or
+	 * NULL... use this to load client cert from memory instead of file */
+	unsigned int client_ssl_cert_mem_len;
+	/**< VHOST: Client SSL context init: length of client_ssl_cert_mem in
+	 * bytes */
+	const char *client_ssl_private_key_filepath;
+	/**<  VHOST: Client SSL context init: filepath to client private key
+	 * if this is set to NULL but client_ssl_cert_filepath is set, you
+	 * can handle the LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS
+	 * callback of protocols[0] to allow setting of the private key directly
+	 * via tls library calls */
+	const void *client_ssl_key_mem;
+	/**< VHOST: Client SSL context init: client key memory buffer or
+	 * NULL... use this to load client key from memory instead of file */
+	const char *client_ssl_ca_filepath;
+	/**< VHOST: Client SSL context init: CA certificate filepath or NULL */
+	const void *client_ssl_ca_mem;
+	/**< VHOST: Client SSL context init: CA certificate memory buffer or
+	 * NULL... use this to load CA cert from memory instead of file */
+
+	const char *client_ssl_cipher_list;
+	/**< VHOST: Client SSL context init: List of valid ciphers to use (eg,
+	* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
+	* or you can leave it as NULL to get "DEFAULT" */
+	const char *client_tls_1_3_plus_cipher_list;
+	/**< VHOST: List of valid ciphers to use for outgoing client connections
+	 * ON TLS1.3 AND ABOVE on this vhost (eg,
+	 * "TLS_CHACHA20_POLY1305_SHA256") or you can leave it as NULL to get
+	 * "DEFAULT".
+	 */
+
+	long ssl_client_options_set;
+	/**< VHOST: Any bits set here will be set as CLIENT SSL options */
+	long ssl_client_options_clear;
+	/**< VHOST: Any bits set here will be cleared as CLIENT SSL options */
+
+
+	unsigned int client_ssl_ca_mem_len;
+	/**< VHOST: Client SSL context init: length of client_ssl_ca_mem in
+	 * bytes */
+	unsigned int client_ssl_key_mem_len;
+	/**< VHOST: Client SSL context init: length of client_ssl_key_mem in
+	 * bytes */
+
+#endif
+
+#if !defined(LWS_WITH_MBEDTLS)
+	SSL_CTX *provided_client_ssl_ctx;
+	/**< CONTEXT: If non-null, swap out libwebsockets ssl
+	  * implementation for the one provided by provided_ssl_ctx.
+	  * Libwebsockets no longer is responsible for freeing the context
+	  * if this option is selected. */
+#endif
+#endif
+
+	int ka_time;
+	/**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive
+	 * timeout to all libwebsocket sockets, client or server */
+	int ka_probes;
+	/**< CONTEXT: if ka_time was nonzero, after the timeout expires how many
+	 * times to try to get a response from the peer before giving up
+	 * and killing the connection */
+	int ka_interval;
+	/**< CONTEXT: if ka_time was nonzero, how long to wait before each ka_probes
+	 * attempt */
+	unsigned int timeout_secs;
+	/**< VHOST: various processes involving network roundtrips in the
+	 * library are protected from hanging forever by timeouts.  If
+	 * nonzero, this member lets you set the timeout used in seconds.
+	 * Otherwise a default timeout is used. */
+	unsigned int connect_timeout_secs;
+	/**< VHOST: client connections have this long to find a working server
+	 * from the DNS results, or the whole connection times out.  If zero,
+	 * a default timeout is used */
+	int bind_iface;
+	/**< VHOST: nonzero to strictly bind sockets to the interface name in
+	 * .iface (eg, "eth2"), using SO_BIND_TO_DEVICE.
+	 *
+	 * Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW
+	 * capability.
+	 *
+	 * Notice that common things like access network interface IP from
+	 * your local machine use your lo / loopback interface and will be
+	 * disallowed by this.
+	 */
+	unsigned int timeout_secs_ah_idle;
+	/**< VHOST: seconds to allow a client to hold an ah without using it.
+	 * 0 defaults to 10s. */
+#endif /* WITH_NETWORK */
+
+	int gid;
+	/**< CONTEXT: group id to change to after setting listen socket,
+	 *   or -1. See also .username below. */
+	int uid;
+	/**< CONTEXT: user id to change to after setting listen socket,
+	 *   or -1.  See also .groupname below. */
+	uint64_t options;
+	/**< VHOST + CONTEXT: 0, or LWS_SERVER_OPTION_... bitfields */
+	void *user;
+	/**< VHOST + CONTEXT: optional user pointer that will be associated
+	 * with the context when creating the context (and can be retrieved by
+	 * lws_context_user(context), or with the vhost when creating the vhost
+	 * (and can be retrieved by lws_vhost_user(vhost)).  You will need to
+	 * use LWS_SERVER_OPTION_EXPLICIT_VHOSTS and create the vhost separately
+	 * if you care about giving the context and vhost different user pointer
+	 * values.
+	 */
+	unsigned int count_threads;
+	/**< CONTEXT: how many contexts to create in an array, 0 = 1 */
+	unsigned int fd_limit_per_thread;
+	/**< CONTEXT: nonzero means restrict each service thread to this
+	 * many fds, 0 means the default which is divide the process fd
+	 * limit by the number of threads.
+	 *
+	 * Note if this is nonzero, and fd_limit_per_thread multiplied by the
+	 * number of service threads is less than the process ulimit, then lws
+	 * restricts internal lookup table allocation to the smaller size, and
+	 * switches to a less efficient lookup scheme.  You should use this to
+	 * trade off speed against memory usage if you know the lws context
+	 * will only use a handful of fds.
+	 *
+	 * Bear in mind lws may use some fds internally, for example for the
+	 * cancel pipe, so you may need to allow for some extras for normal
+	 * operation.
+	 */
+	const char *vhost_name;
+	/**< VHOST: name of vhost, must match external DNS name used to
+	 * access the site, like "warmcat.com" as it's used to match
+	 * Host: header and / or SNI name for SSL. */
+#if defined(LWS_WITH_PLUGINS)
+	const char * const *plugin_dirs;
+	/**< CONTEXT: NULL, or NULL-terminated array of directories to
+	 * scan for lws protocol plugins at context creation time */
+#endif
+	void *external_baggage_free_on_destroy;
+	/**< CONTEXT: NULL, or pointer to something externally malloc'd, that
+	 * should be freed when the context is destroyed.  This allows you to
+	 * automatically sync the freeing action to the context destruction
+	 * action, so there is no need for an external free() if the context
+	 * succeeded to create.
+	 */
+
+
+	unsigned int pt_serv_buf_size;
+	/**< CONTEXT: 0 = default of 4096.  This buffer is used by
+	 * various service related features including file serving, it
+	 * defines the max chunk of file that can be sent at once.
+	 * At the risk of lws having to buffer failed large sends, it
+	 * can be increased to, eg, 128KiB to improve throughput. */
+#if defined(LWS_WITH_FILE_OPS)
+	const struct lws_plat_file_ops *fops;
+	/**< CONTEXT: NULL, or pointer to an array of fops structs, terminated
+	 * by a sentinel with NULL .open.
+	 *
+	 * If NULL, lws provides just the platform file operations struct for
+	 * backwards compatibility.
+	 */
+#endif
+
+#if defined(LWS_WITH_SOCKS5)
+	const char *socks_proxy_address;
+	/**< VHOST: If non-NULL, attempts to proxy via the given address.
+	 * If proxy auth is required, use format
+	 * "username:password\@server:port" */
+	unsigned int socks_proxy_port;
+	/**< VHOST: If socks_proxy_address was non-NULL, uses this port
+	 * if nonzero, otherwise requires "server:port" in .socks_proxy_address
+	 */
+#endif
+
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+	cap_value_t caps[4];
+	/**< CONTEXT: array holding Linux capabilities you want to
+	 * continue to be available to the server after it transitions
+	 * to a noprivileged user.  Usually none are needed but for, eg,
+	 * .bind_iface, CAP_NET_RAW is required.  This gives you a way
+	 * to still have the capability but drop root.
+	 */
+	char count_caps;
+	/**< CONTEXT: count of Linux capabilities in .caps[].  0 means
+	 * no capabilities will be inherited from root (the default) */
+#endif
+	void **foreign_loops;
+	/**< CONTEXT: This is ignored if the context is not being started with
+	 *		an event loop, ie, .options has a flag like
+	 *		LWS_SERVER_OPTION_LIBUV.
+	 *
+	 *		NULL indicates lws should start its own even loop for
+	 *		each service thread, and deal with closing the loops
+	 *		when the context is destroyed.
+	 *
+	 *		Non-NULL means it points to an array of external
+	 *		("foreign") event loops that are to be used in turn for
+	 *		each service thread.  In the default case of 1 service
+	 *		thread, it can just point to one foreign event loop.
+	 */
+	void (*signal_cb)(void *event_lib_handle, int signum);
+	/**< CONTEXT: NULL: default signal handling.  Otherwise this receives
+	 *		the signal handler callback.  event_lib_handle is the
+	 *		native event library signal handle, eg uv_signal_t *
+	 *		for libuv.
+	 */
+	struct lws_context **pcontext;
+	/**< CONTEXT: if non-NULL, at the end of context destroy processing,
+	 * the pointer pointed to by pcontext is written with NULL.  You can
+	 * use this to let foreign event loops know that lws context destruction
+	 * is fully completed.
+	 */
+	void (*finalize)(struct lws_vhost *vh, void *arg);
+	/**< VHOST: NULL, or pointer to function that will be called back
+	 *	    when the vhost is just about to be freed.  The arg parameter
+	 *	    will be set to whatever finalize_arg is below.
+	 */
+	void *finalize_arg;
+	/**< VHOST: opaque pointer lws ignores but passes to the finalize
+	 *	    callback.  If you don't care, leave it NULL.
+	 */
+	const char *listen_accept_role;
+	/**< VHOST: NULL for default, or force accepted incoming connections to
+	 * bind to this role.  Uses the role names from their ops struct, eg,
+	 * "raw-skt".
+	 */
+	const char *listen_accept_protocol;
+	/**< VHOST: NULL for default, or force accepted incoming connections to
+	 * bind to this vhost protocol name.
+	 */
+	const struct lws_protocols **pprotocols;
+	/**< VHOST: NULL: use .protocols, otherwise ignore .protocols and use
+	 * this array of pointers to protocols structs.  The end of the array
+	 * is marked by a NULL pointer.
+	 *
+	 * This is preferred over .protocols, because it allows the protocol
+	 * struct to be opaquely defined elsewhere, with just a pointer to it
+	 * needed to create the context with it.  .protocols requires also
+	 * the type of the user data to be known so its size can be given.
+	 */
+
+	const char *username; /**< CONTEXT: string username for post-init
+	 * permissions.  Like .uid but takes a string username. */
+	const char *groupname; /**< CONTEXT: string groupname for post-init
+	 * permissions.  Like .gid but takes a string groupname. */
+	const char *unix_socket_perms; /**< VHOST: if your vhost is listening
+	 * on a unix socket, you can give a "username:groupname" string here
+	 * to control the owner:group it's created with.  It's always created
+	 * with 0660 mode. */
+	const lws_system_ops_t *system_ops;
+	/**< CONTEXT: hook up lws_system_ apis to system-specific
+	 * implementations */
+#if defined(LWS_WITH_DETAILED_LATENCY)
+	det_lat_buf_cb_t detailed_latency_cb;
+	/**< CONTEXT: NULL, or callback to receive detailed latency information
+	 * collected for each read and write */
+	const char *detailed_latency_filepath;
+	/**< CONTEXT: NULL, or filepath to put latency data into */
+#endif
+	const lws_retry_bo_t *retry_and_idle_policy;
+	/**< VHOST: optional retry and idle policy to apply to this vhost.
+	 *   Currently only the idle parts are applied to the connections.
+	 */
+#if defined(LWS_WITH_SYS_STATE)
+	lws_state_notify_link_t * const *register_notifier_list;
+	/**< CONTEXT: NULL, or pointer to an array of notifiers that should
+	 * be registered during context creation, so they can see state change
+	 * events from very early on.  The array should end with a NULL. */
+#endif
+#if defined(LWS_WITH_SECURE_STREAMS)
+#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
+	const struct lws_ss_policy *pss_policies; /**< CONTEXT: point to first
+	 * in a linked-list of streamtype policies prepared by user code */
+#else
+	const char *pss_policies_json; /**< CONTEXT: point to a string
+	 * containing a JSON description of the secure streams policies.  Set
+	 * to NULL if not using Secure Streams. */
+#endif
+	const struct lws_ss_plugin **pss_plugins; /**< CONTEXT: point to an array
+	 * of pointers to plugin structs here, terminated with a NULL ptr.
+	 * Set to NULL if not using Secure Streams. */
+	const char *ss_proxy_bind; /**< CONTEXT: NULL, or: ss_proxy_port == 0:
+	 * point to a string giving the Unix Domain Socket address to use (start
+	 * with @ for abstract namespace), ss_proxy_port nonzero: set the
+	 * network interface address (not name, it's ambiguous for ipv4/6) to
+	 * bind the tcp connection to the proxy to */
+	const char *ss_proxy_address; /**< CONTEXT: NULL, or if ss_proxy_port
+	 * nonzero: the tcp address of the ss proxy to connect to */
+	uint16_t ss_proxy_port; /* 0 = if connecting to ss proxy, do it via a
+	 * Unix Domain Socket, "[email protected]" if ss_proxy_bind is NULL else
+	 * the socket path given in ss_proxy_bind (start it with a + or +@);
+	 * nonzero means connect via a tcp socket to the tcp address in
+	 * ss_proxy_bind and the given port */
+#endif
+
+	int rlimit_nofile;
+	/**< 0 = inherit the initial ulimit for files / sockets from the startup
+	 * environment.  Nonzero = try to set the limit for this process.
+	 */
+#if defined(LWS_WITH_PEER_LIMITS)
+	lws_peer_limits_notify_t pl_notify_cb;
+	/**< CONTEXT: NULL, or a callback to receive notifications each time a
+	 * connection is being dropped because of peer limits.
+	 *
+	 * The callback provides the context, and an lws_sockaddr46 with the
+	 * peer address and port.
+	 */
+	unsigned short ip_limit_ah;
+	/**< CONTEXT: max number of ah a single IP may use simultaneously
+	 *	      0 is no limit. This is a soft limit: if the limit is
+	 *	      reached, connections from that IP will wait in the ah
+	 *	      waiting list and not be able to acquire an ah until
+	 *	      a connection belonging to the IP relinquishes one it
+	 *	      already has.
+	 */
+	unsigned short ip_limit_wsi;
+	/**< CONTEXT: max number of wsi a single IP may use simultaneously.
+	 *	      0 is no limit.  This is a hard limit, connections from
+	 *	      the same IP will simply be dropped once it acquires the
+	 *	      amount of simultaneous wsi / accepted connections
+	 *	      given here.
+	 */
+
+#endif /* PEER_LIMITS */
+#if defined(LWS_WITH_UDP)
+	uint8_t udp_loss_sim_tx_pc;
+	/**< CONTEXT: percentage of udp writes we could have performed
+	 * to instead not do, in order to simulate and test udp retry flow */
+	uint8_t udp_loss_sim_rx_pc;
+	/**< CONTEXT: percentage of udp reads we actually received
+	 * to make disappear, in order to simulate and test udp retry flow */
+#endif
+
+#if defined(LWS_WITH_SYS_SMD)
+	lws_smd_notification_cb_t		early_smd_cb;
+	/**< CONTEXT: NULL, or an smd notification callback that will be registered
+	 * immediately after the smd in the context is initialized.  This ensures
+	 * you can get all notifications without having to intercept the event loop
+	 * creation, eg, when using an event library.  Other callbacks can be
+	 * registered later manually without problems.
+	 */
+	void					*early_smd_opaque;
+	lws_smd_class_t				early_smd_class_filter;
+#endif
+
+	/* Add new things just above here ---^
+	 * This is part of the ABI, don't needlessly break compatibility
+	 *
+	 * The below is to ensure later library versions with new
+	 * members added above will see 0 (default) even if the app
+	 * was not built against the newer headers.
+	 */
+
+	void *_unused[2]; /**< dummy */
+};
+
+/**
+ * lws_create_context() - Create the websocket handler
+ * \param info:	pointer to struct with parameters
+ *
+ *	This function creates the listening socket (if serving) and takes care
+ *	of all initialization in one step.
+ *
+ *	If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is
+ *	created; you're expected to create your own vhosts afterwards using
+ *	lws_create_vhost().  Otherwise a vhost named "default" is also created
+ *	using the information in the vhost-related members, for compatibility.
+ *
+ *	After initialization, it returns a struct lws_context * that
+ *	represents this server.  After calling, user code needs to take care
+ *	of calling lws_service() with the context pointer to get the
+ *	server's sockets serviced.  This must be done in the same process
+ *	context as the initialization call.
+ *
+ *	The protocol callback functions are called for a handful of events
+ *	including http requests coming in, websocket connections becoming
+ *	established, and data arriving; it's also called periodically to allow
+ *	async transmission.
+ *
+ *	HTTP requests are sent always to the FIRST protocol in protocol, since
+ *	at that time websocket protocol has not been negotiated.  Other
+ *	protocols after the first one never see any HTTP callback activity.
+ *
+ *	The server created is a simple http server by default; part of the
+ *	websocket standard is upgrading this http connection to a websocket one.
+ *
+ *	This allows the same server to provide files like scripts and favicon /
+ *	images or whatever over http and dynamic data over websockets all in
+ *	one place; they're all handled in the user callback.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_context *
+lws_create_context(const struct lws_context_creation_info *info);
+
+
+/**
+ * lws_context_destroy() - Destroy the websocket context
+ * \param context:	Websocket context
+ *
+ *	This function closes any active connections and then frees the
+ *	context.  After calling this, any further use of the context is
+ *	undefined.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_context_destroy(struct lws_context *context);
+
+typedef int (*lws_reload_func)(void);
+
+/**
+ * lws_context_deprecate() - Deprecate the websocket context
+ *
+ * \param context:	Websocket context
+ * \param cb: Callback notified when old context listen sockets are closed
+ *
+ *	This function is used on an existing context before superceding it
+ *	with a new context.
+ *
+ *	It closes any listen sockets in the context, so new connections are
+ *	not possible.
+ *
+ *	And it marks the context to be deleted when the number of active
+ *	connections into it falls to zero.
+ *
+ *	This is aimed at allowing seamless configuration reloads.
+ *
+ *	The callback cb will be called after the listen sockets are actually
+ *	closed and may be reopened.  In the callback the new context should be
+ *	configured and created.  (With libuv, socket close happens async after
+ *	more loop events).
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_context_deprecate(struct lws_context *context, lws_reload_func cb);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_context_is_deprecated(struct lws_context *context);
+
+/**
+ * lws_set_proxy() - Setups proxy to lws_context.
+ * \param vhost:	pointer to struct lws_vhost you want set proxy for
+ * \param proxy: pointer to c string containing proxy in format address:port
+ *
+ * Returns 0 if proxy string was parsed and proxy was setup.
+ * Returns -1 if proxy is NULL or has incorrect format.
+ *
+ * This is only required if your OS does not provide the http_proxy
+ * environment variable (eg, OSX)
+ *
+ *   IMPORTANT! You should call this function right after creation of the
+ *   lws_context and before call to connect. If you call this
+ *   function after connect behavior is undefined.
+ *   This function will override proxy settings made on lws_context
+ *   creation with genenv() call.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_set_proxy(struct lws_vhost *vhost, const char *proxy);
+
+/**
+ * lws_set_socks() - Setup socks to lws_context.
+ * \param vhost:	pointer to struct lws_vhost you want set socks for
+ * \param socks: pointer to c string containing socks in format address:port
+ *
+ * Returns 0 if socks string was parsed and socks was setup.
+ * Returns -1 if socks is NULL or has incorrect format.
+ *
+ * This is only required if your OS does not provide the socks_proxy
+ * environment variable (eg, OSX)
+ *
+ *   IMPORTANT! You should call this function right after creation of the
+ *   lws_context and before call to connect. If you call this
+ *   function after connect behavior is undefined.
+ *   This function will override proxy settings made on lws_context
+ *   creation with genenv() call.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_set_socks(struct lws_vhost *vhost, const char *socks);
+
+struct lws_vhost;
+
+/**
+ * lws_create_vhost() - Create a vhost (virtual server context)
+ * \param context:	pointer to result of lws_create_context()
+ * \param info:		pointer to struct with parameters
+ *
+ * This function creates a virtual server (vhost) using the vhost-related
+ * members of the info struct.  You can create many vhosts inside one context
+ * if you created the context with the option LWS_SERVER_OPTION_EXPLICIT_VHOSTS
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_vhost *
+lws_create_vhost(struct lws_context *context,
+		 const struct lws_context_creation_info *info);
+
+/**
+ * lws_vhost_destroy() - Destroy a vhost (virtual server context)
+ *
+ * \param vh:		pointer to result of lws_create_vhost()
+ *
+ * This function destroys a vhost.  Normally, if you just want to exit,
+ * then lws_destroy_context() will take care of everything.  If you want
+ * to destroy an individual vhost and all connections and allocations, you
+ * can do it with this.
+ *
+ * If the vhost has a listen sockets shared by other vhosts, it will be given
+ * to one of the vhosts sharing it rather than closed.
+ *
+ * The vhost close is staged according to the needs of the event loop, and if
+ * there are multiple service threads.  At the point the vhost itself if
+ * about to be freed, if you provided a finalize callback and optional arg at
+ * vhost creation time, it will be called just before the vhost is freed.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_vhost_destroy(struct lws_vhost *vh);
+
+/**
+ * lwsws_get_config_globals() - Parse a JSON server config file
+ * \param info:		pointer to struct with parameters
+ * \param d:		filepath of the config file
+ * \param config_strings: storage for the config strings extracted from JSON,
+ * 			  the pointer is incremented as strings are stored
+ * \param len:		pointer to the remaining length left in config_strings
+ *			  the value is decremented as strings are stored
+ *
+ * This function prepares a n lws_context_creation_info struct with global
+ * settings from a file d.
+ *
+ * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled
+ */
+LWS_VISIBLE LWS_EXTERN int
+lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
+			 char **config_strings, int *len);
+
+/**
+ * lwsws_get_config_vhosts() - Create vhosts from a JSON server config file
+ * \param context:	pointer to result of lws_create_context()
+ * \param info:		pointer to struct with parameters
+ * \param d:		filepath of the config file
+ * \param config_strings: storage for the config strings extracted from JSON,
+ * 			  the pointer is incremented as strings are stored
+ * \param len:		pointer to the remaining length left in config_strings
+ *			  the value is decremented as strings are stored
+ *
+ * This function creates vhosts into a context according to the settings in
+ *JSON files found in directory d.
+ *
+ * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled
+ */
+LWS_VISIBLE LWS_EXTERN int
+lwsws_get_config_vhosts(struct lws_context *context,
+			struct lws_context_creation_info *info, const char *d,
+			char **config_strings, int *len);
+
+/**
+ * lws_get_vhost() - return the vhost a wsi belongs to
+ *
+ * \param wsi: which connection
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_vhost *
+lws_get_vhost(struct lws *wsi);
+
+/**
+ * lws_get_vhost_name() - returns the name of a vhost
+ *
+ * \param vhost: which vhost
+ */
+LWS_VISIBLE LWS_EXTERN const char *
+lws_get_vhost_name(struct lws_vhost *vhost);
+
+/**
+ * lws_get_vhost_by_name() - returns the vhost with the requested name, or NULL
+ *
+ * \param context: the lws_context to look in
+ * \param name: vhost name we are looking for
+ *
+ * Returns NULL, or the vhost with the name \p name
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_vhost *
+lws_get_vhost_by_name(struct lws_context *context, const char *name);
+
+/**
+ * lws_get_vhost_port() - returns the port a vhost listens on, or -1
+ *
+ * \param vhost: which vhost
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_get_vhost_port(struct lws_vhost *vhost);
+
+/**
+ * lws_get_vhost_user() - returns the user pointer for the vhost
+ *
+ * \param vhost: which vhost
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_get_vhost_user(struct lws_vhost *vhost);
+
+/**
+ * lws_get_vhost_iface() - returns the binding for the vhost listen socket
+ *
+ * \param vhost: which vhost
+ */
+LWS_VISIBLE LWS_EXTERN const char *
+lws_get_vhost_iface(struct lws_vhost *vhost);
+
+/**
+ * lws_json_dump_vhost() - describe vhost state and stats in JSON
+ *
+ * \param vh: the vhost
+ * \param buf: buffer to fill with JSON
+ * \param len: max length of buf
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len);
+
+/**
+ * lws_json_dump_context() - describe context state and stats in JSON
+ *
+ * \param context: the context
+ * \param buf: buffer to fill with JSON
+ * \param len: max length of buf
+ * \param hide_vhosts: nonzero to not provide per-vhost mount etc information
+ *
+ * Generates a JSON description of vhost state into buf
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_json_dump_context(const struct lws_context *context, char *buf, int len,
+		      int hide_vhosts);
+
+/**
+ * lws_vhost_user() - get the user data associated with the vhost
+ * \param vhost: Websocket vhost
+ *
+ * This returns the optional user pointer that can be attached to
+ * a vhost when it was created.  Lws never dereferences this pointer, it only
+ * sets it when the vhost is created, and returns it using this api.
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_vhost_user(struct lws_vhost *vhost);
+
+/**
+ * lws_context_user() - get the user data associated with the context
+ * \param context: Websocket context
+ *
+ * This returns the optional user allocation that can be attached to
+ * the context the sockets live in at context_create time.  It's a way
+ * to let all sockets serviced in the same context share data without
+ * using globals statics in the user code.
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_context_user(struct lws_context *context);
+
+/*! \defgroup vhost-mounts Vhost mounts and options
+ * \ingroup context-and-vhost-creation
+ *
+ * ##Vhost mounts and options
+ */
+///@{
+/** struct lws_protocol_vhost_options - linked list of per-vhost protocol
+ * 					name=value options
+ *
+ * This provides a general way to attach a linked-list of name=value pairs,
+ * which can also have an optional child link-list using the options member.
+ */
+struct lws_protocol_vhost_options {
+	const struct lws_protocol_vhost_options *next; /**< linked list */
+	const struct lws_protocol_vhost_options *options; /**< child linked-list of more options for this node */
+	const char *name; /**< name of name=value pair */
+	const char *value; /**< value of name=value pair */
+};
+
+/** enum lws_mount_protocols
+ * This specifies the mount protocol for a mountpoint, whether it is to be
+ * served from a filesystem, or it is a cgi etc.
+ */
+enum lws_mount_protocols {
+	LWSMPRO_HTTP		= 0, /**< http reverse proxy */
+	LWSMPRO_HTTPS		= 1, /**< https reverse proxy */
+	LWSMPRO_FILE		= 2, /**< serve from filesystem directory */
+	LWSMPRO_CGI		= 3, /**< pass to CGI to handle */
+	LWSMPRO_REDIR_HTTP	= 4, /**< redirect to http:// url */
+	LWSMPRO_REDIR_HTTPS	= 5, /**< redirect to https:// url */
+	LWSMPRO_CALLBACK	= 6, /**< hand by named protocol's callback */
+};
+
+/** enum lws_authentication_mode
+ * This specifies the authentication mode of the mount. The basic_auth_login_file mount parameter
+ * is ignored unless LWSAUTHM_DEFAULT is set.
+ */
+enum lws_authentication_mode {
+	LWSAUTHM_DEFAULT = 0, /**< default authenticate only if basic_auth_login_file is provided */
+	LWSAUTHM_BASIC_AUTH_CALLBACK = 1 << 28 /**< Basic auth with a custom verifier */
+};
+
+/** The authentication mode is stored in the top 4 bits of lws_http_mount.auth_mask */
+#define AUTH_MODE_MASK 0xF0000000
+
+/** struct lws_http_mount
+ *
+ * arguments for mounting something in a vhost's url namespace
+ */
+struct lws_http_mount {
+	const struct lws_http_mount *mount_next;
+	/**< pointer to next struct lws_http_mount */
+	const char *mountpoint;
+	/**< mountpoint in http pathspace, eg, "/" */
+	const char *origin;
+	/**< path to be mounted, eg, "/var/www/warmcat.com" */
+	const char *def;
+	/**< default target, eg, "index.html" */
+	const char *protocol;
+	/**<"protocol-name" to handle mount */
+
+	const struct lws_protocol_vhost_options *cgienv;
+	/**< optional linked-list of cgi options.  These are created
+	 * as environment variables for the cgi process
+	 */
+	const struct lws_protocol_vhost_options *extra_mimetypes;
+	/**< optional linked-list of mimetype mappings */
+	const struct lws_protocol_vhost_options *interpret;
+	/**< optional linked-list of files to be interpreted */
+
+	int cgi_timeout;
+	/**< seconds cgi is allowed to live, if cgi://mount type */
+	int cache_max_age;
+	/**< max-age for reuse of client cache of files, seconds */
+	unsigned int auth_mask;
+	/**< bits set here must be set for authorized client session */
+
+	unsigned int cache_reusable:1; /**< set if client cache may reuse this */
+	unsigned int cache_revalidate:1; /**< set if client cache should revalidate on use */
+	unsigned int cache_intermediaries:1; /**< set if intermediaries are allowed to cache */
+
+	unsigned char origin_protocol; /**< one of enum lws_mount_protocols */
+	unsigned char mountpoint_len; /**< length of mountpoint string */
+
+	const char *basic_auth_login_file;
+	/**<NULL, or filepath to use to check basic auth logins against. (requires LWSAUTHM_DEFAULT) */
+
+	/* Add new things just above here ---^
+	 * This is part of the ABI, don't needlessly break compatibility
+	 *
+	 * The below is to ensure later library versions with new
+	 * members added above will see 0 (default) even if the app
+	 * was not built against the newer headers.
+	 */
+
+	void *_unused[2]; /**< dummy */
+};
+
+///@}
+///@}

+ 94 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dbus.h

@@ -0,0 +1,94 @@
+ /*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * must be included manually as
+ *
+ *  #include <libwebsockets/lws-dbus.h>
+ *
+ * if dbus apis needed
+ */
+
+#if !defined(__LWS_DBUS_H__)
+#define __LWS_DBUS_H__
+
+#include <dbus/dbus.h>
+
+/* helper type to simplify implementing methods as individual functions */
+typedef DBusHandlerResult (*lws_dbus_message_handler)(DBusConnection *conn,
+			   DBusMessage *message, DBusMessage **reply, void *d);
+
+struct lws_dbus_ctx;
+typedef void (*lws_dbus_closing_t)(struct lws_dbus_ctx *ctx);
+
+struct lws_dbus_ctx {
+	struct lws_dll2_owner owner; /* dbusserver ctx: HEAD of accepted list */
+	struct lws_dll2 next; /* dbusserver ctx: HEAD of accepted list */
+	struct lws_vhost *vh; /* the vhost we logically bind to in lws */
+	int tsi;	/* the lws thread service index (0 if only one service
+			   thread as is the default */
+	DBusConnection *conn;
+	DBusServer *dbs;
+	DBusWatch *w[4];
+ 	DBusPendingCall *pc;
+
+ 	char hup;
+ 	char timeouts;
+
+ 	/* cb_closing callback will be called after the connection and this
+ 	 * related ctx struct have effectively gone out of scope.
+ 	 *
+ 	 * The callback should close and clean up the connection and free the
+ 	 * ctx.
+ 	 */
+ 	lws_dbus_closing_t cb_closing;
+};
+
+/**
+ * lws_dbus_connection_setup() - bind dbus connection object to lws event loop
+ *
+ * \param ctx: additional information about the connection
+ * \param conn: the DBusConnection object to bind
+ *
+ * This configures a DBusConnection object to use lws for watchers and timeout
+ * operations.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_dbus_connection_setup(struct lws_dbus_ctx *ctx, DBusConnection *conn,
+			  lws_dbus_closing_t cb_closing);
+
+/**
+ * lws_dbus_server_listen() - bind dbus connection object to lws event loop
+ *
+ * \param ctx: additional information about the connection
+ * \param ads: the DBUS address to listen on, eg, "unix:abstract=mysocket"
+ * \param err: a DBusError object to take any extra error information
+ * \param new_conn: a callback function to prepare new accepted connections
+ *
+ * This creates a DBusServer and binds it to the lws event loop, and your
+ * callback to accept new connections.
+ */
+LWS_VISIBLE LWS_EXTERN DBusServer *
+lws_dbus_server_listen(struct lws_dbus_ctx *ctx, const char *ads,
+		       DBusError *err, DBusNewConnectionFunction new_conn);
+
+#endif

+ 140 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-detailed-latency.h

@@ -0,0 +1,140 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * included from libwebsockets.h
+ */
+
+enum {
+
+	/* types of latency, all nonblocking except name resolution */
+
+	LDLT_READ,	/* time taken to read LAT_DUR_PROXY_RX_TO_CLIENT_WRITE */
+	LDLT_WRITE,
+	LDLT_NAME_RESOLUTION, /* BLOCKING: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
+	LDLT_CONNECTION, /* conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
+	LDLT_TLS_NEG_CLIENT, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
+	LDLT_TLS_NEG_SERVER, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
+
+	LDLT_USER,
+
+	/* interval / duration elements in latencies array */
+
+	LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE				= 0,
+		/* us the client spent waiting to write to proxy */
+	LAT_DUR_PROXY_CLIENT_WRITE_TO_PROXY_RX,
+		/* us the packet took to be received by proxy */
+	LAT_DUR_PROXY_PROXY_REQ_TO_WRITE,
+		/* us the proxy has to wait before it could write */
+	LAT_DUR_PROXY_RX_TO_ONWARD_TX,
+		/* us the proxy spent waiting to write to destination, or
+		 * if nonproxied, then time between write request and write */
+
+	LAT_DUR_USERCB, /* us duration of user callback */
+
+	LAT_DUR_STEPS /* last */
+};
+
+typedef struct lws_detlat {
+	lws_usec_t		earliest_write_req;
+	lws_usec_t		earliest_write_req_pre_write;
+		/**< use this for interval comparison */
+	const char		*aux; /* name for name resolution timing */
+	int			type;
+	uint32_t		latencies[LAT_DUR_STEPS];
+	size_t			req_size;
+	size_t			acc_size;
+} lws_detlat_t;
+
+typedef int (*det_lat_buf_cb_t)(struct lws_context *context,
+				const lws_detlat_t *d);
+
+/**
+ * lws_det_lat_cb() - inject your own latency records
+ *
+ * \param context: the lws_context
+ * \param d: the lws_detlat_t you have prepared
+ *
+ * For proxying or similar cases where latency information is available from
+ * user code rather than lws itself, you can generate your own latency callback
+ * events with your own lws_detlat_t.
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_det_lat_cb(struct lws_context *context, lws_detlat_t *d);
+
+/*
+ * detailed_latency_plot_cb() - canned save to file in plottable format cb
+ *
+ * \p context: the lws_context
+ * \p d: the detailed latency event information
+ *
+ * This canned callback makes it easy to export the detailed latency information
+ * to a file.  Just set the context creation members like this
+ *
+ * #if defined(LWS_WITH_DETAILED_LATENCY)
+ *	info.detailed_latency_cb = lws_det_lat_plot_cb;
+ *	info.detailed_latency_filepath = "/tmp/lws-latency-results";
+ * #endif
+ *
+ * and you will get a file containing information like this
+ *
+ * 718823864615 N 10589 0 0 10589 0 0 0
+ * 718823880837 C 16173 0 0 16173 0 0 0
+ * 718823913063 T 32212 0 0 32212 0 0 0
+ * 718823931835 r 0 0 0 0 232 30 256
+ * 718823948757 r 0 0 0 0 40 30 256
+ * 718823948799 r 0 0 0 0 83 30 256
+ * 718823965602 r 0 0 0 0 27 30 256
+ * 718823965617 r 0 0 0 0 43 30 256
+ * 718823965998 r 0 0 0 0 12 28 256
+ * 718823983887 r 0 0 0 0 74 3 4096
+ * 718823986411 w 16 87 7 110 9 80 80
+ * 718824006358 w 8 68 6 82 6 80 80
+ *
+ * which is easy to grep and pass to gnuplot.
+ *
+ * The columns are
+ *
+ *  - unix time in us
+ *  - N = Name resolution, C = TCP Connection, T = TLS negotiation server,
+ *    t = TLS negotiation client, r = Read, w = Write
+ *  - us duration, for w time client spent waiting to write
+ *  - us duration, for w time data spent in transit to proxy
+ *  - us duration, for w time proxy waited to send data
+ *  - as a convenience, sum of last 3 columns above
+ *  - us duration, time spent in callback
+ *  - last 2 are actual / requested size in bytes
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_det_lat_plot_cb(struct lws_context *context, const lws_detlat_t *d);
+
+/**
+ * lws_det_lat_active() - indicates if latencies are being measured
+ *
+ * \context: lws_context
+ *
+ * Returns 0 if latency measurement has not been set up (the callback is NULL).
+ * Otherwise returns 1
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_det_lat_active(struct lws_context *context);

+ 187 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-diskcache.h

@@ -0,0 +1,187 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup diskcache LWS disk cache
+ * ## Disk cache API
+ *
+ * Lws provides helper apis useful if you need a disk cache containing hashed
+ * files and need to delete files from it on an LRU basis to keep it below some
+ * size limit.
+ *
+ * The API `lws_diskcache_prepare()` deals with creating the cache dir and
+ * 256 subdirs, which are used according to the first two chars of the hex
+ * hash of the cache file.
+ *
+ * `lws_diskcache_create()` and `lws_diskcache_destroy()` allocate and free
+ * an opaque struct that represents the disk cache.
+ *
+ * `lws_diskcache_trim()` should be called at eg, 1s intervals to perform the
+ * cache dir monitoring and LRU autodelete in the background lazily.  It can
+ * be done in its own thread or on a timer... it monitors the directories in a
+ * stateful way that stats one or more file in the cache per call, and keeps
+ * a list of the oldest files as it goes.  When it completes a scan, if the
+ * aggregate size is over the limit, it will delete oldest files first to try
+ * to keep it under the limit.
+ *
+ * The cache size monitoring is extremely efficient in time and memory even when
+ * the cache directory becomes huge.
+ *
+ * `lws_diskcache_query()` is used to determine if the file already exists in
+ * the cache, or if it must be created.  If it must be created, then the file
+ * is opened using a temp name that must be converted to a findable name with
+ * `lws_diskcache_finalize_name()` when the generation of the file contents are
+ * complete.  Aborted cached files that did not complete generation will be
+ * flushed by the LRU eventually.  If the file already exists, it is 'touched'
+ * to make it new again and the fd returned.
+ *
+ */
+///@{
+
+struct lws_diskcache_scan;
+
+/**
+ * lws_diskcache_create() - creates an opaque struct representing the disk cache
+ *
+ * \param cache_dir_base: The cache dir path, eg `/var/cache/mycache`
+ * \param cache_size_limit: maximum size on disk the cache is allowed to use
+ *
+ * This returns an opaque `struct lws_diskcache_scan *` which represents the
+ * disk cache, the trim scanning state and so on.  You should use
+ * `lws_diskcache_destroy()` to free it to destroy it.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan *
+lws_diskcache_create(const char *cache_dir_base, uint64_t cache_size_limit);
+
+/**
+ * lws_diskcache_destroy() - destroys the pointer returned by ...create()
+ *
+ * \param lds: pointer to the pointer returned by lws_diskcache_create()
+ *
+ * Frees *lds and any allocations it did, and then sets *lds to NULL and
+ * returns.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_diskcache_destroy(struct lws_diskcache_scan **lds);
+
+/**
+ * lws_diskcache_prepare() - ensures the cache dir structure exists on disk
+ *
+ * \param cache_base_dir: The cache dir path, eg `/var/cache/mycache`
+ * \param mode: octal dir mode to enforce, like 0700
+ * \param uid: uid the cache dir should belong to
+ *
+ * This should be called while your app is still privileged.  It will create
+ * the cache directory structure on disk as necessary, enforce the given access
+ * mode on it and set the given uid as the owner.  It won't make any trouble
+ * if the cache already exists.
+ *
+ * Typically the mode is 0700 and the owner is the user that your application
+ * will transition to use when it drops root privileges.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_diskcache_prepare(const char *cache_base_dir, int mode, int uid);
+
+#define LWS_DISKCACHE_QUERY_NO_CACHE	0
+#define LWS_DISKCACHE_QUERY_EXISTS	1
+#define LWS_DISKCACHE_QUERY_CREATING	2
+#define LWS_DISKCACHE_QUERY_ONGOING	3 /* something else is creating it */
+
+/**
+ * lws_diskcache_query() - ensures the cache dir structure exists on disk
+ *
+ * \param lds: The opaque struct representing the disk cache
+ * \param is_bot: nonzero means the request is from a bot.  Don't create new cache contents if so.
+ * \param hash_hex: hex string representation of the cache object hash
+ * \param _fd: pointer to the fd to be set
+ * \param cache: destination string to take the cache filepath
+ * \param cache_len: length of the buffer at `cache`
+ * \param extant_cache_len: pointer to a size_t to take any extant cached file size
+ *
+ * This function is called when you want to find if the hashed name already
+ * exists in the cache.  The possibilities for the return value are
+ *
+ *  - LWS_DISKCACHE_QUERY_NO_CACHE: It's not in the cache and you can't create
+ *    it in the cache for whatever reason.
+ *  - LWS_DISKCACHE_QUERY_EXISTS: It exists in the cache.  It's open RDONLY and
+ *    *_fd has been set to the file descriptor.  *extant_cache_len has been set
+ *    to the size of the cached file in bytes.  cache has been set to the
+ *    full filepath of the cached file.  Closing _fd is your responsibility.
+ *  - LWS_DISKCACHE_QUERY_CREATING: It didn't exist, but a temp file has been
+ *    created in the cache and *_fd set to a file descriptor opened on it RDWR.
+ *    You should create the contents, and call `lws_diskcache_finalize_name()`
+ *    when it is done.  Closing _fd is your responsibility.
+ *  - LWS_DISKCACHE_QUERY_ONGOING: not returned by this api, but you may find it
+ *    desirable to make a wrapper function which can handle another asynchronous
+ *    process that is already creating the cached file.  This can be used to
+ *    indicate that situation externally... how to determine the same thing is
+ *    already being generated is out of scope of this api.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_diskcache_query(struct lws_diskcache_scan *lds, int is_bot,
+		    const char *hash_hex, int *_fd, char *cache, int cache_len,
+		    size_t *extant_cache_len);
+
+/**
+ * lws_diskcache_query() - ensures the cache dir structure exists on disk
+ *
+ * \param cache: The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING
+ *
+ * This renames the cache file you are creating to its final name.  It should
+ * be called on the temp name returned by `lws_diskcache_query()` if it gave a
+ * LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and
+ * closed it.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_diskcache_finalize_name(char *cache);
+
+/**
+ * lws_diskcache_trim() - performs one or more file checks in the cache for size management
+ *
+ * \param lds: The opaque object representing the cache
+ *
+ * This should be called periodically to statefully walk the cache on disk
+ * collecting the oldest files.  When it has visited every file, if the cache
+ * is oversize it will delete the oldest files until it's back under size again.
+ *
+ * Each time it's called, it will look at one or more dir in the cache.  If
+ * called when the cache is oversize, it increases the amount of work done each
+ * call until it is reduced again.  Typically it will take 256 calls before it
+ * deletes anything, so if called once per second, it will delete files once
+ * every 4 minutes.  Each call is very inexpensive both in memory and time.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_diskcache_trim(struct lws_diskcache_scan *lds);
+
+
+/**
+ * lws_diskcache_secs_to_idle() - see how long to idle before calling trim
+ *
+ * \param lds: The opaque object representing the cache
+ *
+ * If the cache is undersize, there's no need to monitor it immediately.  This
+ * suggests how long to "sleep" before calling `lws_diskcache_trim()` again.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_diskcache_secs_to_idle(struct lws_diskcache_scan *lds);
+///@}

+ 158 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-display.h

@@ -0,0 +1,158 @@
+/*
+ * lws abstract display
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#if !defined(__LWS_DISPLAY_H__)
+#define __LWS_DISPLAY_H__
+
+#include <stdint.h>
+
+typedef uint16_t lws_display_scalar;
+
+/*
+ * This is embedded in the actual display implementation object at the top,
+ * so a pointer to this can be cast to a pointer to the implementation object
+ * by any code that is specific to how it was implemented.
+ *
+ * Notice for the backlight / display intensity we contain pwm_ops... these can
+ * be some other pwm_ops like existing gpio pwm ops, or handled in a customized
+ * way like set oled contrast.  Either way, the pwm level is arrived at via a
+ * full set of lws_led_sequences capable of generic lws transitions
+ */
+
+typedef struct lws_display {
+	int (*init)(const struct lws_display *disp);
+	const lws_pwm_ops_t		*bl_pwm_ops;
+	int (*contrast)(const struct lws_display *disp, uint8_t contrast);
+	int (*blit)(const struct lws_display *disp, const uint8_t *src,
+		    lws_display_scalar x, lws_display_scalar y,
+		    lws_display_scalar w, lws_display_scalar h);
+	int (*power)(const struct lws_display *disp, int state);
+
+	const lws_led_sequence_def_t	*bl_active;
+	const lws_led_sequence_def_t	*bl_dim;
+	const lws_led_sequence_def_t	*bl_transition;
+
+	void				*variant;
+
+	int				bl_index;
+
+	lws_display_scalar		w;
+	/**< display surface width in pixels */
+	lws_display_scalar		h;
+	/**< display surface height in pixels */
+
+	uint8_t				latency_wake_ms;
+	/**< ms required after wake from sleep before display usable again...
+	 * delay bringing up the backlight for this amount of time on wake.
+	 * This is managed via a sul on the event loop, not blocking. */
+} lws_display_t;
+
+/*
+ * This contains dynamic data related to display state
+ */
+
+enum lws_display_controller_state {
+	LWSDISPS_OFF,
+	LWSDISPS_AUTODIMMED,	  /* is in pre- blanking static dim mode */
+	LWSDISPS_BECOMING_ACTIVE, /* waiting for wake latency before active */
+	LWSDISPS_ACTIVE,	  /* is active */
+	LWSDISPS_GOING_OFF	  /* dimming then off */
+};
+
+typedef struct lws_display_state {
+
+	lws_sorted_usec_list_t		sul_autodim;
+	const lws_display_t		*disp;
+	struct lws_context		*ctx;
+
+	int				autodim_ms;
+	int				off_ms;
+
+	struct lws_led_state		*bl_lcs;
+
+	lws_led_state_chs_t		chs;
+	/* set of sequencer transition channels */
+
+	enum lws_display_controller_state state;
+
+} lws_display_state_t;
+
+/**
+ * lws_display_state_init() - initialize display states
+ *
+ * \param lds: the display state object
+ * \param ctx: the lws context
+ * \param autodim_ms: ms since last active report to dim display (<0 = never)
+ * \param off_ms: ms since dim to turn display off (<0 = never)
+ * \param bl_lcs: the led controller instance that has the backlight
+ * \param disp: generic display object we belong to
+ *
+ * This initializes a display's state, and sets up the optional screen auto-dim
+ * and blanking on inactive, and gradual brightness change timer.
+ *
+ *  - auto-dim then off: set autodim to some ms and off_ms to some ms
+ *  - auto-dim only: set autodim to some ms and off_ms to -1
+ *  - off-only: set autodim to some ms and off_ms to 0
+ *  - neither: set both autodim and off_ms to -1
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx,
+		       int autodim_ms, int off_ms, struct lws_led_state *bl_lcs,
+		       const lws_display_t *disp);
+
+/**
+ * lws_display_state_set_brightness() - gradually change the brightness
+ *
+ * \param lds: the display state we are changing
+ * \param target: the target brightness to transition to
+ *
+ * Adjusts the brightness gradually twoards the target at 20Hz
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_set_brightness(lws_display_state_t *lds,
+				 const lws_led_sequence_def_t *pwmseq);
+
+/*
+ * lws_display_state_active() - inform the system the display is active
+ *
+ * \param lds: the display state we are marking as active
+ *
+ * Resets the auto-dim and auto-off timers and makes sure the display is on and
+ * at the active brightness level
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_active(lws_display_state_t *lds);
+
+/*
+ * lws_display_state_off() - turns off the related display
+ *
+ * \param lds: the display state we are turning off
+ *
+ * Turns the display to least power mode or completely off if possible.
+ * Disables the timers related to dimming and blanking.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_off(lws_display_state_t *lds);
+
+#endif

+ 298 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dll2.h

@@ -0,0 +1,298 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup ll linked-lists
+* ##Linked list apis
+*
+* simple single and doubly-linked lists
+*/
+///@{
+
+/**
+ * lws_start_foreach_ll(): linkedlist iterator helper start
+ *
+ * \param type: type of iteration, eg, struct xyz *
+ * \param it: iterator var name to create
+ * \param start: start of list
+ *
+ * This helper creates an iterator and starts a while (it) {
+ * loop.  The iterator runs through the linked list starting at start and
+ * ends when it gets a NULL.
+ * The while loop should be terminated using lws_start_foreach_ll().
+ */
+#define lws_start_foreach_ll(type, it, start)\
+{ \
+	type it = start; \
+	while (it) {
+
+/**
+ * lws_end_foreach_ll(): linkedlist iterator helper end
+ *
+ * \param it: same iterator var name given when starting
+ * \param nxt: member name in the iterator pointing to next list element
+ *
+ * This helper is the partner for lws_start_foreach_ll() that ends the
+ * while loop.
+ */
+
+#define lws_end_foreach_ll(it, nxt) \
+		it = it->nxt; \
+	} \
+}
+
+/**
+ * lws_start_foreach_ll_safe(): linkedlist iterator helper start safe against delete
+ *
+ * \param type: type of iteration, eg, struct xyz *
+ * \param it: iterator var name to create
+ * \param start: start of list
+ * \param nxt: member name in the iterator pointing to next list element
+ *
+ * This helper creates an iterator and starts a while (it) {
+ * loop.  The iterator runs through the linked list starting at start and
+ * ends when it gets a NULL.
+ * The while loop should be terminated using lws_end_foreach_ll_safe().
+ * Performs storage of next increment for situations where iterator can become invalidated
+ * during iteration.
+ */
+#define lws_start_foreach_ll_safe(type, it, start, nxt)\
+{ \
+	type it = start; \
+	while (it) { \
+		type next_##it = it->nxt;
+
+/**
+ * lws_end_foreach_ll_safe(): linkedlist iterator helper end (pre increment storage)
+ *
+ * \param it: same iterator var name given when starting
+ *
+ * This helper is the partner for lws_start_foreach_ll_safe() that ends the
+ * while loop. It uses the precreated next_ variable already stored during
+ * start.
+ */
+
+#define lws_end_foreach_ll_safe(it) \
+		it = next_##it; \
+	} \
+}
+
+/**
+ * lws_start_foreach_llp(): linkedlist pointer iterator helper start
+ *
+ * \param type: type of iteration, eg, struct xyz **
+ * \param it: iterator var name to create
+ * \param start: start of list
+ *
+ * This helper creates an iterator and starts a while (it) {
+ * loop.  The iterator runs through the linked list starting at the
+ * address of start and ends when it gets a NULL.
+ * The while loop should be terminated using lws_start_foreach_llp().
+ *
+ * This helper variant iterates using a pointer to the previous linked-list
+ * element.  That allows you to easily delete list members by rewriting the
+ * previous pointer to the element's next pointer.
+ */
+#define lws_start_foreach_llp(type, it, start)\
+{ \
+	type it = &(start); \
+	while (*(it)) {
+
+#define lws_start_foreach_llp_safe(type, it, start, nxt)\
+{ \
+	type it = &(start); \
+	type next; \
+	while (*(it)) { \
+		next = &((*(it))->nxt); \
+
+/**
+ * lws_end_foreach_llp(): linkedlist pointer iterator helper end
+ *
+ * \param it: same iterator var name given when starting
+ * \param nxt: member name in the iterator pointing to next list element
+ *
+ * This helper is the partner for lws_start_foreach_llp() that ends the
+ * while loop.
+ */
+
+#define lws_end_foreach_llp(it, nxt) \
+		it = &(*(it))->nxt; \
+	} \
+}
+
+#define lws_end_foreach_llp_safe(it) \
+		it = next; \
+	} \
+}
+
+#define lws_ll_fwd_insert(\
+	___new_object,	/* pointer to new object */ \
+	___m_list,	/* member for next list object ptr */ \
+	___list_head	/* list head */ \
+		) {\
+		___new_object->___m_list = ___list_head; \
+		___list_head = ___new_object; \
+	}
+
+#define lws_ll_fwd_remove(\
+	___type,	/* type of listed object */ \
+	___m_list,	/* member for next list object ptr */ \
+	___target,	/* object to remove from list */ \
+	___list_head	/* list head */ \
+	) { \
+                lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \
+                        if (*___ppss == ___target) { \
+                                *___ppss = ___target->___m_list; \
+                                break; \
+                        } \
+                } lws_end_foreach_llp(___ppss, ___m_list); \
+	}
+
+
+/*
+ * doubly linked-list
+ */
+
+/*
+ * lws_dll2_owner / lws_dll2 : more capable version of lws_dll.  Differences:
+ *
+ *  - there's an explicit lws_dll2_owner struct which holds head, tail and
+ *    count of members.
+ *
+ *  - list members all hold a pointer to their owner.  So user code does not
+ *    have to track anything about exactly what lws_dll2_owner list the object
+ *    is a member of.
+ *
+ *  - you can use lws_dll unless you want the member count or the ability to
+ *    not track exactly which list it's on.
+ *
+ *  - layout is compatible with lws_dll (but lws_dll apis will not update the
+ *    new stuff)
+ */
+
+
+struct lws_dll2;
+struct lws_dll2_owner;
+
+typedef struct lws_dll2 {
+	struct lws_dll2		*prev;
+	struct lws_dll2		*next;
+	struct lws_dll2_owner	*owner;
+} lws_dll2_t;
+
+typedef struct lws_dll2_owner {
+	struct lws_dll2		*tail;
+	struct lws_dll2		*head;
+
+	uint32_t		count;
+} lws_dll2_owner_t;
+
+static LWS_INLINE int
+lws_dll2_is_detached(const struct lws_dll2 *d) { return !d->owner; }
+
+static LWS_INLINE const struct lws_dll2_owner *
+lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; }
+
+static LWS_INLINE struct lws_dll2 *
+lws_dll2_get_head(struct lws_dll2_owner *owner) { return owner->head; }
+
+static LWS_INLINE struct lws_dll2 *
+lws_dll2_get_tail(struct lws_dll2_owner *owner) { return owner->tail; }
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_remove(struct lws_dll2 *d);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
+		      int (*cb)(struct lws_dll2 *d, void *user));
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_clear(struct lws_dll2 *d);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_owner_clear(struct lws_dll2_owner *d);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
+		    int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
+
+LWS_VISIBLE LWS_EXTERN void *
+_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
+		      size_t dll2_ofs, size_t ptr_ofs);
+
+/*
+ * Searches objects in an owner list linearly and returns one with a given
+ * member C-string matching a supplied length-provided string if it exists, else
+ * NULL.
+ */
+
+#define lws_dll2_search_sz_pl(own, name, namelen, type, membd2list, membptr) \
+		((type *)_lws_dll2_search_sz_pl(own, name, namelen, \
+				       offsetof(type, membd2list), \
+				       offsetof(type, membptr)))
+
+#if defined(_DEBUG)
+void
+lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
+#else
+#define lws_dll2_describe(x, y)
+#endif
+
+/*
+ * these are safe against the current container object getting deleted,
+ * since the hold his next in a temp and go to that next.  ___tmp is
+ * the temp.
+ */
+
+#define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
+{ \
+	___type ___it = ___start; \
+	while (___it) { \
+		___type ___tmp = (___it)->next;
+
+#define lws_end_foreach_dll_safe(___it, ___tmp) \
+		___it = ___tmp; \
+	} \
+}
+
+#define lws_start_foreach_dll(___type, ___it, ___start) \
+{ \
+	___type ___it = ___start; \
+	while (___it) {
+
+#define lws_end_foreach_dll(___it) \
+		___it = (___it)->next; \
+	} \
+}
+
+///@}
+

+ 145 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-dsh.h

@@ -0,0 +1,145 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * lws_dsh (Disordered Shared Heap) is an opaque abstraction supporting a single
+ * linear buffer (overallocated at end of the lws_dsh_t) which may contain
+ * multiple kinds of packets that are retired out of order, and tracked by kind.
+ *
+ * Each kind of packet has an lws_dll2 list of its kind of packets and acts as
+ * a FIFO; packets of a particular type are always retired in order.  But there
+ * is no requirement about the order types are retired matching the original
+ * order they arrived.
+ * 
+ * Gaps are tracked as just another kind of "packet" list.
+ *
+ * "allocations" (including gaps) are prepended by an lws_dsh_object_t.
+ *
+ * dsh may themselves be on an lws_dll2_owner list, and under memory pressure
+ * allocate into other buffers on the list.
+ *
+ * All management structures exist inside the allocated buffer.
+ */
+
+/**
+ * lws_dsh_create() - Allocate a DSH buffer
+ *
+ * \param owner: the owning list this dsh belongs on, or NULL if standalone
+ * \param buffer_size: the allocation in bytes
+ * \param count_kinds: how many separately-tracked fifos use the buffer
+ *
+ * This makes a single heap allocation that includes internal tracking objects
+ * in the buffer.  Sub-allocated objects are bound to a "kind" index and
+ * managed via a FIFO for each kind.
+ *
+ * Every "kind" of allocation shares the same buffer space.
+ *
+ * Multiple buffers may be bound together in an lws_dll2 list, and if an
+ * allocation cannot be satisfied by the local buffer, space can be borrowed
+ * from other dsh in the same list (the local dsh FIFO tracks these "foreign"
+ * allocations as if they were local).
+ *
+ * Returns an opaque pointer to the dsh, or NULL if allocation failed.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_dsh *
+lws_dsh_create(lws_dll2_owner_t *owner, size_t buffer_size, int count_kinds);
+
+/**
+ * lws_dsh_destroy() - Destroy a DSH buffer
+ *
+ * \param pdsh: pointer to the dsh pointer
+ *
+ * Deallocates the DSH and sets *pdsh to NULL.
+ *
+ * Before destruction, any foreign buffer usage on the part of this dsh are
+ * individually freed.  All dsh on the same list are walked and checked if they
+ * have their own foreign allocations on the dsh buffer being destroyed.  If so,
+ * it attempts to migrate the allocation to a dsh that is not currently being
+ * destroyed.  If all else fails (basically the buffer memory is being shrunk)
+ * unmigratable objects are cleanly destroyed.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_dsh_destroy(struct lws_dsh **pdsh);
+
+/**
+ * lws_dsh_alloc_tail() - make a suballocation inside a dsh
+ *
+ * \param dsh: the dsh tracking the allocation
+ * \param kind: the kind of allocation
+ * \param src1: the first source data to copy
+ * \param size1: the size of the first source data
+ * \param src2: the second source data to copy (after the first), or NULL
+ * \param size2: the size of the second source data
+ *
+ * Allocates size1 + size2 bytes in a dsh (it prefers the given dsh but will
+ * borrow space from other dsh on the same list if necessary) and copies size1
+ * bytes into it from src1, followed by size2 bytes from src2 if src2 isn't
+ * NULL.  The actual suballocation is a bit larger because of alignment and a
+ * prepended management header.
+ *
+ * The suballocation is added to the kind-specific FIFO at the tail.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_dsh_alloc_tail(struct lws_dsh *dsh, int kind, const void *src1,
+		   size_t size1, const void *src2, size_t size2);
+
+/**
+ * lws_dsh_free() - free a suballocation from the dsh
+ *
+ * \param obj: a pointer to a void * that pointed to the allocated payload
+ *
+ * This returns the space used by \p obj in the dsh buffer to the free list
+ * of the dsh the allocation came from.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_dsh_free(void **obj);
+
+/**
+ * lws_dsh_get_head() - get the head allocation inside the dsh
+ *
+ * \param dsh: the dsh tracking the allocation
+ * \param kind: the kind of allocation
+ * \param obj: pointer to a void * to be set to the payload
+ * \param size: set to the size of the allocation
+ *
+ * This gets the "next" object in the kind FIFO for the dsh, and returns 0 if
+ * any.  If none, returns nonzero.
+ *
+ * This is nondestructive of the fifo or the payload.  Use lws_dsh_free on
+ * obj to remove the entry from the kind fifo and return the payload to the
+ * free list.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_dsh_get_head(struct lws_dsh *dsh, int kind, void **obj, size_t *size);
+
+/**
+ * lws_dsh_describe() - DEBUG BUILDS ONLY dump the dsh to the logs
+ *
+ * \param dsh: the dsh to dump
+ * \param desc: text that appears at the top of the dump
+ *
+ * Useful information for debugging lws_dsh
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_dsh_describe(struct lws_dsh *dsh, const char *desc);

+ 61 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-eventlib-exports.h

@@ -0,0 +1,61 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * These are exports needed by event lib plugins.
+ *
+ * You should consider these opaque for normal user code.
+ */
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_realloc(void *ptr, size_t size, const char *reason);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_vhost_destroy1(struct lws_vhost *vh);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
+		   const char *caller);
+
+struct lws_context_per_thread;
+LWS_VISIBLE LWS_EXTERN void
+lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
+
+#if !defined(wsi_from_fd) && !defined(WIN32) && !defined(_WIN32)
+struct lws_context;
+LWS_VISIBLE LWS_EXTERN struct lws *
+wsi_from_fd(const struct lws_context *context, int fd);
+#endif
+
+LWS_VISIBLE LWS_EXTERN int
+_lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_context_destroy2(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_destroy_event_pipe(struct lws *wsi);
+
+LWS_VISIBLE LWS_EXTERN void
+__lws_close_free_wsi_final(struct lws *wsi);
+
+

+ 87 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-freertos.h

@@ -0,0 +1,87 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * This is included from libwebsockets.h if LWS_PLAT_FREERTOS
+ */
+
+typedef int lws_sockfd_type;
+typedef int lws_filefd_type;
+
+#if defined(LWS_AMAZON_RTOS)
+#include <FreeRTOS.h>
+#include <event_groups.h>
+#include <string.h>
+#include "timers.h"
+#include <lwip/sockets.h>
+
+/*
+ * Later lwip (at least 2.1.12) already defines these in its own headers
+ * protected by the same test as used here... if POLLIN / POLLOUT already exist
+ * then assume no need to declare those and struct pollfd.
+ *
+ * Older lwip needs these declarations done here.
+ */
+
+#if !defined(POLLIN) && !defined(POLLOUT)
+
+struct pollfd {
+	lws_sockfd_type fd; /**< fd related to */
+	short events; /**< which POLL... events to respond to */
+	short revents; /**< which POLL... events occurred */
+};
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+#endif
+
+#else /* LWS_AMAZON_RTOS */
+#include <freertos/FreeRTOS.h>
+#include <freertos/event_groups.h>
+#include <string.h>
+#include "esp_wifi.h"
+#include "esp_system.h"
+#include "esp_event.h"
+//#include "esp_event_loop.h"
+#include "nvs.h"
+#include "driver/gpio.h"
+#include "esp_spi_flash.h"
+#include "freertos/timers.h"
+
+#if defined(LWS_ESP_PLATFORM)
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+#if defined(LWS_WITH_DRIVERS)
+#include "libwebsockets/lws-gpio.h"
+extern const lws_gpio_ops_t lws_gpio_plat;
+#endif
+#endif
+
+#endif /* LWS_AMAZON_RTOS */
+
+#if !defined(CONFIG_FREERTOS_HZ)
+#define CONFIG_FREERTOS_HZ 100
+#endif

+ 215 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-fts.h

@@ -0,0 +1,215 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup search Search
+ *
+ * ##Full-text search
+ *
+ * Lws provides superfast indexing and fulltext searching from index files on
+ * storage.
+ */
+///@{
+
+struct lws_fts;
+struct lws_fts_file;
+
+/*
+ * Queries produce their results in an lwsac, using these public API types.
+ * The first thing in the lwsac is always a struct lws_fts_result (see below)
+ * containing heads for linked-lists of the other result types.
+ */
+
+/* one filepath's results */
+
+struct lws_fts_result_filepath {
+	struct lws_fts_result_filepath *next;
+	int matches;	/* logical number of matches */
+	int matches_length;	/* bytes in length table (may be zero) */
+	int lines_in_file;
+	int filepath_length;
+
+	/* - uint32_t line table follows (first for alignment) */
+	/* - filepath (of filepath_length) follows */
+};
+
+/* autocomplete result */
+
+struct lws_fts_result_autocomplete {
+	struct lws_fts_result_autocomplete *next;
+	int instances;
+	int agg_instances;
+	int ac_length;
+	char elided; /* children skipped in interest of antecedent children */
+	char has_children;
+
+	/* - autocomplete suggestion (of length ac_length) follows */
+};
+
+/*
+ * The results lwsac always starts with this.  If no results and / or no
+ * autocomplete the members may be NULL.  This implies the symbol nor any
+ * suffix on it exists in the trie file.
+ */
+struct lws_fts_result {
+	struct lws_fts_result_filepath *filepath_head;
+	struct lws_fts_result_autocomplete *autocomplete_head;
+	int duration_ms;
+	int effective_flags; /* the search flags that were used */
+};
+
+/*
+ * index creation functions
+ */
+
+/**
+ * lws_fts_create() - Create a new index file
+ *
+ * \param fd: The fd opened for write
+ *
+ * Inits a new index file, returning a struct lws_fts to represent it
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_fts *
+lws_fts_create(int fd);
+
+/**
+ * lws_fts_destroy() - Finalize a new index file / destroy the trie lwsac
+ *
+ * \param trie: The previously opened index being finalized
+ *
+ * Finalizes an index file that was being created, and frees the memory involved
+ * *trie is set to NULL afterwards.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fts_destroy(struct lws_fts **trie);
+
+/**
+ * lws_fts_file_index() - Create a new entry in the trie file for an input path
+ *
+ * \param t: The previously opened index being written
+ * \param filepath: The filepath (which may be virtual) associated with this file
+ * \param filepath_len: The number of chars in the filepath
+ * \param priority: not used yet
+ *
+ * Returns an ordinal that represents this new filepath in the index file.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fts_file_index(struct lws_fts *t, const char *filepath, int filepath_len,
+		   int priority);
+
+/**
+ * lws_fts_fill() - Process all or a bufferload of input file
+ *
+ * \param t: The previously opened index being written
+ * \param file_index: The ordinal representing this input filepath
+ * \param buf: A bufferload of data from the input file
+ * \param len: The number of bytes in buf
+ *
+ * Indexes a buffer of data from the input file.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fts_fill(struct lws_fts *t, uint32_t file_index, const char *buf,
+	     size_t len);
+
+/**
+ * lws_fts_serialize() - Store the in-memory trie into the index file
+ *
+ * \param t: The previously opened index being written
+ *
+ * The trie is held in memory where it can be added to... after all the input
+ * filepaths and data have been processed, this is called to serialize /
+ * write the trie data into the index file.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fts_serialize(struct lws_fts *t);
+
+/*
+ * index search functions
+ */
+
+/**
+ * lws_fts_open() - Open an existing index file to search it
+ *
+ * \param filepath: The filepath to the index file to open
+ *
+ * Opening the index file returns an opaque struct lws_fts_file * that is
+ * used to perform other operations on it, or NULL if it can't be opened.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_fts_file *
+lws_fts_open(const char *filepath);
+
+#define LWSFTS_F_QUERY_AUTOCOMPLETE	(1 << 0)
+#define LWSFTS_F_QUERY_FILES		(1 << 1)
+#define LWSFTS_F_QUERY_FILE_LINES	(1 << 2)
+#define LWSFTS_F_QUERY_QUOTE_LINE	(1 << 3)
+
+struct lws_fts_search_params {
+	/* the actual search term */
+	const char *needle;
+	 /* if non-NULL, FILE results for this filepath only */
+	const char *only_filepath;
+	/* will be set to the results lwsac */
+	struct lwsac *results_head;
+	/* combination of LWSFTS_F_QUERY_* flags */
+	int flags;
+	/* maximum number of autocomplete suggestions to return */
+	int max_autocomplete;
+	/* maximum number of filepaths to return */
+	int max_files;
+	/* maximum number of line number results to return per filepath */
+	int max_lines;
+};
+
+/**
+ * lws_fts_search() - Perform a search operation on an index
+ *
+ * \param jtf: The index file struct returned by lws_fts_open
+ * \param ftsp: The struct lws_fts_search_params filled in by the caller
+ *
+ * The caller should memset the ftsp struct to 0 to ensure members that may be
+ * introduced in later versions contain known values, then set the related
+ * members to describe the kind of search action required.
+ *
+ * ftsp->results_head is the results lwsac, or NULL.  It should be freed with
+ * lwsac_free() when the results are finished with.
+ *
+ * Returns a pointer into the results lwsac that is a struct lws_fts_result
+ * containing the head pointers into linked-lists of results for autocomplete
+ * and filepath data, along with some sundry information.  This does not need
+ * to be freed since freeing the lwsac will also remove this and everything it
+ * points to.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_fts_result *
+lws_fts_search(struct lws_fts_file *jtf, struct lws_fts_search_params *ftsp);
+
+/**
+ * lws_fts_close() - Close a previously-opened index file
+ *
+ * \param jtf: The pointer returned from the open
+ *
+ * Closes the file handle on the index and frees any allocations
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fts_close(struct lws_fts_file *jtf);
+
+///@}

+ 170 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genaes.h

@@ -0,0 +1,170 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup generic AES
+ * ## Generic AES related functions
+ *
+ * Lws provides generic AES functions that abstract the ones
+ * provided by whatever tls library you are linking against.
+ *
+ * It lets you use the same code if you build against mbedtls or OpenSSL
+ * for example.
+ */
+///@{
+
+#if defined(LWS_WITH_MBEDTLS)
+#include <mbedtls/aes.h>
+#include <mbedtls/gcm.h>
+#endif
+
+enum enum_aes_modes {
+	LWS_GAESM_CBC,
+	LWS_GAESM_CFB128,
+	LWS_GAESM_CFB8,
+	LWS_GAESM_CTR,
+	LWS_GAESM_ECB,
+	LWS_GAESM_OFB,
+	LWS_GAESM_XTS,		/* care... requires double-length key */
+	LWS_GAESM_GCM,
+	LWS_GAESM_KW,
+};
+
+enum enum_aes_operation {
+	LWS_GAESO_ENC,
+	LWS_GAESO_DEC
+};
+
+enum enum_aes_padding {
+	LWS_GAESP_NO_PADDING,
+	LWS_GAESP_WITH_PADDING
+};
+
+/* include/libwebsockets/lws-jwk.h must be included before this */
+
+#define LWS_AES_BLOCKSIZE 128
+#define LWS_AES_CBC_BLOCKLEN 16
+
+struct lws_genaes_ctx {
+#if defined(LWS_WITH_MBEDTLS)
+	union {
+		mbedtls_aes_context ctx;
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+		mbedtls_aes_xts_context ctx_xts;
+#endif
+		mbedtls_gcm_context ctx_gcm;
+	} u;
+#else
+	EVP_CIPHER_CTX *ctx;
+	const EVP_CIPHER *cipher;
+	ENGINE *engine;
+	char init;
+#endif
+	unsigned char tag[16];
+	struct lws_gencrypto_keyelem *k;
+	enum enum_aes_operation op;
+	enum enum_aes_modes mode;
+	enum enum_aes_padding padding;
+	int taglen;
+	char underway;
+};
+
+/** lws_genaes_create() - Create RSA public decrypt context
+ *
+ * \param ctx: your struct lws_genaes_ctx
+ * \param op: LWS_GAESO_ENC or LWS_GAESO_DEC
+ * \param mode: one of LWS_GAESM_
+ * \param el: struct prepared with key element data
+ * \param padding: 0 = no padding, 1 = padding
+ * \param engine: if openssl engine used, pass the pointer here
+ *
+ * Creates an RSA context with a public key associated with it, formed from
+ * the key elements in \p el.
+ *
+ * Returns 0 for OK or nonzero for error.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
+		  enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
+		  enum enum_aes_padding padding, void *engine);
+
+/** lws_genaes_destroy() - Destroy genaes AES context
+ *
+ * \param ctx: your struct lws_genaes_ctx
+ * \param tag: NULL, or, GCM-only: buffer to receive tag
+ * \param tlen: 0, or, GCM-only: length of tag buffer
+ *
+ * Destroys any allocations related to \p ctx.
+ *
+ * For GCM only, up to tlen bytes of tag buffer will be set on exit.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen);
+
+/** lws_genaes_crypt() - Encrypt or decrypt
+ *
+ * \param ctx: your struct lws_genaes_ctx
+ * \param in: input plaintext or ciphertext
+ * \param len: length of input (which is always length of output)
+ * \param out: output plaintext or ciphertext
+ * \param iv_or_nonce_ctr_or_data_unit_16: NULL, iv, nonce_ctr16, or data_unit16
+ * \param stream_block_16: pointer to 16-byte stream block for CTR mode only
+ * \param nc_or_iv_off: NULL or pointer to nc, or iv_off
+ * \param taglen: length of tag
+ *
+ * Encrypts or decrypts using the AES mode set when the ctx was created.
+ * The last three arguments have different meanings depending on the mode:
+ *
+ * 			      KW   CBC  CFB128 CFB8 CTR    ECB  OFB    XTS
+ * iv_or_nonce_ct.._unit_16 : iv   iv   iv     iv   nonce  NULL iv     dataunt
+ * stream_block_16	    : NULL NULL NULL   NULL stream NULL NULL   NULL
+ * nc_or_iv_off		    : NULL NULL iv_off NULL nc_off NULL iv_off NULL
+ *
+ * For GCM:
+ *
+ * iv_or_nonce_ctr_or_data_unit_16 : iv
+ * stream_block_16		   : pointer to tag
+ * nc_or_iv_off			   : set pointed-to size_t to iv length
+ * in				   : first call: additional data, subsequently
+ *				   :   input data
+ * len				   : first call: add data length, subsequently
+ *				   :   input / output length
+ *
+ * The length of the optional arg is always 16 if used, regardless of the mode.
+ *
+ * Returns 0 for OK or nonzero for error.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len,
+		 uint8_t *out,
+		 uint8_t *iv_or_nonce_ctr_or_data_unit_16,
+		 uint8_t *stream_block_16,
+		 size_t *nc_or_iv_off, int taglen);
+
+///@}

+ 130 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-gencrypto.h

@@ -0,0 +1,130 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * These are gencrypto-level constants... they are used by both JOSE and direct
+ * gencrypto code.  However while JWK relies on these, using gencrypto apis has
+ * no dependency at all on any JOSE type.
+ */
+
+enum lws_gencrypto_kty {
+	LWS_GENCRYPTO_KTY_UNKNOWN,
+
+	LWS_GENCRYPTO_KTY_OCT,
+	LWS_GENCRYPTO_KTY_RSA,
+	LWS_GENCRYPTO_KTY_EC
+};
+
+/*
+ * Keytypes where the same element name is reused must all agree to put the
+ * same-named element at the same e[] index.  It's because when used with jwk,
+ * we parse and store in incoming key data, but we may not be informed of the
+ * definitive keytype until the end.
+ */
+
+enum lws_gencrypto_oct_tok {
+	LWS_GENCRYPTO_OCT_KEYEL_K, /* note... same offset as AES K */
+
+	LWS_GENCRYPTO_OCT_KEYEL_COUNT
+};
+
+enum lws_gencrypto_rsa_tok {
+	LWS_GENCRYPTO_RSA_KEYEL_E,
+	LWS_GENCRYPTO_RSA_KEYEL_N,
+	LWS_GENCRYPTO_RSA_KEYEL_D, /* note... same offset as EC D */
+	LWS_GENCRYPTO_RSA_KEYEL_P,
+	LWS_GENCRYPTO_RSA_KEYEL_Q,
+	LWS_GENCRYPTO_RSA_KEYEL_DP,
+	LWS_GENCRYPTO_RSA_KEYEL_DQ,
+	LWS_GENCRYPTO_RSA_KEYEL_QI,
+
+	LWS_GENCRYPTO_RSA_KEYEL_COUNT
+};
+
+enum lws_gencrypto_ec_tok {
+	LWS_GENCRYPTO_EC_KEYEL_CRV,
+	LWS_GENCRYPTO_EC_KEYEL_X,
+	/* note... same offset as RSA D */
+	LWS_GENCRYPTO_EC_KEYEL_D = LWS_GENCRYPTO_RSA_KEYEL_D,
+	LWS_GENCRYPTO_EC_KEYEL_Y,
+
+	LWS_GENCRYPTO_EC_KEYEL_COUNT
+};
+
+enum lws_gencrypto_aes_tok {
+	/* note... same offset as OCT K */
+	LWS_GENCRYPTO_AES_KEYEL_K = LWS_GENCRYPTO_OCT_KEYEL_K,
+
+	LWS_GENCRYPTO_AES_KEYEL_COUNT
+};
+
+/* largest number of key elements for any algorithm */
+#define LWS_GENCRYPTO_MAX_KEYEL_COUNT LWS_GENCRYPTO_RSA_KEYEL_COUNT
+
+/* this "stretchy" type holds individual key element data in binary form.
+ * It's typcially used in an array with the layout mapping the element index to
+ * the key element meaning defined by the enums above.  An array of these of
+ * length LWS_GENCRYPTO_MAX_KEYEL_COUNT can define key elements for any key
+ * type.
+ */
+
+struct lws_gencrypto_keyelem {
+	uint8_t *buf;
+	uint32_t len;
+};
+
+
+/**
+ * lws_gencrypto_bits_to_bytes() - returns rounded up bytes needed for bits
+ *
+ * \param bits
+ *
+ * Returns the number of bytes needed to store the given number of bits.  If
+ * a byte is partially used, the byte count is rounded up.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_gencrypto_bits_to_bytes(int bits);
+
+/**
+ * lws_base64_size() - returns estimated size of base64 encoding
+ *
+ * \param bytes
+ *
+ * Returns a slightly oversize estimate of the size of a base64 encoded version
+ * of the given amount of unencoded data.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_base64_size(int bytes);
+
+/**
+ * lws_gencrypto_padded_length() - returns PKCS#5/#7 padded length
+ *
+ * @param blocksize - blocksize to pad to
+ * @param len - Length of input to pad
+ *
+ * Returns the length of a buffer originally of size len after PKCS#5 or PKCS#7
+ * padding has been applied to it.
+ */
+LWS_VISIBLE LWS_EXTERN size_t
+lws_gencrypto_padded_length(size_t block_size, size_t len);

+ 211 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genec.h

@@ -0,0 +1,211 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+enum enum_genec_alg {
+	LEGENEC_UNKNOWN,
+
+	LEGENEC_ECDH,
+	LEGENEC_ECDSA
+};
+
+struct lws_genec_ctx {
+#if defined(LWS_WITH_MBEDTLS)
+	union {
+		mbedtls_ecdh_context *ctx_ecdh;
+		mbedtls_ecdsa_context *ctx_ecdsa;
+	} u;
+#else
+	EVP_PKEY_CTX *ctx[2];
+#endif
+	struct lws_context *context;
+	const struct lws_ec_curves *curve_table;
+	enum enum_genec_alg genec_alg;
+
+	char has_private;
+};
+
+#if defined(LWS_WITH_MBEDTLS)
+enum enum_lws_dh_side {
+	LDHS_OURS = MBEDTLS_ECDH_OURS,
+	LDHS_THEIRS = MBEDTLS_ECDH_THEIRS
+};
+#else
+enum enum_lws_dh_side {
+	LDHS_OURS,
+	LDHS_THEIRS
+};
+#endif
+
+struct lws_ec_curves {
+	const char *name;
+	int tls_lib_nid;
+	uint16_t key_bytes;
+};
+
+
+/* ECDH-specific apis */
+
+/** lws_genecdh_create() - Create a genecdh
+ *
+ * \param ctx: your genec context
+ * \param context: your lws_context (for RNG access)
+ * \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
+ *		       struct lws_ec_curves array, terminated by an entry with
+ *		       .name = NULL, of curves you want to whitelist
+ *
+ * Initializes a genecdh
+ */
+LWS_VISIBLE int
+lws_genecdh_create(struct lws_genec_ctx *ctx, struct lws_context *context,
+		   const struct lws_ec_curves *curve_table);
+
+/** lws_genecdh_set_key() - Apply an EC key to our or theirs side
+ *
+ * \param ctx: your genecdh context
+ * \param el: your key elements
+ * \param side: LDHS_OURS or LDHS_THEIRS
+ *
+ * Applies an EC key to one side or the other of an ECDH ctx
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdh_set_key(struct lws_genec_ctx *ctx, struct lws_gencrypto_keyelem *el,
+		    enum enum_lws_dh_side side);
+
+/** lws_genecdh_new_keypair() - Create a genec with a new public / private key
+ *
+ * \param ctx: your genec context
+ * \param side: LDHS_OURS or LDHS_THEIRS
+ * \param curve_name: an EC curve name, like "P-256"
+ * \param el: array pf LWS_GENCRYPTO_EC_KEYEL_COUNT key elems to take the new key
+ *
+ * Creates a genecdh with a newly minted EC public / private key
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdh_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
+		        const char *curve_name, struct lws_gencrypto_keyelem *el);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
+		  int *ss_len);
+
+
+/* ECDSA-specific apis */
+
+/** lws_genecdsa_create() - Create a genecdsa and
+ *
+ * \param ctx: your genec context
+ * \param context: your lws_context (for RNG access)
+ * \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
+ *		       struct lws_ec_curves array, terminated by an entry with
+ *		       .name = NULL, of curves you want to whitelist
+ *
+ * Initializes a genecdh
+ */
+LWS_VISIBLE int
+lws_genecdsa_create(struct lws_genec_ctx *ctx, struct lws_context *context,
+		    const struct lws_ec_curves *curve_table);
+
+/** lws_genecdsa_new_keypair() - Create a genecdsa with a new public / private key
+ *
+ * \param ctx: your genec context
+ * \param curve_name: an EC curve name, like "P-256"
+ * \param el: array pf LWS_GENCRYPTO_EC_KEYEL_COUNT key elements to take the new key
+ *
+ * Creates a genecdsa with a newly minted EC public / private key
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
+			 struct lws_gencrypto_keyelem *el);
+
+/** lws_genecdsa_set_key() - Apply an EC key to an ecdsa context
+ *
+ * \param ctx: your genecdsa context
+ * \param el: your key elements
+ *
+ * Applies an EC key to an ecdsa context
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
+		     struct lws_gencrypto_keyelem *el);
+
+/** lws_genecdsa_hash_sig_verify_jws() - Verifies a JWS ECDSA signature on a given hash
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: unencrypted payload (usually a recomputed hash)
+ * \param hash_type: one of LWS_GENHASH_TYPE_
+ * \param keybits: number of bits in the crypto key
+ * \param sig: pointer to the signature we received with the payload
+ * \param sig_len: length of the signature we are checking in bytes
+ *
+ * This just looks at the signed hash... that's why there's no input length
+ * parameter, it's decided by the choice of hash.  It's up to you to confirm
+ * separately the actual payload matches the hash that was confirmed by this to
+ * be validly signed.
+ *
+ * Returns <0 for error, or 0 if signature matches the hash + key..
+ *
+ * The JWS ECDSA signature verification algorithm differs to generic ECDSA
+ * signatures and they're not interoperable.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
+				 enum lws_genhash_types hash_type, int keybits,
+				 const uint8_t *sig, size_t sig_len);
+
+/** lws_genecdsa_hash_sign_jws() - Creates a JWS ECDSA signature for a hash you provide
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: precomputed hash
+ * \param hash_type: one of LWS_GENHASH_TYPE_
+ * \param keybits: number of bits in the crypto key
+ * \param sig: pointer to buffer to take signature
+ * \param sig_len: length of the buffer (must be >= length of key N)
+ *
+ * Returns <0 for error, or 0 for success.
+ *
+ * This creates a JWS ECDSA signature for a hash you already computed and provide.
+ *
+ * The JWS ECDSA signature generation algorithm differs to generic ECDSA
+ * signatures and they're not interoperable.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
+			   enum lws_genhash_types hash_type, int keybits,
+			   uint8_t *sig, size_t sig_len);
+
+
+/* Apis that apply to both ECDH and ECDSA */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_genec_destroy(struct lws_genec_ctx *ctx);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_genec_destroy_elements(struct lws_gencrypto_keyelem *el);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_genec_dump(struct lws_gencrypto_keyelem *el);

+ 187 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genhash.h

@@ -0,0 +1,187 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup generichash Generic Hash
+ * ## Generic Hash related functions
+ *
+ * Lws provides generic hash / digest accessors that abstract the ones
+ * provided by whatever tls library you are linking against.
+ *
+ * It lets you use the same code if you build against mbedtls or OpenSSL
+ * for example.
+ */
+///@{
+
+enum lws_genhash_types {
+	LWS_GENHASH_TYPE_UNKNOWN,
+	LWS_GENHASH_TYPE_MD5,
+	LWS_GENHASH_TYPE_SHA1,
+	LWS_GENHASH_TYPE_SHA256,
+	LWS_GENHASH_TYPE_SHA384,
+	LWS_GENHASH_TYPE_SHA512,
+};
+
+enum lws_genhmac_types {
+	LWS_GENHMAC_TYPE_UNKNOWN,
+	LWS_GENHMAC_TYPE_SHA256,
+	LWS_GENHMAC_TYPE_SHA384,
+	LWS_GENHMAC_TYPE_SHA512,
+};
+
+#define LWS_GENHASH_LARGEST 64
+
+struct lws_genhash_ctx {
+        uint8_t type;
+#if defined(LWS_WITH_MBEDTLS)
+        union {
+		mbedtls_md5_context md5;
+        	mbedtls_sha1_context sha1;
+		mbedtls_sha256_context sha256;
+		mbedtls_sha512_context sha512; /* 384 also uses this */
+		const mbedtls_md_info_t *hmac;
+        } u;
+#else
+        const EVP_MD *evp_type;
+        EVP_MD_CTX *mdctx;
+#endif
+};
+
+struct lws_genhmac_ctx {
+        uint8_t type;
+#if defined(LWS_WITH_MBEDTLS)
+	const mbedtls_md_info_t *hmac;
+	mbedtls_md_context_t ctx;
+#else
+	const EVP_MD *evp_type;
+
+#if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key)
+	EVP_MD_CTX *ctx;
+	EVP_PKEY *key;
+#else
+#if defined(LWS_HAVE_HMAC_CTX_new)
+        HMAC_CTX *ctx;
+#else
+        HMAC_CTX ctx;
+#endif
+#endif
+
+#endif
+};
+
+/** lws_genhash_size() - get hash size in bytes
+ *
+ * \param type:	one of LWS_GENHASH_TYPE_...
+ *
+ * Returns number of bytes in this type of hash
+ */
+LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
+lws_genhash_size(enum lws_genhash_types type);
+
+/** lws_genhmac_size() - get hash size in bytes
+ *
+ * \param type:	one of LWS_GENHASH_TYPE_...
+ *
+ * Returns number of bytes in this type of hmac
+ */
+LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
+lws_genhmac_size(enum lws_genhmac_types type);
+
+/** lws_genhash_init() - prepare your struct lws_genhash_ctx for use
+ *
+ * \param ctx: your struct lws_genhash_ctx
+ * \param type:	one of LWS_GENHASH_TYPE_...
+ *
+ * Initializes the hash context for the type you requested
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type);
+
+/** lws_genhash_update() - digest len bytes of the buffer starting at in
+ *
+ * \param ctx: your struct lws_genhash_ctx
+ * \param in: start of the bytes to digest
+ * \param len: count of bytes to digest
+ *
+ * Updates the state of your hash context to reflect digesting len bytes from in
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len);
+
+/** lws_genhash_destroy() - copy out the result digest and destroy the ctx
+ *
+ * \param ctx: your struct lws_genhash_ctx
+ * \param result: NULL, or where to copy the result hash
+ *
+ * Finalizes the hash and copies out the digest.  Destroys any allocations such
+ * that ctx can safely go out of scope after calling this.
+ *
+ * NULL result is supported so that you can destroy the ctx cleanly on error
+ * conditions, where there is no valid result.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result);
+
+/** lws_genhmac_init() - prepare your struct lws_genhmac_ctx for use
+ *
+ * \param ctx: your struct lws_genhmac_ctx
+ * \param type:	one of LWS_GENHMAC_TYPE_...
+ * \param key: pointer to the start of the HMAC key
+ * \param key_len: length of the HMAC key
+ *
+ * Initializes the hash context for the type you requested
+ *
+ * If the return is nonzero, it failed and there is nothing needing to be
+ * destroyed.
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
+		 const uint8_t *key, size_t key_len);
+
+/** lws_genhmac_update() - digest len bytes of the buffer starting at in
+ *
+ * \param ctx: your struct lws_genhmac_ctx
+ * \param in: start of the bytes to digest
+ * \param len: count of bytes to digest
+ *
+ * Updates the state of your hash context to reflect digesting len bytes from in
+ *
+ * If the return is nonzero, it failed and needs destroying.
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len);
+
+/** lws_genhmac_destroy() - copy out the result digest and destroy the ctx
+ *
+ * \param ctx: your struct lws_genhmac_ctx
+ * \param result: NULL, or where to copy the result hash
+ *
+ * Finalizes the hash and copies out the digest.  Destroys any allocations such
+ * that ctx can safely go out of scope after calling this.
+ *
+ * NULL result is supported so that you can destroy the ctx cleanly on error
+ * conditions, where there is no valid result.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result);
+///@}

+ 254 - 0
Source/ThirdParty/libwebsockets/include/libwebsockets/lws-genrsa.h

@@ -0,0 +1,254 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*! \defgroup genericRSA Generic RSA
+ * ## Generic RSA related functions
+ *
+ * Lws provides generic RSA functions that abstract the ones
+ * provided by whatever OpenSSL library you are linking against.
+ *
+ * It lets you use the same code if you build against mbedtls or OpenSSL
+ * for example.
+ */
+///@{
+
+/* include/libwebsockets/lws-jwk.h must be included before this */
+
+enum enum_genrsa_mode {
+	LGRSAM_PKCS1_1_5,
+	LGRSAM_PKCS1_OAEP_PSS,
+
+	LGRSAM_COUNT
+};
+
+struct lws_genrsa_ctx {
+#if defined(LWS_WITH_MBEDTLS)
+	mbedtls_rsa_context *ctx;
+#else
+	BIGNUM *bn[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
+	EVP_PKEY_CTX *ctx;
+	RSA *rsa;
+#endif
+	struct lws_context *context;
+	enum enum_genrsa_mode mode;
+};
+
+/** lws_genrsa_public_decrypt_create() - Create RSA public decrypt context
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param el: struct prepared with key element data
+ * \param context: lws_context for RNG
+ * \param mode: RSA mode, one of LGRSAM_ constants
+ * \param oaep_hashid: the lws genhash id for the hash used in MFG1 hash
+ *			used in OAEP mode - normally, SHA1
+ *
+ * Creates an RSA context with a public key associated with it, formed from
+ * the key elements in \p el.
+ *
+ * Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses.  It's
+ * recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations.
+ *
+ * Returns 0 for OK or nonzero for error.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_gencrypto_keyelem *el,
+		  struct lws_context *context, enum enum_genrsa_mode mode,
+		  enum lws_genhash_types oaep_hashid);
+
+/** lws_genrsa_destroy_elements() - Free allocations in genrsa_elements
+ *
+ * \param el: your struct lws_gencrypto_keyelem
+ *
+ * This is a helper for user code making use of struct lws_gencrypto_keyelem
+ * where the elements are allocated on the heap, it frees any non-NULL
+ * buf element and sets the buf to NULL.
+ *
+ * NB: lws_genrsa_public_... apis do not need this as they take care of the key
+ * creation and destruction themselves.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el);
+
+/** lws_genrsa_new_keypair() - Create new RSA keypair
+ *
+ * \param context: your struct lws_context (may be used for RNG)
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param mode: RSA mode, one of LGRSAM_ constants
+ * \param el: struct to get the new key element data allocated into it
+ * \param bits: key size, eg, 4096
+ *
+ * Creates a new RSA context and generates a new keypair into it, with \p bits
+ * bits.
+ *
+ * Returns 0 for OK or nonzero for error.
+ *
+ * Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses.  It's
+ * recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
+		       enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
+		       int bits);
+
+/** lws_genrsa_public_encrypt() - Perform RSA public key encryption
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: plaintext input
+ * \param in_len: length of plaintext input
+ * \param out: encrypted output
+ *
+ * Performs PKCS1 v1.5 Encryption
+ *
+ * Returns <0 for error, or length of decrypted data.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+			  size_t in_len, uint8_t *out);
+
+/** lws_genrsa_private_encrypt() - Perform RSA private key encryption
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: plaintext input
+ * \param in_len: length of plaintext input
+ * \param out: encrypted output
+ *
+ * Performs PKCS1 v1.5 Encryption
+ *
+ * Returns <0 for error, or length of decrypted data.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+			   size_t in_len, uint8_t *out);
+
+/** lws_genrsa_public_decrypt() - Perform RSA public key decryption
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: encrypted input
+ * \param in_len: length of encrypted input
+ * \param out: decrypted output
+ * \param out_max: size of output buffer
+ *
+ * Performs PKCS1 v1.5 Decryption
+ *
+ * Returns <0 for error, or length of decrypted data.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+			  size_t in_len, uint8_t *out, size_t out_max);
+
+/** lws_genrsa_private_decrypt() - Perform RSA private key decryption
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: encrypted input
+ * \param in_len: length of encrypted input
+ * \param out: decrypted output
+ * \param out_max: size of output buffer
+ *
+ * Performs PKCS1 v1.5 Decryption
+ *
+ * Returns <0 for error, or length of decrypted data.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+			   size_t in_len, uint8_t *out, size_t out_max);
+
+/** lws_genrsa_hash_sig_verify() - Verifies RSA signature on a given hash
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: input to be hashed
+ * \param hash_type: one of LWS_GENHASH_TYPE_
+ * \param sig: pointer to the signature we received with the payload
+ * \param sig_len: length of the signature we are checking in bytes
+ *
+ * Returns <0 for error, or 0 if signature matches the payload + key.
+ *
+ * This just looks at a hash... that's why there's no input length
+ * parameter, it's decided by the choice of hash.   It's up to you to confirm
+ * separately the actual payload matches the hash that was confirmed by this to
+ * be validly signed.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+			   enum lws_genhash_types hash_type,
+			   const uint8_t *sig, size_t sig_len);
+
+/** lws_genrsa_hash_sign() - Creates an ECDSA signature for a hash you provide
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param in: input to be hashed and signed
+ * \param hash_type: one of LWS_GENHASH_TYPE_
+ * \param sig: pointer to buffer to take signature
+ * \param sig_len: length of the buffer (must be >= length of key N)
+ *
+ * Returns <0 for error, or 0 for success.
+ *
+ * This creates an RSA signature for a hash you already computed and provide.
+ * You should have created the hash before calling this by iterating over the
+ * actual payload you need to confirm.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
+		     enum lws_genhash_types hash_type,
+		     uint8_t *sig, size_t sig_len);
+
+/** lws_genrsa_public_decrypt_destroy() - Destroy RSA public decrypt context
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ *
+ * Destroys any allocations related to \p ctx.
+ *
+ * This and related APIs operate identically with OpenSSL or mbedTLS backends.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_genrsa_destroy(struct lws_genrsa_ctx *ctx);
+
+/** lws_genrsa_render_pkey_asn1() - Exports public or private key to ASN1/DER
+ *
+ * \param ctx: your struct lws_genrsa_ctx
+ * \param _private: 0 = public part only, 1 = all parts of the key
+ * \param pkey_asn1: pointer to buffer to take the ASN1
+ * \param pkey_asn1_len: max size of the pkey_asn1_len
+ *
+ * Returns length of pkey_asn1 written, or -1 for error.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private,
+			    uint8_t *pkey_asn1, size_t pkey_asn1_len);
+///@}

Some files were not shown because too many files changed in this diff