summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/mongoose/examples/websocket_ssl_proxy
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-01-10 13:30:30 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-01-10 13:30:30 +0100
commit8556d0cdf7058be2c519bd4d8e7006ea9e913527 (patch)
tree09594058dc17564b4ff3c106581d0856cf69c2d5 /3rdparty/mongoose/examples/websocket_ssl_proxy
parent61f7cd05dfed932dd1be927608a4989c187cc737 (diff)
Added integral source of mongoose (nw)
Diffstat (limited to '3rdparty/mongoose/examples/websocket_ssl_proxy')
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile15
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem49
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem49
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem45
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h253
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c123
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h34
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c182
-rw-r--r--3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html50
12 files changed, 935 insertions, 0 deletions
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile b/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile
new file mode 100644
index 00000000000..bd3f6be1297
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile
@@ -0,0 +1,15 @@
+# Copyright (c) 2014 Cesanta Software
+# All rights reserved
+
+PROG = ws_ssl
+CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 $(CFLAGS_EXTRA)
+SOURCES = ws_ssl.c ../../mongoose.c ssl_wrapper.c
+
+all: $(PROG)
+
+$(PROG): $(SOURCES)
+ $(CC) -o $(PROG) $(SOURCES) \
+ -DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY -lssl $(CFLAGS)
+
+clean:
+ rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem
new file mode 100644
index 00000000000..ebc7d8fd5eb
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_ca.pem
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwizPnrCx+/kPSdEeSJFLDXrBH+cSQsSLrCm99G1hCjzqSlIk
+1BhkZMEHxBaiVLky4+M/nwhjwwRHI10h6U2Or3tbPLv7z94cPf+uCx1aF7TE3Fm3
+6YnDk+CjrYVFN5GRPGOPPdFxGoc+vFvQJyAAimvchnS1ZoEQFvermwzOnKspA6gc
+Px+7wnOeju9TyJuDr5ngtDXFnkcpkBNPxz3En4MJY4xJiaueafh9pIES2vSl7uP0
+J/qot9v2rdiL7nt1H1vwseeEkZhQ+NLB5e2z4psyktJcwDX7wQ6j7JnKfHeP+ixO
+TUORgV4foBMVOqo//Guo92Q5HoLNK77V0y4+ZQIDAQABAoIBAGEsx+LlDs3JQQty
+KjOq8uKWElyC6bKcZkIMydGvg6b6AU6ceW3jnyqFJ/vMUAUSghNmQQq3yiVo2Kks
+DLKTa9sKYwisE0NeJsgoUtOhJttCTlrwU4f+t/AjtgY68f7zTLnqIV+Ql4ftM0pU
+sIFEFMExZbWsZrQb1w+Hd0wrRqNEbSOfSjHeigvuw1T3GH2tSBUTGTpcoewCzy7U
+PKS5pkYyiKySQQNqZTac3NHPjxdK6xxzwURZp1irKdiPdt04KHLVLX8KXelt/J0k
+AeYkVbpFIeQ9rNBerMEp6uRBt+nE5mvP+xx1XPqKRxuxbMyTnBXeOM2zS/a/dBiz
+fwokwcECgYEA9RSsv9AQ/AR8tt+aPEQvjhJ5pn/YbCb1DA9IDXpaq3tzacGd8JHj
+3kUtb79nosu85LvSkAYmtzgfJs6xZyUkscra6q+xlsJ12QRxLzqfxcp9Y0wsdqM4
+AcOwuiPKrjkWxOQpyWPWRwbmAefLfRMekHt4Y/QY0CwhslpnsOsj3O0CgYEAytOE
+8I4GBfSQfSjXwfrso++Oi75VSsl5ZeiMGihfEhYFTE8/3rEZf7nf9iFSkN3TT+7f
+pFqQzddzPBZXlpVM6k1jcEjdpJizbeR8DmICpABFrZvKz1o8pQ2Yw+FYI86ih0x4
+806snMNgg/RgcVijXKFrC5joJOI+DVgwWoQyMFkCgYBxt4MkiV2oIkjf7ca6GgVa
+zbXGjOGV5Umkq96J6nDxyplVw/IN8xOhScX4aP6kahaep4vfKguCzjaeIh/stS5e
+lLqZVKZ5Roe6B7ag7HnAI+GkVm73KWrOXse8xui/iFvJRfkhqgJ9+HR3A9/GjD2N
+Ws0Uy+lLhn6oLAya6bA9TQKBgAVfZP4aRP6TY+Bs3Io+41XUWqpI+GlqvNR+PHfU
+6e/ItYs37jEv78T6X3xdlZpQxfAwG6x22a8aLetBjEBo5Aiw1Bl9VKGvidE3ZDHd
+VsSRXUckAVNMyJ52pb1KktMf/h4nYGzRgLEGW+Ai8QsPlgQ2ImfEPSH8/DfORjmf
+ltTBAoGBAMxIZ52DrJvuxogSOfA1MoCD6a90trkXCquvi+A/fXojZ8BHmMQshvhK
+rAO7SDIV1i1Nh3jQ/oFWE8KOprqrOLO6jNTyF65vh+zk7ztGsEME9FkDhHasUiXf
+t5PE9KeTChHRvIa4FGCl9We9GftE5Ii77LWMOIq22pyxYbvHQFEf
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIJAIOoO+AapJ5WMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
+BAMTA3dzMTEMMAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
+bGluMB4XDTE0MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMD
+d3MxMQwwCgYDVQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCLM+esLH7+Q9J0R5IkUsN
+esEf5xJCxIusKb30bWEKPOpKUiTUGGRkwQfEFqJUuTLj4z+fCGPDBEcjXSHpTY6v
+e1s8u/vP3hw9/64LHVoXtMTcWbfpicOT4KOthUU3kZE8Y4890XEahz68W9AnIACK
+a9yGdLVmgRAW96ubDM6cqykDqBw/H7vCc56O71PIm4OvmeC0NcWeRymQE0/HPcSf
+gwljjEmJq55p+H2kgRLa9KXu4/Qn+qi32/at2Ivue3UfW/Cx54SRmFD40sHl7bPi
+mzKS0lzANfvBDqPsmcp8d4/6LE5NQ5GBXh+gExU6qj/8a6j3ZDkegs0rvtXTLj5l
+AgMBAAGjgZwwgZkwHQYDVR0OBBYEFL54xAgtJTW6US4Mbr4QG0yKzvaxMGoGA1Ud
+IwRjMGGAFL54xAgtJTW6US4Mbr4QG0yKzvaxoT6kPDA6MQwwCgYDVQQDEwN3czEx
+DDAKBgNVBAoTA3dzMTELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAIOo
+O+AapJ5WMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJz/RzMa9Wa2
+eEXed7ijH1gcWtgVsVT1xZo0ksFl+QJ5Be1AJpOIe8nKdzYjxPWUkofIoaGHdMLL
+Uc/udRzsXncup+0mD+Yos6Cqyo9yHq7L1HbXfKYZtBXIjWHdF2+RP8j9tHfITXYI
+Pb2zsQ+A6PYpp5OLGZTDAnI2qffqsmwXFNhPfFhOANrGlOjsvy1P7JDzvymj/90m
+NomlO3vjxLHOf6MvedTgCB0dRcAoUWPgbxPWifjBmGBjQjA4ukMQ58wbBQgvIoCW
+obrXmLCNZIkpWTw4gMRYquY880IYK/OuFNJH/dawxx/WzuVr7IdLmbFY15zf5TUb
+ZpIpwqRCysg=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem
new file mode 100644
index 00000000000..82e99504cb8
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_client.pem
@@ -0,0 +1,45 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAwOp1RS9RnE8L5TszDPIOmpf/1pqb+ki99l/sGhqB/KZBKCuq
+uoCc2VPK3PCByBE15/xJ7t691FnJfForI9DO5p2R0FPD6o357hqRsh0dJNBm0VgG
+iNtLQ8lyYoE72HJbkgCAUZW4N0OBibOmvp/s3Fmr7rEjW5LmZxOtX+iULKIUZ0w6
+gJlM8G5QA1SuqndN0PbPx+RZKSXZCoJj+Nboqw03nyJUexzs+lynR9ITMziUaaVM
+4rzG+P6joQAnUkDNydxo/d4tj4xaioZdKxWLYEbj2BUtOlJJydotWo2wcG85ONrT
+Gw0ltR1vku1hidMm2QL30uGIL5SeqyE8TqWk4QIDAQABAoIBAQCxHtKauc45MA4g
+4hCGAzvLTmETnRI2YlEfAoTYlpvf5pkOE8GFyI25r4gjACJ4GO0gWG9dBF7Pt7wZ
+EwRmttEvxV3aIv5OvRnKNdSs7rQSV9D+xc4CGy1oSG1f6X2TxbMzQoiN32OqQa2O
+S0Z94IFs8lu8JCDtc9tcqiFVXEmnC3RvJZOShWpsCsbmh5ue1Xed0MQQ47vt7Zt7
+I0cutvwSFJMsZkZUJp5+KjVNYo9TEJxVD3m2NJNJxBfBoRVHXNii3hUEHcTIdIAz
+omtRwBU8AKgJirGIRo1h2ZFyubI8ScGOJWIiWMQvQqTHKiOaz3yUar1NSG+kFn0U
+cj7s3FhdAoGBAOQbx8Jwhtp4iOkP6aW1nVTgiaTj4LMlyJZioFwgPFRIcA3oRHt9
+5SRetmgFZNvcuNw1udfeaObKmlzxwUruprwOpihgAQWJFTtOjQNrt2gsYuX4l3W6
+T46dO2W1pV+mW4A5gt0aqhLv7pCS4lpreNAqyHSPqcQWcCeiTzmp/LfDAoGBANiB
+FQOTyMElR9OzKwmcGfIvnhUfJQwi5qNE3R+xXiP5x36a9HQBey5ri2lnBle0Ksr/
+G+RKoflmk1eFXVHN0w35yw0dVco//WE4vOknldNEnIT85k02ld8lDTa2Q/EJZtPH
+un6zeU0Q2/4SZ/GXPssEZPlpPM7WtQzztlH3+sqLAoGBAKnhppvAgi4ippQsLa4j
+29BiiSAsNiQ1d3XIbfUubL+4UvuIh7gQwp6biu1dVwgHEgWuXYHPOgDn0p51zaao
+pbRYlJZtKVWeChnpHkv15NnIdL8grGwZHTbxElNlPIxHsM2GB1fzi8YeumUhf0In
+2AnwUum8NIq8yzo5PxeK6ZNRAoGBAIEA2Q6ankJH/nZsCbbeJq+iI+Wd+ysyGI8s
+Vz2tJ9Tz3iTYG9SLlWRhfF4/nw3fMqhmPa5Xsg+zSRQbSTGXHKz1LEISOq4aVtX5
+QscCaUnLVh//uRJE9iRSJX92NyGGYpjKJ5ubQSnkY9EOEpVnc2jwo2HhjPQKBzNC
+fF53Dh5lAoGALwTN5uxrBZLPu4DtZkOosKkv4l+kzFoOjLJR4vA7ONBx2CSe9G7F
+tSsH7lZS3b0mxBWjO90WhaSvtMWWrfqq8vrqmoTE795fYxNoLfCLK13W31aTDUsI
+pQRJIL30MPvASbcFHN2MD2dXz2nQzY8C9lvtvap/krYiDKDU2L7+iP8=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdQCBRQHBXNHMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
+MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
+MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
+VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA6nVFL1GcTwvlOzMM8g6al//Wmpv6SL32
+X+waGoH8pkEoK6q6gJzZU8rc8IHIETXn/Enu3r3UWcl8Wisj0M7mnZHQU8Pqjfnu
+GpGyHR0k0GbRWAaI20tDyXJigTvYcluSAIBRlbg3Q4GJs6a+n+zcWavusSNbkuZn
+E61f6JQsohRnTDqAmUzwblADVK6qd03Q9s/H5FkpJdkKgmP41uirDTefIlR7HOz6
+XKdH0hMzOJRppUzivMb4/qOhACdSQM3J3Gj93i2PjFqKhl0rFYtgRuPYFS06UknJ
+2i1ajbBwbzk42tMbDSW1HW+S7WGJ0ybZAvfS4YgvlJ6rITxOpaThAgMBAAEwDQYJ
+KoZIhvcNAQEFBQADggEBABPLmq6zKOMY0WRjtBoSymq6f+vXeEwtWCfVejdG6RlG
+/PTdCKNvp3OL7FDnmQQ+r5rMs4+Os4fX/g315QFKXu01rqxmFb2XVNhhaECdUWtK
+QP6ZoVZviUiDjhK6a+05aerPCJpkGy/lz0W6gmj4qhuAQbobxb6UbzqTRYY+ZwGk
++SI3TAVCdmXFlxN/M9b0DbmkseRG8GGFmyRYyRb84vbV6zemFI++5ROUT9zXT7ey
+nYfFJvAAk5jJhY5UP2aMlVWYYa4jUZrrPLoiBLUuRrp67EKGebCH9mgCIf8ztNJF
+fpuvcz++LUeRyTlAGDefe+FyHGIwFzIfZn39D7CaRvM=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem
new file mode 100644
index 00000000000..93ef657ec6f
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws1_server.pem
@@ -0,0 +1,45 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyal0BZKRYd+Wpxv4MB8LjjgXv/MxSN5oSAKThlCZ/AWG0FEP
+d4nrBACT2xUxwo+xbYl3joiwL/eCPAp6QNKRGhvXVOnSIFVSjKZWbdX+toqK9pDS
+QMDTL4ZJvK6pLZXknyHjEr0PxZh22F7iS1+C8HxBPj0Xgg/u5/+jPhFPPZ1d5elv
+4cm/z+xy6RjFlA80aIeK7dcWssOsOIPjUNFfmoYgR63ScZIlUZj6j8VX9oX7fJID
+jumGajDxgD2nBWFbHcGKin6bz/wZ+OIhXOCDdY7oKuMW4JiBwbfBtedkQuQYS11s
+PRFFYDLoZH59Ivcu0c4F2tomE86qM8THsI910wIDAQABAoIBAG55FAQRfO8/C0rU
+eavy9eOdOvV+hltC66G3N5X3BcQYSvhHz89OkJ6KqnT0MWRCT5KQIhzFKK++SWwW
+2U41jCPfaKEtzlzEIQrH/MUC3Byn3OSiBWxPteFtEWv5ytgcKzg52iljxQYcNc7m
+e9WKpzKS/zLXSM+JZvlVA9p2pRA88kUZ/EE5H+FW3kHj5eGNqX+cxUVpL0VKTiLv
+aXWjYotpmDJW/Rn9wRQethm6Gdx3bvo+LEVlJRELNq8NM5H/tZIVRzudJOgzsw5v
+3OQGhfKB6Eg/vqSFoZxX6ApXDxmtaSO83B0kK550bDVv4sBnOExGjKCzybt04tet
+KtLPPoECgYEA5WUD+mFL99sCX6pzIyUVlxp9eUhVy5nvhoF6u3mvhay2XsZUY0wy
++/qVqYSZTvuvJ6JSXc4iVIX8u/gj7914805AwujepIF/8E0AaXLBMndzDE4ze5S5
+2RHI7Cy4/3AWOcQ9wFFmUdSs7/6oAkcQtvzP40hGg3J2jAEhIdCqmbMCgYEA4Q0G
+BYP9XeTdh0C+BcP9B5VUEC0jerYS8VqVqriB+9JfT3InI7K08sOG2DiQQBhAHuzL
+RhCECU2a9j0+u5F5JNeY5m3IhU73Lw+lOlUkMaAO6x7JJEzhXhonE7Kv8fWygr/0
+OB7yzqz+YsWdQ2VOPZ88ntlAYE65vzcaVswZY2ECgYEAr7Gt2VA6Ei0A5Wq0Yr+d
+iKz2WzUG2TkelqOG8B4kTDrbNz2qFp+fERV9GWgAz9i+75lIgqZF7vzsdL96LtYv
+NBLEUURwegjhh5hCb4E/7bpFOLCQh9+CdHpFrHYYfzRHIZlnPmxZ9OTyS6J85bmu
+WKjLRKXvs++wUkzvJmoesDcCgYEAkTOB6xUZ5/a+J4HSGI43NylVr4owFgBbgHVd
+k2SwGPXGoM+aCSJINUmKOv9jsrbyyAEntfD5/7aegLlLPGHDs82WzTWP5tLoEOkb
+ReOhEpOejHy0ckNYNQrSo5bqhkZsAogu3fa52jcrejbeHJnEPWX8CtFJA9pHZeP7
+jnzo9IECgYBefHg0dymSj2xxN0XmC+S5cvQu2K/NYUpatoWvHnPiQ87wIM0AWz0O
+D0ghEI+Ze57NbtSrrcTE7hY/LHrAqXGAB9XNIM5g9Pp/lM+XjzKVr1FMf4xpuHf1
+VJJRHrOU14CvMvKbgbPrL6B0d5yrYmeex7GxNw0ZVvtjCa502Eck+w==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdQCBRQHBXNGMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
+MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
+MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
+VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJqXQFkpFh35anG/gwHwuOOBe/8zFI3mhI
+ApOGUJn8BYbQUQ93iesEAJPbFTHCj7FtiXeOiLAv94I8CnpA0pEaG9dU6dIgVVKM
+plZt1f62ior2kNJAwNMvhkm8rqktleSfIeMSvQ/FmHbYXuJLX4LwfEE+PReCD+7n
+/6M+EU89nV3l6W/hyb/P7HLpGMWUDzRoh4rt1xayw6w4g+NQ0V+ahiBHrdJxkiVR
+mPqPxVf2hft8kgOO6YZqMPGAPacFYVsdwYqKfpvP/Bn44iFc4IN1jugq4xbgmIHB
+t8G152RC5BhLXWw9EUVgMuhkfn0i9y7RzgXa2iYTzqozxMewj3XTAgMBAAEwDQYJ
+KoZIhvcNAQEFBQADggEBAE20gAykuuaCoP49GnZ/Z6ZItFry4Fl6iCWBDdEsWI9R
+wRNYumeaeejdFPXfSJdTT7UlrVK1WWGLQLq+ixHRDX+V9T67ou85F92H/OxbUoPr
+iz/TZAEBTC1GvTJl49lsfPl1dTWH8T4Ej2hxCUvIJrkCkI2Ov4Wwef6A26USrwBt
+S/CPInjCe6qkE5E8xfTDl8k5IIgMadTPhi5sbV2piBJoN4floJPqR0hdDKbgUymn
+5WNSiRkuI6UIDZwQEp+A8TmFBHbSwfTGt2Sz5iI27P8J6pFvR5eRA1k57dRUWNXC
+WAU1nqteP3QAjj9L3o8IO0T62scaiJX8x01gTmVVe2I=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem
new file mode 100644
index 00000000000..9345a94a60a
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_ca.pem
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwXIMpHuTNsro2pxe6y1mu27md2Olhvfx26rO3maO0/stIC2z
+G/xQatFDLIWzfKFYOT0iSEj252ENFDCw6aDRKpiaUFtXcMAWkNkkKntEyoEgE45k
+rTrvpay0v0B+ojwjA1Jz/9v35cgvDwTs3vNFno5HhI0m2YF4ocTmeHJ6u0xRL/qy
+atfKsfuVq5s5CXOYCXp3Ux6kJ1c22J0EdZMvS75SVjAZgRkqQpqt9L3e2ZBCEgUr
+w0KwlERvpeJF+sJJOshXjfrDzvwL8IpPnGZLJNINFbSJMk5MFGcMyq/28pSZLB9E
+Dh8vk5D5gUnxM60ONUy2nYPcYr5p1PLDiC8hfQIDAQABAoIBAB0Twpi6xn8W8vdh
+R9c75NRJsDTD8q6d+GnXe+7sJY3xlG/gzqpnO8NCn0FC+57BNdystsl8xjgzW17s
+jrsfZDFt7MwlXrhg90NgkFIeY1G5JRQrdDChykHx+t1AmYhTV8P5EdykuNd+RqyQ
+RfahRJa3tkJTYUKSdoqCaU4zjwU2CSxltuJx24V+WoZE12EwewJ8HPg2XTnbsGE7
+Fnx5s29O4ItM70CC0536AY/OgfuPix5z573VQiilqqfOQkVkKa1fHd6tGpWU+3kH
+X9FnhEBf9cN9tVgmaB0sCSVVrfgqSXg1EwKHqe/+FCumuesA68Q35+/K3b+QrNiR
+ka2yliECgYEA+V/4pbgG/lPYvTwWhKxGXXdJmrSPgZC0mwE+fRuYkeptbIkS0pwt
+/UDTXk9nttj1f1ZJ3NgQbT/1w8jpXfsCJ8VeGzL9+ADhRKWVFRlu/nyFCMXawLEV
+rot7SEr8BW/m8moHgY5lYipM3dXJPk0F+KLrN60U/aNmFUtPGW802BkCgYEAxpWy
+FGL2sEQ0QaRDTcqqF5faVqw+5rVGvN+EX5o26E0QWWnoo3L2c2/5X93iBl+Fqtnm
+9jSIQUC3rYOawKnZ/HcIE2ergFit/p6JaV9NiLDRtDUmSzlffEGVCj0neYFsnWp5
+zcmkUyZ6fr19EmKQWfdteNBlXue32TjVlFbfUQUCgYAfMbgi0sBdNBPaqBeRBRPQ
+QUm9xnRlGrrc4Oz2LWuKZS7G8uad3deK5H8MPxaUMtOS2DJpI8X6RJPzp8A5d1qv
+quq4sEpAqauEMMpTV1khEGZ70HQqwnwZ12zWgDrCW1siW80QkcVw4CW5YjLITk4+
+6fJOhqInkDcG1uLQJa8QkQKBgQCfs8l4DbJ4RRGFbLXXvNGXkb68j18yqLxPrq3F
+OL9JiJhKYBsAP7clVPrG9ykLmQxlP0I35D1jxMkymLD+mlo9Z/itqmTJHggnyZWW
+kVdIQ3MSKuA2BNjek9tpVY8Gb2hLHFMChVRKrpo6jOclvvB5+bsnOukbLtyyq7tP
+xaFohQKBgByCmlltjOBWZLFLeA1x8j3inm9zM/FAJuANbHUOZ1RwrRcNFbDv/FXm
+rLPnPCaH5AwAWhVRJcNHo37Ee0s/xqe+Q4dG4xL943k+6KlopAw1SXhuXF6PnBfF
+y+ArVlh9d2oWN5cBEzRddnWnKJuMi70kMzYf6dIW9s/dHbq/gFDy
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIJAJDtcXU2wiJIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
+BAMTA3dzMjEMMAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
+bGluMB4XDTE0MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMD
+d3MyMQwwCgYDVQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBcgyke5M2yujanF7rLWa7
+buZ3Y6WG9/Hbqs7eZo7T+y0gLbMb/FBq0UMshbN8oVg5PSJISPbnYQ0UMLDpoNEq
+mJpQW1dwwBaQ2SQqe0TKgSATjmStOu+lrLS/QH6iPCMDUnP/2/flyC8PBOze80We
+jkeEjSbZgXihxOZ4cnq7TFEv+rJq18qx+5WrmzkJc5gJendTHqQnVzbYnQR1ky9L
+vlJWMBmBGSpCmq30vd7ZkEISBSvDQrCURG+l4kX6wkk6yFeN+sPO/Avwik+cZksk
+0g0VtIkyTkwUZwzKr/bylJksH0QOHy+TkPmBSfEzrQ41TLadg9xivmnU8sOILyF9
+AgMBAAGjgZwwgZkwHQYDVR0OBBYEFLK4flD5QD/mRufsPx63xlEKM8pwMGoGA1Ud
+IwRjMGGAFLK4flD5QD/mRufsPx63xlEKM8pwoT6kPDA6MQwwCgYDVQQDEwN3czIx
+DDAKBgNVBAoTA3dzMjELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAJDt
+cXU2wiJIMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEYD+CReikYr
+Rzvk+/Vdi/7IcaH9CFknIdtineSIw1y98nxnbnNJqxwfNaRblbYvg6OFdUI3POuI
++rdYLCFl8z3tWqRHLkGqHSJA9xcng3jLJxz0+ctiVcekJvXaB3O6eSZjhGbmmI/s
+CQhdy2zpEIVOeUq50DrSJp9CknyGu/IkaGx5GOZtkiHMrpig50CRjX1lS6qrMNYp
+vB8gfuqpjsL4Ar3vg+lgMSwNWXBNHrIRPHB5VEzBEdmLFZlvueR0ooEMCklpwX/a
+lFImVc6JcY1pBEkHTiTLGMpGAHG3I1aVUaWb3L+V+2ym/KNRNL5C2+1eiqql5u8m
+HUaOcNC90ew=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem
new file mode 100644
index 00000000000..8021de3c8a3
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_client.pem
@@ -0,0 +1,45 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA0ucemqFwBFziVOgTgx4mZII4WnGDpA/rWAGHvUZOqy2dQ3Pz
+woGKxBaVPAl5kxEosROVGa7dTuq5yFZ4XIGvwCKxF30vCmdGCytqq6MMp904jG32
+KikkmjCApIMGxMO4eoBHZZxiyVvKTbg9M2CRXErwnYWhFH/qGdPnuo0CEaHJA4VK
+A9incT9dpeEhU30R6ajAe/je9rCj2OMLMFSMfd51L/VYfO60zDwUNY7YVIghQZgJ
+e44EVGsp1pXaqaD6o3PvGY3ohw2aZjJzlJ7MJHbKV9lft98R3pklbpBzMH849cEy
+Q/51L/rlfTUgCpTy7wEZpWHQNtHfu/1rhJjpNQIDAQABAoIBAQCUNIHXG/dBuZv7
+GpMLotZL7w520Co30lAJqhmfMpb5x7YpvoPffXTsUwpQBECAzqAPv7kZMT6nxF8F
+n245Y5EDrd1QqlGyN9yK4Nm2/39XPygL1wITopHsIIVmFgVdpEQxIZAKoZjx8yT4
+9K1dO1Eq0CbCKzOE2lbCC51eBNUdWZIMxwC6O/j/KoIkZ/HwlG2hpUuXg8x/XawA
+ZJDCoTcWHCjYP10FxKVN3vAyWM2IM44o9IbsAGEOswR4gUwRsgq6Ehc1U59XUHi+
+x30oda55I1/8xD+SfP/zk2dDPHkv/hq5+258GU/THsw2+AAexocvSIS/g9EppTEg
+biFaDKzJAoGBAPqey10JeyiOlHbBjoSSa7lJYUjocQANFQ4ayOAgfNX72iyabrKF
+p9sVAeO/nM00+DPrm2wWws03ScsPeh+9BDJMPRBUHfSNp7+F+oyj7PWHBEFHbyO9
+5HnYZP+1vhdG2dYPIY2gRSFXpiGn3j0M1D0w9c7Ilm8ee3krdR4E/mw3AoGBANdu
+EfS1dK3+m7sEgc2+3U32z83GpuCHeUIKGPYMLI0fIb1CPpboHU9YjOFJZH9iIIdl
+00JC963O3+pqLe0XbMOmBVt9QjZfhfB+AY+JHtbPgoQVLtq9X/WvW7h3xn6S971r
+Crkhqay3Cs4BzsgYDYraQCTw3oq4twR9Nuy4etfzAoGAXOsG5wWe3diO/sCggFJx
+Eg88vHVBgA1ZoxMXKtGgtw1bRHI1XIblRvqw6qmeDw72fvl5dEe0DbXT7C9ezemc
+ZrGRaj5lpMfoS7/2trIIJrfaQgGkGRJMZUhvmcbeJW8lUJHnlMS5HLWMaKn+YZAi
+GFXQrMv9ylD44mHUWD7tvV0CgYBNctPfvvCQsQ05ofgsiKa1Jbs1hmpuJCYy2MB6
+jIvjvEJ78PnhdNc8tGAJikIoDZYWN0RI+RxkDxCvDLcwGpDOkbwxVQnd1F+pwxM6
+kBhXL8kDRT5QA28hO4bk/aKN1LZeEcKMJg8C+ddXkozNoOAVgDs5TKMlCh057u41
+EmmPgwKBgQDOlYi7fPYOCy0yjHMxSrp2SZOS06AMWGbbCoGkjRtvuP+FmKSNB+LZ
+pOSEPJgzjsRutKjneww4LpV6dViAyTcP5JoeQpokHf7UVo7yq2QH/iwF3zJwsC/S
+OuVLkqpZzWuye/QCH5NOTfw27ye8jG8VcQW2QPbcbkLXLM7zg2yX7g==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdQCBRQHBXNJMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
+MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
+MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
+VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS5x6aoXAEXOJU6BODHiZkgjhacYOkD+tY
+AYe9Rk6rLZ1Dc/PCgYrEFpU8CXmTESixE5UZrt1O6rnIVnhcga/AIrEXfS8KZ0YL
+K2qrowyn3TiMbfYqKSSaMICkgwbEw7h6gEdlnGLJW8pNuD0zYJFcSvCdhaEUf+oZ
+0+e6jQIRockDhUoD2KdxP12l4SFTfRHpqMB7+N72sKPY4wswVIx93nUv9Vh87rTM
+PBQ1jthUiCFBmAl7jgRUaynWldqpoPqjc+8ZjeiHDZpmMnOUnswkdspX2V+33xHe
+mSVukHMwfzj1wTJD/nUv+uV9NSAKlPLvARmlYdA20d+7/WuEmOk1AgMBAAEwDQYJ
+KoZIhvcNAQEFBQADggEBACCCAJypO9DFU6GeOH+FwE0JCLTypHoIwERWxNL7xfjg
+rwVqIxwAEo+fJjL+QY7JbAb/eqKaXIBYkAF2lFc4iEmecXX/A3Aqw95AYi78o7HD
+MwRPqJha9mxLcCWwjX8XK8pT152BvYFPNhi+6jd++rDRxKDfmNvgdUQ2/YW6a5Wv
+zEmLDPUWRIuMQIEmOa2/JhlllDviMExTw51nbqYgCghycRvDACyQAuu8re7P6gcg
+bXObNlfxcU/8Ph6MFI+2S9ODtQ4BHyuKd4kRNsYn8vV42a0h3bCYSGPk3kSIgxd7
+XijwHT/o8E9ddH2BvDv+6Nhno9C6/MbezEOIs4nlhRk=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem
new file mode 100644
index 00000000000..b6b48ef23f4
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/certs/ws2_server.pem
@@ -0,0 +1,45 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA29iFnMf4pjty6knOt4wT0joPUlU2dGCFWxQ5Eg77Yx3Lou2a
+FOzNGp7zLYH8gauOK+mgY+B9cBv8PvVtUQQKB0SKTTV8ZNKVyP3O5F2gRSJ+tHtT
+FqaPfG0WPOn/f02YbOpAe6Rk+NnlJoeuBxG4uapUSq7r0mTGJQe+52y1LcMs23ID
+ENBfDoUMVt5vCnF+cYK5ndeFVLyPO3JjohDH1zv3a9ECG28rtjKHLpNYFDsPJaD7
+UPuyyk3hIvfPCZoJOUlEVfpLT/lM+9oCPnq9PwIp5NqYofkuc3eKooCo7N4r4IlP
+Ajktaao6b0ScNwNQB3leOIdEUFSIYy8N1JszVwIDAQABAoIBAFlIvjrGG/2m9yyf
+fQyeHw6p9b8CTHNHH+G1fNgQrZe7ahBpXsJQyZueIjTBLcOb4MmEwFbPvSHiu7b2
+Bcd5VHlPJLvmlPZ9b8eJDJVCUOzC7aJu03fHfU6THwzuG42f/d9942JTiY5nL+FO
+CSdl0xfUTRdnou53buFrG+TxCUPj13HP1HY6DAVzEIq1H4TZwIZo7KRRTIYpTB3P
+6yvr9xsISLlnmfQ4tp2pApl5o+bHJEhr1VO6SAT/pSyShi79KmMMqYtyTmOMz7w6
+VJkre5ybnXBDN6tfMHWqdobJ4gRWK9rqf+LIZig5XQnyzkue8k+I7aPgO4xNFh56
+dkejQcECgYEA9MDCWViqpfvof+epiKzccqnIRnz1EfHdRQjiKsKGRe39+K+pyaqJ
+FOOPFy3aOw6M4cFWwcdMYzKTItvzyLVhDqMzT5eup/NVqo5tPoy93XPf2qRYiTl4
+2j5wvm0RVkYEONd3pk2lbfbUmn7XQXj0+AG60SvsqErF/UhIBGec/xsCgYEA5fLC
+EdiiC98kr4sVaE8G854WI+aAkStqO5YXyrnsMzRsqk8KVVYE1yCC9rYyymDBYmlx
+uEW+vbWqLc8PO3v4ty3o5ff303lPMWIrvKiUldjqMjS6ncWxsQjU0bygGVgOgHO7
+c8rjiDH5M0JgWSREYUVFT5mW/5+Y1LVT8mYNlHUCgYEAhMSX6N23XGkFW3Twu2qB
+/1Vohgw86OoaDNvfzDBPpFmQ3rlz0ijHSeSTd5BxBH5FICXACUgygNErjcphOSxj
+JQyUxgVTQlo2y1mNm1O/nwS/lxx1xqK9ky4x/Kqvr+w1WBxSFI2kQr2V4OUTobma
+sXpGvDcmnrhJJLd0EaefO6cCgYEA3Xw/S9tC8nZjqqYn34nHI16Q6tF54tpTf8Np
+dT4x8Xw8cqqhRGMPVHsfSi1irKYXfwgbnienuqlBmtAHVv9pKF+TJfb7gXkmO2XY
+xOYIAHGn2uYJHjCun9vmyYKLHv4/MaDH3Jd/I88mviXgEdyp9Js5UJua4utB1Rg3
+HJMJ34UCgYEAr0PpHEBMbZXZBybNU96+jRTgkrNeJpzlnMy7et2IsRAtLjZ0mpbn
+NaX8i8eO+ubweqFdhOvbh7Hd0zr7BzrYcUG1e3njhtxJE1MgWL5plnLVUbIyDAm3
+iBpIHIBASNCN3sqeq+VqXvavRmeZh5O0vyLP46/kxZx0rzR/NCi9xxU=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdQCBRQHBXNIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
+MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
+MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
+VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb2IWcx/imO3LqSc63jBPSOg9SVTZ0YIVb
+FDkSDvtjHcui7ZoU7M0anvMtgfyBq44r6aBj4H1wG/w+9W1RBAoHRIpNNXxk0pXI
+/c7kXaBFIn60e1MWpo98bRY86f9/TZhs6kB7pGT42eUmh64HEbi5qlRKruvSZMYl
+B77nbLUtwyzbcgMQ0F8OhQxW3m8KcX5xgrmd14VUvI87cmOiEMfXO/dr0QIbbyu2
+Mocuk1gUOw8loPtQ+7LKTeEi988Jmgk5SURV+ktP+Uz72gI+er0/Aink2pih+S5z
+d4qigKjs3ivgiU8COS1pqjpvRJw3A1AHeV44h0RQVIhjLw3UmzNXAgMBAAEwDQYJ
+KoZIhvcNAQEFBQADggEBALi/RmqeXGazT/WRj9+ZqdcnbcHwK5wwr2/YkpFPJ0Hf
+ZDm+2vgjDdTT6cJS6fau0M5nliYdz89aQQo1j9RSRZnzlc/2YCFXyRLCOJYaINbj
+1MEUAvNDGL7xTpepK9hVkXASRkbyNXERXRKFI1N+vpKu6UorT6/osEV/qM+MFJ3s
+24xE8/J3J4MirVQVt6eY6Jb+tkliOPMIugr6YQlLsqJygEWATP8Qsr81XSfcZhVq
+rXzVt7QV8dO0nStMjKK5omrtEAhVnASk7w1tFHkpBF1rqXGoo9ML40RnFZ+E5zqi
+iZtzp+NzzLnEnWMNs+fJpPJ96P0kbq2bQzuSBcUynq0=
+-----END CERTIFICATE-----
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h b/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h
new file mode 100644
index 00000000000..4d1c33fc820
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/net_skeleton.h
@@ -0,0 +1,253 @@
+// Copyright (c) 2014 Cesanta Software Limited
+// All rights reserved
+//
+// This software is dual-licensed: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation. For the terms of this
+// license, see <http://www.gnu.org/licenses/>.
+//
+// You are free to use this software under the terms of the GNU General
+// Public License, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// Alternatively, you can license this software under a commercial
+// license, as set out in <http://cesanta.com/>.
+//
+// $Date: 2014-09-28 05:04:41 UTC $
+
+#ifndef NS_SKELETON_HEADER_INCLUDED
+#define NS_SKELETON_HEADER_INCLUDED
+
+#define NS_SKELETON_VERSION "2.1.0"
+
+#undef UNICODE // Use ANSI WinAPI functions
+#undef _UNICODE // Use multibyte encoding on Windows
+#define _MBCS // Use multibyte encoding on Windows
+#define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
+#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
+#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
+#define _XOPEN_SOURCE 600 // For flockfile() on Linux
+#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
+#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE // Enable fseeko() and ftello() functions
+#endif
+#define _FILE_OFFSET_BITS 64 // Enable 64-bit file offsets
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4127) // FD_SET() emits warning, disable it
+#pragma warning (disable : 4204) // missing c99 support
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+
+#ifdef _WIN32
+#ifdef _MSC_VER
+#pragma comment(lib, "ws2_32.lib") // Linking with winsock library
+#endif
+#include <windows.h>
+#include <process.h>
+#ifndef EINPROGRESS
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+#ifndef __func__
+#define STRX(x) #x
+#define STR(x) STRX(x)
+#define __func__ __FILE__ ":" STR(__LINE__)
+#endif
+#ifndef va_copy
+#define va_copy(x,y) x = y
+#endif // MINGW #defines va_copy
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define sleep(x) Sleep((x) * 1000)
+#define to64(x) _atoi64(x)
+typedef int socklen_t;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 int64_t;
+typedef SOCKET sock_t;
+typedef struct _stati64 ns_stat_t;
+#ifndef S_ISDIR
+#define S_ISDIR(x) ((x) & _S_IFDIR)
+#endif
+#else
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <arpa/inet.h> // For inet_pton() when NS_ENABLE_IPV6 is defined
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#define closesocket(x) close(x)
+#define __cdecl
+#define INVALID_SOCKET (-1)
+#define to64(x) strtoll(x, NULL, 10)
+typedef int sock_t;
+typedef struct stat ns_stat_t;
+#endif
+
+#ifdef NS_ENABLE_DEBUG
+#define DBG(x) do { printf("%-20s ", __func__); printf x; putchar('\n'); \
+ fflush(stdout); } while(0)
+#else
+#define DBG(x)
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+#endif
+
+#ifdef NS_ENABLE_SSL
+#ifdef __APPLE__
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+#include <openssl/ssl.h>
+#else
+typedef void *SSL;
+typedef void *SSL_CTX;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+union socket_address {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#ifdef NS_ENABLE_IPV6
+ struct sockaddr_in6 sin6;
+#else
+ struct sockaddr sin6;
+#endif
+};
+
+// Describes chunk of memory
+struct ns_str {
+ const char *p;
+ size_t len;
+};
+
+// IO buffers interface
+struct iobuf {
+ char *buf;
+ size_t len;
+ size_t size;
+};
+
+void iobuf_init(struct iobuf *, size_t initial_size);
+void iobuf_free(struct iobuf *);
+size_t iobuf_append(struct iobuf *, const void *data, size_t data_size);
+void iobuf_remove(struct iobuf *, size_t data_size);
+void iobuf_resize(struct iobuf *, size_t new_size);
+
+// Callback function (event handler) prototype, must be defined by user.
+// Net skeleton will call event handler, passing events defined above.
+struct ns_connection;
+typedef void (*ns_callback_t)(struct ns_connection *, int event_num, void *evp);
+
+// Events. Meaning of event parameter (evp) is given in the comment.
+#define NS_POLL 0 // Sent to each connection on each call to ns_mgr_poll()
+#define NS_ACCEPT 1 // New connection accept()-ed. union socket_address *addr
+#define NS_CONNECT 2 // connect() succeeded or failed. int *success_status
+#define NS_RECV 3 // Data has benn received. int *num_bytes
+#define NS_SEND 4 // Data has been written to a socket. int *num_bytes
+#define NS_CLOSE 5 // Connection is closed. NULL
+
+
+struct ns_mgr {
+ struct ns_connection *active_connections;
+ const char *hexdump_file; // Debug hexdump file path
+ sock_t ctl[2]; // Socketpair for mg_wakeup()
+ void *user_data; // User data
+};
+
+
+struct ns_connection {
+ struct ns_connection *next, *prev; // ns_mgr::active_connections linkage
+ struct ns_connection *listener; // Set only for accept()-ed connections
+ struct ns_mgr *mgr;
+
+ sock_t sock; // Socket
+ union socket_address sa; // Peer address
+ struct iobuf recv_iobuf; // Received data
+ struct iobuf send_iobuf; // Data scheduled for sending
+ SSL *ssl;
+ SSL_CTX *ssl_ctx;
+ void *user_data; // User-specific data
+ void *proto_data; // Application protocol-specific data
+ time_t last_io_time; // Timestamp of the last socket IO
+ ns_callback_t callback; // Event handler function
+
+ unsigned int flags;
+#define NSF_FINISHED_SENDING_DATA (1 << 0)
+#define NSF_BUFFER_BUT_DONT_SEND (1 << 1)
+#define NSF_SSL_HANDSHAKE_DONE (1 << 2)
+#define NSF_CONNECTING (1 << 3)
+#define NSF_CLOSE_IMMEDIATELY (1 << 4)
+#define NSF_WANT_READ (1 << 5)
+#define NSF_WANT_WRITE (1 << 6)
+#define NSF_LISTENING (1 << 7)
+#define NSF_UDP (1 << 8)
+
+#define NSF_USER_1 (1 << 20)
+#define NSF_USER_2 (1 << 21)
+#define NSF_USER_3 (1 << 22)
+#define NSF_USER_4 (1 << 23)
+#define NSF_USER_5 (1 << 24)
+#define NSF_USER_6 (1 << 25)
+};
+
+void ns_mgr_init(struct ns_mgr *, void *user_data);
+void ns_mgr_free(struct ns_mgr *);
+time_t ns_mgr_poll(struct ns_mgr *, int milli);
+void ns_broadcast(struct ns_mgr *, ns_callback_t, void *, size_t);
+
+struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
+struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t,
+ ns_callback_t, void *);
+struct ns_connection *ns_bind(struct ns_mgr *, const char *,
+ ns_callback_t, void *);
+struct ns_connection *ns_connect(struct ns_mgr *, const char *,
+ ns_callback_t, void *);
+
+int ns_send(struct ns_connection *, const void *buf, int len);
+int ns_printf(struct ns_connection *, const char *fmt, ...);
+int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
+
+// Utility functions
+void *ns_start_thread(void *(*f)(void *), void *p);
+int ns_socketpair(sock_t [2]);
+int ns_socketpair2(sock_t [2], int sock_type); // SOCK_STREAM or SOCK_DGRAM
+void ns_set_close_on_exec(sock_t);
+void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
+int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
+int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
+int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // NS_SKELETON_HEADER_INCLUDED
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c
new file mode 100644
index 00000000000..969aa979345
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.c
@@ -0,0 +1,123 @@
+// Copyright (c) 2014 Cesanta Software Limited
+// All rights reserved
+//
+// This software is dual-licensed: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation. For the terms of this
+// license, see <http://www.gnu.org/licenses/>.
+//
+// You are free to use this software under the terms of the GNU General
+// Public License, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// Alternatively, you can license this software under a commercial
+// license, as set out in <http://cesanta.com/products.html>.
+//
+// $Date$
+
+#include "net_skeleton.h"
+#include "ssl_wrapper.h"
+
+static void ev_handler(struct ns_connection *nc, int ev, void *p) {
+ const char *target_addr = (const char *) nc->mgr->user_data;
+ struct ns_connection *pc = (struct ns_connection *) nc->user_data;
+ struct iobuf *io = &nc->recv_iobuf;
+
+ (void) p;
+ switch (ev) {
+ case NS_ACCEPT:
+ // Create a connection to the target, and interlink both connections
+ nc->user_data = ns_connect(nc->mgr, target_addr, ev_handler, nc);
+ if (nc->user_data == NULL) {
+ nc->flags |= NSF_CLOSE_IMMEDIATELY;
+ }
+ break;
+
+ case NS_CLOSE:
+ // If either connection closes, unlink them and shedule closing
+ if (pc != NULL) {
+ pc->flags |= NSF_FINISHED_SENDING_DATA;
+ pc->user_data = NULL;
+ }
+ nc->user_data = NULL;
+ break;
+
+ case NS_RECV:
+ // Forward arrived data to the other connection, and discard from buffer
+ if (pc != NULL) {
+ ns_send(pc, io->buf, io->len);
+ iobuf_remove(io, io->len);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void *ssl_wrapper_init(const char *local_addr, const char *target_addr,
+ const char **err_msg) {
+ struct ns_mgr *mgr = (struct ns_mgr *) calloc(1, sizeof(mgr[0]));
+ *err_msg = NULL;
+
+ if (mgr == NULL) {
+ *err_msg = "malloc failed";
+ } else {
+ ns_mgr_init(mgr, (void *) target_addr);
+ if (ns_bind(mgr, local_addr, ev_handler, NULL) == NULL) {
+ *err_msg = "ns_bind() failed: bad listening_port";
+ ns_mgr_free(mgr);
+ free(mgr);
+ mgr = NULL;
+ }
+ }
+
+ return mgr;
+}
+
+void ssl_wrapper_serve(void *param, volatile int *quit) {
+ struct ns_mgr *mgr = (struct ns_mgr *) param;
+
+ while (*quit == 0) {
+ ns_mgr_poll(mgr, 1000);
+ }
+ ns_mgr_free(mgr);
+ free(mgr);
+}
+
+#ifndef SSL_WRAPPER_USE_AS_LIBRARY
+static int s_received_signal = 0;
+
+static void signal_handler(int sig_num) {
+ signal(sig_num, signal_handler);
+ s_received_signal = sig_num;
+}
+
+static void show_usage_and_exit(const char *prog) {
+ fprintf(stderr, "Usage: %s <listening_address> <target_address>\n", prog);
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[]) {
+ void *wrapper;
+ const char *err_msg;
+
+ if (argc != 3) {
+ show_usage_and_exit(argv[0]);
+ }
+
+ // Setup signal handlers
+ signal(SIGTERM, signal_handler);
+ signal(SIGINT, signal_handler);
+ signal(SIGPIPE, SIG_IGN);
+
+ if ((wrapper = ssl_wrapper_init(argv[1], argv[2], &err_msg)) == NULL) {
+ fprintf(stderr, "Error: %s\n", err_msg);
+ exit(EXIT_FAILURE);
+ }
+ ssl_wrapper_serve(wrapper, &s_received_signal);
+
+ return EXIT_SUCCESS;
+}
+#endif // SSL_WRAPPER_USE_AS_LIBRARY
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h
new file mode 100644
index 00000000000..ccdf780556c
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/ssl_wrapper.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 Cesanta Software Limited
+// All rights reserved
+//
+// This software is dual-licensed: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation. For the terms of this
+// license, see <http://www.gnu.org/licenses/>.
+//
+// You are free to use this software under the terms of the GNU General
+// Public License, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// Alternatively, you can license this software under a commercial
+// license, as set out in <http://cesanta.com/products.html>.
+//
+// $Date$
+
+#ifndef SSL_WRAPPER_HEADER_INCLUDED
+#define SSL_WRAPPER_HEADER_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+void *ssl_wrapper_init(const char *listen_addr, const char *target_addr,
+ const char **err_msg);
+void ssl_wrapper_serve(void *, volatile int *stop_marker);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // SSL_WRAPPER_HEADER_INCLUDED
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c
new file mode 100644
index 00000000000..d2fceee650e
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.c
@@ -0,0 +1,182 @@
+// Copyright (c) 2014 Cesanta Software
+// All rights reserved
+//
+// This example demostrates proxying of WebSocket traffic, regardless of the
+// protocol (ws:// or wss://).
+// To use this example:
+// 1. configure your browser to use a proxy on port 2014
+// 2. import certs/ws1_ca.pem and certs/ws2_ca.pem into the trusted
+// certificates list on your browser
+// 3. make && ./ws_ssl
+// 4. Point your browser to http://ws_ssl.com
+// A page with 4 sections should appear, showing websocket echoes
+
+#include "net_skeleton.h"
+#include "mongoose.h"
+#include "ssl_wrapper.h"
+
+#define S1_PEM "certs/ws1_server.pem"
+#define C1_PEM "certs/ws1_client.pem"
+#define CA1_PEM "certs/ws1_ca.pem"
+#define S2_PEM "certs/ws2_server.pem"
+#define C2_PEM "certs/ws2_client.pem"
+#define CA2_PEM "certs/ws2_ca.pem"
+
+struct config {
+ const char *uri;
+ const char *wrapper_server_addr;
+ const char *wrapper_client_addr;
+ const char *target_addr;
+};
+
+static struct config s_wrappers[] = {
+ {
+ "ws1:80",
+ "tcp://127.0.0.1:7001",
+ "tcp://127.0.0.1:7001",
+ "tcp://127.0.0.1:9001"
+ },
+ {
+ "ws1:443",
+ "ssl://127.0.0.1:7002:" S1_PEM,
+ "tcp://127.0.0.1:7002",
+ "tcp://127.0.0.1:9001"
+ },
+ {
+ "ws2:80",
+ "tcp://127.0.0.1:7003",
+ "tcp://127.0.0.1:7003",
+ "ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
+ },
+ {
+ "ws2:443",
+ "ssl://127.0.0.1:7004:" S2_PEM,
+ "tcp://127.0.0.1:7004",
+ "ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
+ },
+};
+
+static int s_received_signal = 0;
+
+static void signal_handler(int sig_num) {
+ signal(sig_num, signal_handler);
+ s_received_signal = sig_num;
+}
+
+static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
+ int i;
+
+ switch (ev) {
+ case MG_AUTH:
+ return MG_TRUE;
+
+ case MG_REQUEST:
+ printf("==> [%s] [%s]\n", conn->request_method, conn->uri);
+
+ if (strcmp(conn->request_method, "CONNECT") == 0) {
+ // Iterate over configured wrappers, see if we can use one of them
+ for (i = 0; i < (int) ARRAY_SIZE(s_wrappers); i++) {
+ if (strcmp(conn->uri, s_wrappers[i].uri) == 0) {
+ mg_forward(conn, s_wrappers[i].wrapper_client_addr);
+ return MG_MORE;
+ }
+ }
+
+ // No suitable wrappers found. Disallow that CONNECT request.
+ mg_send_status(conn, 405);
+ return MG_TRUE;
+ }
+
+ // Not a CONNECT request, serve HTML file.
+ mg_send_file(conn, "ws_ssl.html", NULL);
+ return MG_MORE;
+
+ default:
+ return MG_FALSE;
+ }
+}
+
+static int ws_handler(struct mg_connection *conn, enum mg_event ev) {
+ switch (ev) {
+ case MG_AUTH:
+ return MG_TRUE;
+ case MG_REQUEST:
+ if (conn->is_websocket) {
+ // Simple websocket echo server
+ mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT,
+ conn->content, conn->content_len);
+ } else {
+ mg_printf_data(conn, "%s", "websocket connection expected");
+ }
+ return MG_TRUE;
+ default:
+ return MG_FALSE;
+ }
+}
+
+static void *serve_thread_func(void *param) {
+ struct mg_server *server = (struct mg_server *) param;
+ printf("Listening on port %s\n", mg_get_option(server, "listening_port"));
+ while (s_received_signal == 0) {
+ mg_poll_server(server, 1000);
+ }
+ mg_destroy_server(&server);
+ return NULL;
+}
+
+static void *wrapper_thread_func(void *param) {
+ struct config *c = (struct config *) param;
+ const char *err_msg;
+ void *wrapper;
+
+ wrapper = ssl_wrapper_init(c->wrapper_server_addr, c->target_addr, &err_msg);
+ if (wrapper == NULL) {
+ fprintf(stderr, "Error: %s\n", err_msg);
+ exit(EXIT_FAILURE);
+ }
+ //((struct ns_mgr *) wrapper)->hexdump_file = "/dev/stderr";
+ ssl_wrapper_serve(wrapper, &s_received_signal);
+
+ return NULL;
+}
+
+int main(void) {
+ struct mg_server *proxy_server = mg_create_server(NULL, ev_handler);
+ struct mg_server *ws1_server = mg_create_server(NULL, ws_handler);
+ struct mg_server *ws2_server = mg_create_server(NULL, ws_handler);
+ size_t i;
+
+ ((struct ns_mgr *) proxy_server)->hexdump_file = "/dev/stderr";
+
+ // Configure proxy server to listen on port 2014
+ mg_set_option(proxy_server, "listening_port", "2014");
+ //mg_set_option(proxy_server, "enable_proxy", "yes");
+
+ // Configure two websocket echo servers:
+ // ws1 is WS, listening on 9001
+ // ws2 is WSS, listening on 9002
+ // Note that HTML page thinks that ws1 is WSS, and ws2 is WS,
+ // where in reality it is vice versa and proxy server makes the decision.
+ mg_set_option(ws1_server, "listening_port", "tcp://127.0.0.1:9001");
+ mg_set_option(ws2_server, "listening_port",
+ "ssl://127.0.0.1:9002:" S2_PEM ":" CA2_PEM);
+
+ // Setup signal handlers
+ signal(SIGTERM, signal_handler);
+ signal(SIGINT, signal_handler);
+
+ // Start SSL wrappers, each in it's own thread
+ for (i = 0; i < ARRAY_SIZE(s_wrappers); i++) {
+ ns_start_thread(wrapper_thread_func, &s_wrappers[i]);
+ }
+
+ // Start websocket servers in separate threads
+ mg_start_thread(serve_thread_func, ws1_server);
+ mg_start_thread(serve_thread_func, ws2_server);
+
+ // Finally, start proxy server in this thread: this call blocks
+ serve_thread_func(proxy_server);
+
+ printf("Existing on signal %d\n", s_received_signal);
+ return EXIT_SUCCESS;
+}
diff --git a/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html
new file mode 100644
index 00000000000..23ab2506145
--- /dev/null
+++ b/3rdparty/mongoose/examples/websocket_ssl_proxy/ws_ssl.html
@@ -0,0 +1,50 @@
+<html>
+<head>
+ <title>Websocket Proxy SSL Test</title>
+ <meta charset="utf-8">
+ <script>
+ window.onload = function() {
+ var protocols = ['ws://', 'wss://'];
+ var websocketServers = ['ws1', 'ws2'];
+ //protocols = ['wss://'];
+ //websocketServers = ['ws1']
+
+ var createWebsocketConnection = function(proto, server) {
+ var conn = new WebSocket(proto + server);
+
+ var div = document.createElement('div');
+ var h2 = document.createElement('h2');
+ h2.innerHTML = 'Connection to ' + proto + server;
+ document.body.appendChild(h2);
+ document.body.appendChild(div);
+
+ conn.onmessage = function(ev) {
+ var el = document.createElement('div');
+ el.innerHTML = 'websocket message: ' + ev.data;
+ div.appendChild(el);
+ // Keep only last 5 messages in the list
+ while (div.childNodes.length > 5) div.removeChild(div.firstChild);
+ };
+
+ // Send some string to the websocket connection periodically.
+ // websocket server much echo it back.
+ window.setInterval(function() { conn.send(Math.random()); }, 1000);
+ };
+
+ for (var i = 0; i < protocols.length; i++) {
+ for (var j = 0; j < websocketServers.length; j++) {
+ createWebsocketConnection(protocols[i], websocketServers[j]);
+ }
+ }
+ };
+ </script>
+ <style>
+ body > div {
+ border: 1px solid #ccc; background: #f0f0f0; padding: 0 1em;
+ margin: 0 2em; min-height: 4em; max-width: 40em;
+ }
+ </style>
+</head>
+<body>
+</body>
+</html> \ No newline at end of file