diff --git a/mount-origin/404.html b/mount-origin/404.html deleted file mode 100644 index 3e5a14b..0000000 --- a/mount-origin/404.html +++ /dev/null @@ -1,9 +0,0 @@ - - - -
-

404

- Sorry, that file doesn't exist. - - - diff --git a/mount-origin/candide.zip b/mount-origin/candide.zip deleted file mode 100644 index 82a6619..0000000 Binary files a/mount-origin/candide.zip and /dev/null differ diff --git a/mount-origin/favicon.ico b/mount-origin/favicon.ico deleted file mode 100644 index c0cc2e3..0000000 Binary files a/mount-origin/favicon.ico and /dev/null differ diff --git a/mount-origin/http2.png b/mount-origin/http2.png deleted file mode 100644 index b4129e7..0000000 Binary files a/mount-origin/http2.png and /dev/null differ diff --git a/mount-origin/leaf.jpg b/mount-origin/leaf.jpg deleted file mode 100644 index 1a3f46b..0000000 Binary files a/mount-origin/leaf.jpg and /dev/null differ diff --git a/mount-origin/libwebsockets.org-logo.svg b/mount-origin/libwebsockets.org-logo.svg deleted file mode 100644 index 7baea64..0000000 --- a/mount-origin/libwebsockets.org-logo.svg +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mount-origin/lws-common.js b/mount-origin/lws-common.js deleted file mode 100644 index 5d56ca2..0000000 --- a/mount-origin/lws-common.js +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This section around grayOut came from here: - * http://www.codingforums.com/archive/index.php/t-151720.html - * Assumed public domain - * - * Init like this in your main html script, this also reapplies the gray - * - * lws_gray_out(true,{'zindex':'499'}); - * - * To remove the gray - * - * lws_gray_out(false); - * - */ - -function gsize(ptype) -{ - var h = document.compatMode === "CSS1Compat" && - !window.opera ? - document.documentElement.clientHeight : - document.body.clientHeight; - var w = document.compatMode === "CSS1Compat" && - !window.opera ? - document.documentElement.clientWidth : - document.body.clientWidth; - var pageWidth, pageHeight, t; - - if (document.body && - (document.body.scrollWidth || document.body.scrollHeight)) { - t = document.body.scrollWidth; - pageWidth = (w > t) ? ("" + w + "px") : ("" + (t) + "px"); - t = document.body.scrollHeight; - pageHeight = (h > t) ? ("" + h + "px") : ("" + (t) + "px"); - } else if (document.body.offsetWidth) { - t = document.body.offsetWidth; - pageWidth = (w > t) ? ("" + w + "px") : ("" + (t) + "px"); - t = document.body.offsetHeight; - pageHeight =(h > t) ? ("" + h + "px") : ("" + (t) + "px"); - } else { - pageWidth = "100%"; - pageHeight = "100%"; - } - return (ptype === 1) ? pageWidth : pageHeight; -} - -function addEvent( obj, type, fn ) { - if ( obj.attachEvent ) { - obj["e" + type + fn] = fn; - obj[type+fn] = function() { obj["e" + type + fn]( window.event );}; - obj.attachEvent("on" + type, obj[type + fn]); - } else - obj.addEventListener(type, fn, false); -} - -function removeEvent( obj, type, fn ) { - if ( obj.detachEvent ) { - obj.detachEvent("on" + type, obj[type + fn]); - obj[type + fn] = null; - } else - obj.removeEventListener(type, fn, false); -} - -function lws_gray_out(vis, _options) { - - var options = _options || {}; - var zindex = options.zindex || 50; - var opacity = options.opacity || 70; - var opaque = (opacity / 100); - var bgcolor = options.bgcolor || "#000000"; - var dark = document.getElementById("darkenScreenObject"); - - if (!dark) { - var tbody = document.getElementsByTagName("body")[0]; - var tnode = document.createElement("div"); - tnode.style.position = "absolute"; - tnode.style.top = "0px"; - tnode.style.left = "0px"; - tnode.style.overflow = "hidden"; - tnode.style.display ="none"; - tnode.id = "darkenScreenObject"; - tbody.appendChild(tnode); - dark = document.getElementById("darkenScreenObject"); - } - if (vis) { - dark.style.opacity = opaque; - dark.style.MozOpacity = opaque; - // dark.style.filter ='alpha(opacity='+opacity+')'; - dark.style.zIndex = zindex; - dark.style.backgroundColor = bgcolor; - dark.style.width = gsize(1); - dark.style.height = gsize(0); - dark.style.display = "block"; - addEvent(window, "resize", - function() { - dark.style.height = gsize(0); - dark.style.width = gsize(1); - } - ); - } else { - dark.style.display = "none"; - removeEvent(window, "resize", - function() { - dark.style.height = gsize(0); - dark.style.width = gsize(1); - } - ); - } -} - -/* - * end of grayOut related stuff - */ - -function new_ws(urlpath, protocol) -{ - if (typeof MozWebSocket != "undefined") - return new MozWebSocket(urlpath, protocol); - - return new WebSocket(urlpath, protocol); -} - -function lws_san(s) -{ - if (s.search("<") !== -1) - return "invalid string"; - - return s; -} diff --git a/mount-origin/strict-csp.svg b/mount-origin/strict-csp.svg deleted file mode 100644 index cd128f1..0000000 --- a/mount-origin/strict-csp.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mount-origin/test.css b/mount-origin/test.css deleted file mode 100644 index 6cd32e7..0000000 --- a/mount-origin/test.css +++ /dev/null @@ -1,190 +0,0 @@ - -span.title { - font-size:18pt; - font-family: Arial; - font-weight:normal; - text-align:center; - color:#000000; -} -span.mount { - font-size:10pt; - font-family: Arial; - font-weight:normal; - text-align:center; - color:#000000; -} -span.mountname { - font-size:14pt; - font-family: Arial; - font-weight:bold; - text-align:center; - color:#404010; -} -span.n { - font-size:12pt; - font-family: Arial; - font-weight:normal; - text-align:center; - color:#808020; -} -span.v { - font-size:12pt; - font-family: Arial; - font-weight:bold; - text-align:center; - color:#202020; -} -span.m1 { - font-size:12pt; - font-family: Arial; - font-weight:bold; - text-align:center; - color:#202020; -} -span.m2 { - font-size:12pt; - font-family: Arial; - font-weight:normal; - text-align:center; - color:#202020; -} - -.browser { font-size:12pt; font-family: Arial; font-weight:normal; text-align:center; color:#ffff00; vertical-align:middle; text-align:center; background:#d0b070; padding:12px; -webkit-border-radius:10px; border-radius:10px;} -.group2 { vertical-align:middle; - text-align:center; - background:#f0f0e0; - padding:12px; - -webkit-border-radius:10px; - border-radius:10px; } -.explain { vertical-align:middle; - text-align:center; - background:#f0f0c0; padding:12px; - -webkit-border-radius:10px; - border-radius:10px; - color:#404000; - padding:3px; -} -td.wsstatus { vertical-align:middle; width:200px; height:50px; - text-align:center; - background:#f0f0c0; padding:6px; - -webkit-border-radius:8px; - border-radius:8px; - color:#404000; } -.tdform { vertical-align:middle; width:200px; height:50px; - text-align:center; - background:#f0f0d0; padding:6px; - -webkit-border-radius:8px; - margin:10px; - border-radius:8px; - border: 1px solid black; - border-collapse: collapse;font-size:18pt; font-family: Arial; font-weight:normal; text-align:center; color:#000000; - color:#404000; } - -td.l { vertical-align:middle; - text-align:center; - background:#d0d0b0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - -td.bigger { font-size:120%; } - -div.bgw { background:white } -div.conninfo { - border: solid 2px #e0d040; - padding: 4px; - width: 500px; - height:350px; - overflow: auto; -} -span.f12 { font-size:12pt } - -.content { vertical-align:top; text-align:center; background:#fffff0; padding:12px; -webkit-border-radius:10px; border-radius:10px; } -.canvas { vertical-align:top; text-align:center; background:#efefd0; padding:12px; -webkit-border-radius:10px; border-radius:10px; } -.tabs { - position: relative; - min-height: 750px; /* This part sucks */ - clear: both; - margin: 25px 0; -} -.tab { - float: left; -} -.tab label { - background: #eee; - padding: 10px; - border: 1px solid #ccc; - margin-left: -1px; - position: relative; - left: 1px; -} -.tab [type=radio] { - display: none; -} -.content { - position: absolute; - top: 28px; - left: 0; - background: white; - right: 0; - bottom: 0; - padding: 20px; - border: 1px solid #ccc; -} -[type=radio]:checked ~ label { - background: white; - border-bottom: 1px solid white; - z-index: 2; -} -[type=radio]:checked ~ label ~ .content { - z-index: 1; -} - - td.wsstatus { vertical-align:middle; width:200px; height:50px; - text-align:center; - background:#f0f0c0; padding:6px; - -webkit-border-radius:8px; - border-radius:8px; - color:#404000; } - td.l { vertical-align:middle; - text-align:center; - background:#d0d0b0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.dl { vertical-align:middle; - text-align:center; - background:#c0c0c0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.c { vertical-align:middle; - text-align:center; - background:#c0c0a0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.c0 { vertical-align:middle; - text-align:center; - background:#b0b090; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.dc0 { vertical-align:middle; - text-align:center; - background:#a0a0a0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.c1 { vertical-align:middle; - text-align:center; - background:#c0c0c0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } - td.t { vertical-align:middle; - text-align:center; - background:#e0e0c0; - padding:3px; - -webkit-border-radius:3px; - border-radius:3px; } \ No newline at end of file diff --git a/mount-origin/test.html b/mount-origin/test.html deleted file mode 100644 index 047bcc8..0000000 --- a/mount-origin/test.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - Minimal Websocket test app - - - -
-
- - - -
- - - - - - - - - - -
- - - -
-
...
-
-
-Click Here to -have the test server send a big picture by http. -
-
- -
- - - -
-
- - - - - - - - - - - - -
- Websocket connection not initialized - dumb increment-protocol
-The incrementing number is coming from the server at 20Hz and is individual for -each connection to the server... try opening a second browser window. -

-The button sends a message over the websocket link to ask the server -to zero just this connection's number. -
- - -
-
-
-
- -
- - - -
-
- - - - - - - - - - - - - -
- Websocket connection not initialized - - lws-mirror-protocol -
-
-Use the mouse to draw on the canvas below -- all other browser windows open -on this page see your drawing in realtime and you can see any of theirs as -well. -

-The lws-mirror protocol doesn't interpret what is being sent to it, it just -re-sends it to every other websocket it has a connection with using that -protocol, including the guy who sent the packet. -

-libwebsockets-test-client joins in by spamming circles on to this -shared canvas when run. -
-
Drawing color: - -
-
-
-
-
-
- -
- - - -
-
- - - - - - - - - - - - - - -
- -
- Websocket connection not initialized - Open and close testing -
-To help with open and close testing, you can open and close a connection by -hand using the buttons.
- "Close" closes the connection from the browser with code 3000 - and reason 'Bye!".
- "Request Server Close" sends a message asking the server to -initiate the close, which it does with code 1001 and reason "Seeya". -
- - -
- -
-
-
- -
- - - -
-
- - - - - - - - - - - - -
-
Websocket connection not initialized
-
- Server Info - - -
-This information is sent by the server over a ws[s] link and updated live -whenever the information changes server-side. -
-
-
-
- -
- - - -
-
- - - - - - - - - - - - - - -
-POST Form testing -
-This tests POST handling in lws. -
- FORM 1: send with urlencoded POST body args
-
- Some text: -
- -
-
- FORM 2: send with multipart/form-data
- (can handle file upload, test limited to 100KB)
-
- Some text: - -
-   -
- -
-
-
-
-
- -
-
- -Looking for support? -https://libwebsockets.org, - - https://github.com/warmcat/libwebsockets
-Join the mailing list: - - https://libwebsockets.org/mailman/listinfo/libwebsockets - -
- - - diff --git a/mount-origin/test.js b/mount-origin/test.js deleted file mode 100644 index 74bba69..0000000 --- a/mount-origin/test.js +++ /dev/null @@ -1,543 +0,0 @@ -(function () { -function check_file() -{ - var f = document.getElementById("file").files[0]; - var max_len = 100000; - var dis = 0; - - if (f) { - if (f.size >= max_len) { - dis = 1; - document.getElementById("file_info").innerHTML = - "File larger than " + - max_len+""; - } else - document.getElementById("file_info").innerHTML = - "File length "+f.size; - } else - dis = 1; - - document.getElementById("upload").disabled = dis; -} - -/* - * We display untrusted stuff in html context... reject anything - * that has HTML stuff in it - */ - -function san(s) -{ - if (s.search("<") !== -1) - return "invalid string"; - - return s; -} - -/* BrowserDetect came from http://www.quirksmode.org/js/detect.html */ - -var BrowserDetect = { - init: function () { - this.browser = this.searchString(this.dataBrowser) || - "An unknown browser"; - this.version = this.searchVersion(navigator.userAgent) - || this.searchVersion(navigator.appVersion) - || "an unknown version"; - this.OS = this.searchString(this.dataOS) || "an unknown OS"; - }, - searchString: function (data) { - for (var i=0;iwebsocket connection opened
" + - san(socket_di.extensions); - }; - - socket_di.onmessage =function got_packet(msg) { - document.getElementById("number").textContent = msg.data + "\n"; - }; - - socket_di.onclose = function(){ - document.getElementById("wsdi_statustd").style.backgroundColor = - "#ff4040"; - document.getElementById("wsdi_status").textContent = - " websocket connection CLOSED "; - }; - } catch(exception) { - alert("

Error" + exception); - } -} - - var socket_status, jso, s; - -function ws_open_status() -{ - - socket_status = new_ws(get_appropriate_ws_url(""), "lws-status"); - - try { - socket_status.onopen = function() { - document.getElementById("s_statustd").style.backgroundColor = - "#40ff40"; - document.getElementById("s_status").innerHTML = - " websocket connection opened
" + - san(socket_status.extensions); - }; - - socket_status.onmessage =function got_packet(msg) { - var s; - - console.log(msg.data); - - jso = JSON.parse(msg.data); - - if (jso.wss_over_h2 === "1") - document.getElementById("wstransport").innerHTML = - ""; - - document.getElementById("servinfo").innerHTML = - "" + - "" + - "
Build info"+ - san(jso.version) + "
Server info" + - san(jso.hostname) + "
"; - s=""; - var n; - for (n = 0; n < jso.conns.length; n++) { - var d = new Date(parseInt(jso.conns[n].time, 10) * 1000); - - s = s + ""; - } - s = s + "
client " + (n + 1) + - "" + san(jso.conns[n].peer) + - "
" + san(d.toString()) + - "
" + san(jso.conns[n].ua) + - "
"; - - document.getElementById("conninfo").innerHTML = s; - }; - - socket_status.onclose = function(){ - document.getElementById("s_statustd").style.backgroundColor = - "#ff4040"; - document.getElementById("s_status").textContent = - " websocket connection CLOSED "; - }; - } catch(exception) { - alert("

Error" + exception); - } -} - -function reset() { - socket_di.send("reset\n"); -} - - -function junk() { - for(var word = ""; word.length < 9000; word += "a"){} - socket_di.send(word); -} - -function on_pmd() { - socket_status.send("{ \"RequestType\":\"DDoS\", \"blob\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAJbElEQVR4Xu2af4xUVxXHv+e9O0OhIEibgrRlF8rOG6CWKiumrUlTo6byj6mmNFta2DdQsRJJrP5j+0cnjSVp1BoSU1yzO28LEeL6h7GJNhpJNa2CBQ1gd9k3QPlRBU2LLV0W2p173zFvZvbtzOybmbd7J9DEd/+befece97nfe+95/4gxEWLAGlZx8aIAWqKIAYYA9QkoGkeKzAGqElA0zxWYAxQk4CmeazAGKAmAU3zWIExQE0CmuaxAmOAmgQ0zWMFxgA1CWiaxwqMAWoS0DRvrQJ3ujeb17Hrx6SuzLwV32x7VzO+1pj3HJprJue8BcBQCSONRzr+2RrHaO2OtHDc1wDcUwqOj0s7nWpVoDp+hOMeA5Au+zggbesuHX+Vti1VoOh3j4BxRxEf8xmVSbe3KlAdP2bOPUmEpaXviiGZsVbq+IsBxgCnpp9YgVPjNan2RwagmXMfUpnUAEAc9k6Rx8AHB0zzy3euU5nUXk02RXMzl+9Ssw8PYN06FeYvOkAmM5dfpzLWL6LGFXkSMR13jIAEmKXMpBM6AIXjeih+BVLqTEcSWfJ/T71ks4bZ9vAYgU1/epC2ZegAFLnhAogEM0tV5x1r/UcGKBw3UJ1sTyVwH8laZ5EU2DO4WCTFmXFbOTbnemxZdHnq9AAMvDVTjF4ObKVS7di8IvA97jOSArNsiLZ8oGBpW5HYRKrkB1IFcGwkiS2dhWkB7B1qE6Z5uiUAew7NEsk5o4EveEtgLw98TwngwIApRlcFoogBVnzdSArUAWg6+T4QS3U69Xi98eiqK7A4vnX1+YsldWbPJmSzk8fJa6FAP67FXTv9sVLZqU1k9rvHibGsmKQzBlTGeih0gqgcA69CFxaO+zKA+4uxEF6W3dbaSXFdA4Bmzt1DhK5SLHycTMd9n4A5pT9oSNqp0GXO1VagcFx/cphZhnZF2tasjwJAkRs+CqJPFvEBIzHA8a8ScQyMAdbbTGgJwAY7FS3LA3edXCyUbJoHitzwKIhK3Zb5ssykr5/Uha9BHigc9whQ3nHyu7DIDe8A0TY/OI/xtJexngnP5ocLRCRAkLLbas1KhOGps6lE2MxvOO6TBvBsMS7Pe8rbtHz7pLhavRLpdwtgCDCkzIS/o9Gff8pg/n55EtlRSqT7h+8B0xhs62AYvHJlf524QZ3duzs0pfCT7aj7gQNsmqPHH1V2qr9+ewBePHYXIICNHfsb1TNzw7Y6e343svdNWh35dpHyQL9iKUV5VGVSu+qt94tx7DrZCa8wA93pP0deiTR80fLDyACjOGthncgAp9FmqwG+CsbnynHkpW1Z04ip5Sai3x0CY3kpU+P9sjt9d6saaSlA9JybJWaMXARDyRFjLrZ1fNiqQLX8DAwmxai4CCAhzblzsWFhsH7W8lvM8eOiRSAGqIUvVqAmvhhgDFCbgKaDqY+B2ayBBV2fQJJnwzQlSL6HjcsvhMaRHUwG/2dXjjWMtXdwPjBjPryCARKXIcQ7sJd8EOn9fFuTbkCBCDOMUZw69596SXWVv4HB2bicXAClBARdwqm95+stEurFER1gz6GESM45DGBFmLNJW+C5E7cKUmfH68pkoh3rl046r8CL7s3CQ+hdFQY2KNvaXS94o8/\" }"); - socket_status.send("{ \"RequestType\":\"SendImage\", \"RequestID\":\"283463389\", \"toType\":\"toUser\", \"toID\":\"1036\", \"fileType\":\"image/jpeg\", \"blob\":\"data:image/jpeg;base64,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oooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACioZry0t/8AX3Mcf+8wFUZvEekxcfaN5/2VJosBqUVz03jC3GRBau3+8QKozeLb9/8AVRRxj86fKwOvorg5tc1Sb7124HoOKjtdUvba4WcXDtgjILZBFPlA9AoooqQCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACori5gtYzLcSqijualrkPFsztfpAWO1EBA9zTSuBqzeK9NjyIxJIfYYFUpvGMh/497NR/vtn+Vc3RV8qA1pvE+rS/dlWMf7Kj+tUZtRv7j/XXcrD0LnFV6KdkAUUUUAFFFFABQOtFA60AelDpS0g6UtZAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcb4r/5Cv/bJf612Vcb4r/5Cv/bJf61UdwMaiiirAKKKVVZztVSSewFACUVch0fU5/8AV2UuD3K4H61eh8KanJ/rDFF/vNn+VF0Bi0V08Pg5BzPeE+yrV2HwxpUX3o3kP+01LmQHF0DrXb3ui6b9ilCWqIVQkEdQRXEDrQncD0odKWkHSlrMAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjfFf8AyFf+2S/1rsq43xX/AMhX/tkv9aqO4FfSNGl1UuVkEaJwWIzzW7D4RsU5lmlkPpnApvg//jzn/wCuv9BW/Q27gZ8Og6TD92zRv9/5v51djhihG2KJUHooxT6KkAooooAKKKKAIbz/AI9Jv+ubfyrzoda9FvP+PSb/AK5t/KvOh1q4gelDpS0g6UtQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVxviv8A5Cv/AGyX+tdlXG+K/wDkK/8AbJf61UdwNPwf/wAec3/XX+grfrA8H/8AHnN/11/oK36T3AKKKKQBRRRQAUUUUAQ3n/HpN/1zb+VedDrXot5/x6Tf9c2/lXnQ61cQPSh0paQdKWoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK43xX/yFf+2S/wBa7KuN8V/8hX/tkv8AWqjuBp+D/wDjzm/66/0Fb9YHg/8A485v+uv9BW/Se4BRRRSAKKKKACiiigCG8/49Jv8Arm38q86HWvRbz/j0m/65t/KvOh1q4gelDpS0g6UtQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVxviv/AJCv/bJf612Vcb4r/wCQr/2yX+tVHcDT8H/8ec3/AF1/oK36wPB//HnN/wBdf6Ct+k9wCiiikAUUVDc3dtZp5lzMsY7ZPX6UATUViy+K9MQ4QSye4XH86j/4S+w/59p/yH+NOzA2Lw4tJs/882/lXnQ610GqeKBdW7W9pCyBxhmbGce1c+OtXFWA9KHSlpB0pazAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiioLy9t7GEz3MgVR09SfQUAT0Vy9z4vkJItLYAdi55/Kqh8Vaqe8Q+iVXKwOzri/FDq+qttOdqKp+vNNfxNqrqV81Fz3C81mO7yOXdizMcknvTirAdV4P/AOPOb/rr/QVv1geD/wDjzm/66/0Fb9S9wCiiikBXv7tLG1kuX/gHA9TXBXd3PeztPO5Zj09h6Cuq8WFhpqgdDIM/rXH1cUAUUUVQBQOtFS2sTT3MUKjJdwv5mgD0UdKWkpayAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuH8QX73l+67j5cR2qP5mu4rzzUI2ivZ43HIc/zqo7gV6KKKsAooooA6zweP8AQpj/ANNf6Ct+snwzbNb6WjMMGUl/w7fpWtWb3AKKKKQFXU7IX9lJbHgsMqfQ1wU8EttK0MyFWU4INej1UvtLstQXFzECezDgiqTsB5/RXUyeDoScxXjKPQrmmr4OT+K+P4J/9eq5kBzFdH4Y0h/MGo3CFQv+rB7n1rSs/DWnWrB2VpWHQv0/KtUAAYAwBUuXYBaKKKkAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK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RGJ2jIDLzkMM9wQCPpXM6V8IfDuk614c1uC7vGm8N2ktrAjsu2YuCDJIMcuNzYIx9413VFAHBn4VfY2a48PeMNY0m6a+vr1pYhFIr/apmldGjkRkIDMdpIyB3qfwl8K9E8IajZ6rY3t3LPa2dzaMZSuJTPKkjyMABhtyDgYGCeK7WigDC8N+EbHwzoM3h+0uZ5YZp7qcvJjcDPK8jDgAYBcgewFc6vwc0NbW1tU1fVI/sel3WlRSRSiOQJPKspkDKAQ6soxjj1Brv6KAPPf+FQwX76jdeJvFWp6xe39gNNW5ljgiaGAMWG0RIqk7jnLA10Wg+F73RZ7SWfxVqmoJa2IsvJn8tY5CGBEpVFA3gDbxgYzxmugooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//Z\"}"); - socket_status.send("{ \"RequestType\":\"SendImage\", \"RequestID\":\"788346414\", \"toType\":\"toUser\", \"toID\":\"1036\", \"fileType\":\"image/jpeg\", \"blob\":\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAHgAoADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopNy/wB4fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/AHh+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv8AeH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/wB4fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/AHh+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv8AeH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/wB4fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/AHh+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv8AeH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/wB4fnRuX+8PzoAWik3L/eH50bl/vD86AFopNy/3h+dG5f7w/OgBaKTcv94fnRuX+8PzoAxst6mky3940UmRQA7J9TRk+ppKKAAFh/EaCWP8RoooAXJ9TRk+ppKKADL/AN40Zf8AvGkwKMCgA3N/eNG5v7xoI70Ad6AF3Mf4iPxpMsP4j+dHSlxmgBCWH8R/OlBb+8fzpCM96OgoAVWb+8fzoLN6n86OBTSc0AOy3940Zb+8aTg0YFACkv8A3jRlv7xpNvvSYx3oAXLn+I0Ev/eNAwOc0YBNABubHU/nSbm/vH86VaMc5oATc394/nTt3+0aTb70baAAl8/eP50uW/vGk20baADc3940B27k0babQA/Lf3jRlv7xpMAdTRgH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iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9k=\"}"); -} - -var socket_ot; - -function ot_open() { - socket_ot = new_ws(get_appropriate_ws_url(""), "dumb-increment-protocol"); - - console.log("ot_open"); - - try { - socket_ot.onopen = function() { - document.getElementById("ot_statustd").style.backgroundColor = - "#40ff40"; - document.getElementById("ot_status").innerHTML = - " websocket connection opened
" + - san(socket_di.extensions); - document.getElementById("ot_open_btn").disabled = true; - document.getElementById("ot_close_btn").disabled = false; - document.getElementById("ot_req_close_btn").disabled = false; - console.log("ot_open.onopen"); - }; - - socket_ot.onclose = function(e){ - document.getElementById("ot_statustd").style.backgroundColor = - "#ff4040"; - document.getElementById("ot_status").textContent = - " websocket connection CLOSED, code: " + e.code + - ", reason: " + e.reason; - document.getElementById("ot_open_btn").disabled = false; - document.getElementById("ot_close_btn").disabled = true; - document.getElementById("ot_req_close_btn").disabled = true; - }; - } catch(exception) { - alert("

Error" + exception); - } -} - -/* browser will close the ws in a controlled way */ -function ot_close() { - socket_ot.close(3000, "Bye!"); -} - -/* we ask the server to close the ws in a controlled way */ -function ot_req_close() { - socket_ot.send("closeme\n"); -} - -var socket_lm; -var pending = ""; - -function lm_timer_handler(ev) { - socket_lm.send(pending); - pending=""; -} - -/* lws-mirror protocol */ - -var down = 0; -var no_last = 1; -var last_x = 0, last_y = 0; -var ctx; -var color = "#000000"; -var lm_timer; - -function ev_mousemove (ev) { - var x, y; - - if (ev.offsetX) { - x = ev.offsetX; - y = ev.offsetY; - } else { - x = ev.layerX - offsetX; - y = ev.layerY - offsetY; - - } - - if (!down) - return; - if (no_last) { - no_last = 0; - last_x = x; - last_y = y; - return; - } - pending = pending + "d " + color + " " + last_x + " " + last_y + - " " + x + " " + y + ";"; - - if (pending.length > 400) { - socket_lm.send(pending); - clearTimeout(lm_timer); - pending = ""; - } else - lm_timer = setTimeout(lm_timer_handler, 1); - - last_x = x; - last_y = y; -} - -function ev_mousedown (ev) { - down = 1; -} - -function ev_mouseup(ev) { - down = 0; - no_last = 1; -} - - -function ws_open_mirror() -{ - socket_lm = new_ws(get_appropriate_ws_url("?mirror=" + mirror_name), - "lws-mirror-protocol"); - try { - socket_lm.onopen = function() { - document.getElementById("wslm_statustd").style.backgroundColor = - "#40ff40"; - document.getElementById("wslm_status").innerHTML = - " websocket connection opened
" + - san(socket_lm.extensions); - lws_gray_out(false); - }; - - socket_lm.onmessage =function got_packet(msg) { - j = msg.data.split(";"); - var f = 0; - while (f < j.length - 1) { - i = j[f].split(" "); - if (i[0] === "d") { - ctx.strokeStyle = i[1]; - ctx.beginPath(); - ctx.moveTo(+(i[2]), +(i[3])); - ctx.lineTo(+(i[4]), +(i[5])); - ctx.stroke(); - } - if (i[0] === "c") { - ctx.strokeStyle = i[1]; - ctx.beginPath(); - ctx.arc(+(i[2]), +(i[3]), +(i[4]), 0, Math.PI*2, true); - ctx.stroke(); - } - - f++; - } - }; - - socket_lm.onclose = function(){ - document.getElementById("wslm_statustd").style.backgroundColor = - "#ff4040"; - document.getElementById("wslm_status").textContent = - " websocket connection CLOSED "; - lws_gray_out(true,{"zindex":"499"}); - }; - } catch(exception) { - alert("

Error" + exception); - } - - var canvas = document.createElement("canvas"); - canvas.height = 300; - canvas.width = 480; - ctx = canvas.getContext("2d"); - - document.getElementById("wslm_drawing").appendChild(canvas); - - canvas.addEventListener("mousemove", ev_mousemove, false); - canvas.addEventListener("mousedown", ev_mousedown, false); - canvas.addEventListener("mouseup", ev_mouseup, false); - - offsetX = offsetY = 0; - element = canvas; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop; - element = element.offsetParent; - } while (element); - } -} - -function update_color() { - color = document.getElementById("color").value; -} - -/* stuff that has to be delayed until all the page assets are loaded */ - -window.addEventListener("load", function() { - - lws_gray_out(true,{"zindex":"499"}); - - document.getElementById("file").onchange = check_file; - document.getElementById("offset").onclick = reset; - document.getElementById("junk").onclick = junk; - document.getElementById("color").onclick = update_color; - document.getElementById("ot_open_btn").onclick = ot_open; - document.getElementById("ot_close_btn").onclick = ot_close; - document.getElementById("ot_req_close_btn").onclick = ot_req_close; - document.getElementById("pmd").onclick = on_pmd; - - var transport_protocol = ""; - - if ( performance && performance.timing.nextHopProtocol ) { - transport_protocol = performance.timing.nextHopProtocol; - } else if ( window.chrome && window.chrome.loadTimes ) { - transport_protocol = window.chrome.loadTimes().connectionInfo; - } else { - - var p = performance.getEntriesByType("resource"); - for (var i=0; i < p.length; i++) { - var value = "nextHopProtocol" in p[i]; - if (value) - transport_protocol = p[i].nextHopProtocol; - } - } - - console.log("transport protocol " + transport_protocol); - - if (transport_protocol === "h2") - document.getElementById("transport").innerHTML = - ""; - - BrowserDetect.init(); - - document.getElementById("brow").textContent = " " + - BrowserDetect.browser + " " + BrowserDetect.version + " " + - BrowserDetect.OS +" "; - - document.getElementById("number").textContent = - get_appropriate_ws_url(mirror_name); - - /* create the ws connections back to the server */ - - ws_open_dumb_increment(); - ws_open_status(); - ws_open_mirror(); - -}, false); - -}()); diff --git a/mount-origin/wss-over-h2.png b/mount-origin/wss-over-h2.png deleted file mode 100644 index 1a62d83..0000000 Binary files a/mount-origin/wss-over-h2.png and /dev/null differ diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 75b0fe6..0000000 --- a/src/main.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * lws-minimal-http-server-eventlib - * - * Written in 2010-2019 by Andy Green - * - * This file is made available under the Creative Commons CC0 1.0 - * Universal Public Domain Dedication. - * - * This demonstrates a minimal http[s] server that can work with any of the - * supported event loop backends, or the default poll() one. - * - * To keep it simple, it serves stuff from the subdirectory - * "./mount-origin" of the directory it was started in. - * You can change that by changing mount.origin below. - */ - -#include -#include -#include - -#define LWS_PLUGIN_STATIC -#include "./plugins/protocol_lws_mirror.c" -#include "./plugins/protocol_lws_status.c" -#include "./plugins/protocol_dumb_increment.c" -#include "./plugins/protocol_post_demo.c" - -static struct lws_context *context; - -static struct lws_protocols protocols[] = { - /* first protocol must always be HTTP handler */ - - { "http-only", lws_callback_http_dummy, 0, 0, }, - LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT, - LWS_PLUGIN_PROTOCOL_MIRROR, - LWS_PLUGIN_PROTOCOL_LWS_STATUS, - LWS_PLUGIN_PROTOCOL_POST_DEMO, - { NULL, NULL, 0, 0 } /* terminator */ -}; - -/* - * mount handlers for sections of the URL space - */ - -static const struct lws_http_mount mount_ziptest = { - NULL, /* linked-list pointer to next*/ - "/ziptest", /* mountpoint in URL namespace on this vhost */ - "candide.zip", /* handler */ - NULL, /* default filename if none given */ - NULL, - NULL, - NULL, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - LWSMPRO_FILE, /* origin points to a callback */ - 8, /* strlen("/ziptest"), ie length of the mountpoint */ - NULL, - - { NULL, NULL } // sentinel -}; - -static const struct lws_http_mount mount_post = { - (struct lws_http_mount *)&mount_ziptest, /* linked-list pointer to next*/ - "/formtest", /* mountpoint in URL namespace on this vhost */ - "protocol-post-demo", /* handler */ - NULL, /* default filename if none given */ - NULL, - NULL, - NULL, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - LWSMPRO_CALLBACK, /* origin points to a callback */ - 9, /* strlen("/formtest"), ie length of the mountpoint */ - NULL, - - { NULL, NULL } // sentinel -}; - - -static const struct lws_http_mount mount = { - /* .mount_next */ &mount_post, /* linked-list "next" */ - /* .mountpoint */ "/", /* mountpoint URL */ - /* .origin */ "./mount-origin", /* serve from dir */ - /* .def */ "test.html", /* default filename */ - /* .protocol */ NULL, - /* .cgienv */ NULL, - /* .extra_mimetypes */ NULL, - /* .interpret */ NULL, - /* .cgi_timeout */ 0, - /* .cache_max_age */ 0, - /* .auth_mask */ 0, - /* .cache_reusable */ 0, - /* .cache_revalidate */ 0, - /* .cache_intermediaries */ 0, - /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ - /* .mountpoint_len */ 1, /* char count */ - /* .basic_auth_login_file */ NULL, -}; - -void signal_cb(void *handle, int signum) -{ - lwsl_err("%s: signal %d\n", __func__, signum); - - switch (signum) { - case SIGTERM: - case SIGINT: - break; - default: - - break; - } - lws_context_destroy(context); -} - -void sigint_handler(int sig) -{ - signal_cb(NULL, sig); -} - -int main(int argc, const char **argv) -{ - struct lws_context_creation_info info; - const char *p; - int logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE - /* for LLL_ verbosity above NOTICE to be built into lws, - * lws must have been configured and built with - * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ - /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ - /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ - /* | LLL_DEBUG */; - - if ((p = lws_cmdline_option(argc, argv, "-d"))) - logs = atoi(p); - - lws_set_log_level(logs, NULL); - lwsl_user("LWS minimal http server eventlib | visit http://localhost:7681\n"); - lwsl_user(" [-s (ssl)] [--uv (libuv)] [--ev (libev)] [--event (libevent)]\n"); - - memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ - info.port = 7681; - info.mounts = &mount; - info.error_document_404 = "/404.html"; - info.pcontext = &context; - info.protocols = protocols; - info.signal_cb = signal_cb; - info.options = - LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; - - if (lws_cmdline_option(argc, argv, "-s")) { - info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - info.ssl_cert_filepath = "localhost-100y.cert"; - info.ssl_private_key_filepath = "localhost-100y.key"; - } - - if (lws_cmdline_option(argc, argv, "--uv")) - info.options |= LWS_SERVER_OPTION_LIBUV; - else - if (lws_cmdline_option(argc, argv, "--event")) - info.options |= LWS_SERVER_OPTION_LIBEVENT; - else - if (lws_cmdline_option(argc, argv, "--ev")) - info.options |= LWS_SERVER_OPTION_LIBEV; - else - signal(SIGINT, sigint_handler); - - context = lws_create_context(&info); - if (!context) { - lwsl_err("lws init failed\n"); - return 1; - } - - while (!lws_service(context, 0)) - ; - - lwsl_info("calling external context destroy\n"); - lws_context_destroy(context); - - return 0; -} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d0616cc --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,55 @@ + /*! + * main.cpp + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 08/11/2019 + * + */ + + // This is an independent project of an individual developer. Dear PVS-Studio, please check it. + // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + + /*-------------------------------- INCLUDES ---------------------------------*/ + + #include + + #include "server/domo-server.h" + + /*! ---------------------------------------------------------------------------- + * @fn main + * + * @brief Main function of domo-iot daemon. + */ + int main(int argc, char *argv[]) + { + int the_return; + + DomoServer the_server; + + if (!the_server.setup()) + { + fprintf(stderr, "Failed to setup the daemon.\n"); + return -1; + } + + the_return = the_server.loop(); + + return the_return; + } \ No newline at end of file diff --git a/src/plugins/protocol_dumb_increment.c b/src/plugins/protocol_dumb_increment.c deleted file mode 100644 index 11d6fef..0000000 --- a/src/plugins/protocol_dumb_increment.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * ws protocol handler plugin for "dumb increment" - * - * Written in 2010-2019 by Andy Green - * - * This file is made available under the Creative Commons CC0 1.0 - * Universal Public Domain Dedication. - * - * The person who associated a work with this deed has dedicated - * the work to the public domain by waiving all of his or her rights - * to the work worldwide under copyright law, including all related - * and neighboring rights, to the extent allowed by law. You can copy, - * modify, distribute and perform the work, even for commercial purposes, - * all without asking permission. - * - * These test plugins are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ - -#if !defined (LWS_PLUGIN_STATIC) -#define LWS_DLL -#define LWS_INTERNAL -#include -#endif - -#include - -#define DUMB_PERIOD_US 50000 - -struct pss__dumb_increment { - int number; -}; - -struct vhd__dumb_increment { - const unsigned int *options; -}; - -static int -callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct pss__dumb_increment *pss = (struct pss__dumb_increment *)user; - struct vhd__dumb_increment *vhd = - (struct vhd__dumb_increment *) - lws_protocol_vh_priv_get(lws_get_vhost(wsi), - lws_get_protocol(wsi)); - uint8_t buf[LWS_PRE + 20], *p = &buf[LWS_PRE]; - const struct lws_protocol_vhost_options *opt; - int n, m; - - switch (reason) { - case LWS_CALLBACK_PROTOCOL_INIT: - vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi), - lws_get_protocol(wsi), - sizeof(struct vhd__dumb_increment)); - if (!vhd) - return -1; - if ((opt = lws_pvo_search( - (const struct lws_protocol_vhost_options *)in, - "options"))) - vhd->options = (unsigned int *)opt->value; - break; - - case LWS_CALLBACK_ESTABLISHED: - pss->number = 0; - if (!vhd->options || !((*vhd->options) & 1)) - lws_set_timer_usecs(wsi, DUMB_PERIOD_US); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - n = lws_snprintf((char *)p, sizeof(buf) - LWS_PRE, "%d", - pss->number++); - m = lws_write(wsi, p, n, LWS_WRITE_TEXT); - if (m < n) { - lwsl_err("ERROR %d writing to di socket\n", n); - return -1; - } - break; - - case LWS_CALLBACK_RECEIVE: - if (len < 6) - break; - if (strncmp((const char *)in, "reset\n", 6) == 0) - pss->number = 0; - if (strncmp((const char *)in, "closeme\n", 8) == 0) { - lwsl_notice("dumb_inc: closing as requested\n"); - lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, - (unsigned char *)"seeya", 5); - return -1; - } - break; - - case LWS_CALLBACK_TIMER: - if (!vhd->options || !((*vhd->options) & 1)) { - lws_callback_on_writable_all_protocol_vhost( - lws_get_vhost(wsi), lws_get_protocol(wsi)); - lws_set_timer_usecs(wsi, DUMB_PERIOD_US); - } - break; - - default: - break; - } - - return 0; -} - -#define LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT \ - { \ - "dumb-increment-protocol", \ - callback_dumb_increment, \ - sizeof(struct pss__dumb_increment), \ - 10, /* rx buf size must be >= permessage-deflate rx size */ \ - 0, NULL, 0 \ - } - -#if !defined (LWS_PLUGIN_STATIC) - -static const struct lws_protocols protocols[] = { - LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT -}; - -LWS_EXTERN LWS_VISIBLE int -init_protocol_dumb_increment(struct lws_context *context, - struct lws_plugin_capability *c) -{ - if (c->api_magic != LWS_PLUGIN_API_MAGIC) { - lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC, - c->api_magic); - return 1; - } - - c->protocols = protocols; - c->count_protocols = LWS_ARRAY_SIZE(protocols); - c->extensions = NULL; - c->count_extensions = 0; - - return 0; -} - -LWS_EXTERN LWS_VISIBLE int -destroy_protocol_dumb_increment(struct lws_context *context) -{ - return 0; -} - -#endif diff --git a/src/plugins/protocol_lws_mirror.c b/src/plugins/protocol_lws_mirror.c deleted file mode 100644 index 70f501c..0000000 --- a/src/plugins/protocol_lws_mirror.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Written in 2010-2019 by Andy Green - * - * This file is made available under the Creative Commons CC0 1.0 - * Universal Public Domain Dedication. - * - * The person who associated a work with this deed has dedicated - * the work to the public domain by waiving all of his or her rights - * to the work worldwide under copyright law, including all related - * and neighboring rights, to the extent allowed by law. You can copy, - * modify, distribute and perform the work, even for commercial purposes, - * all without asking permission. - * - * The test apps are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - * - * Notice that the lws_pthread... locking apis are all zero-footprint - * NOPs in the case LWS_MAX_SMP == 1, which is the default. When lws - * is built for multiple service threads though, they resolve to their - * pthreads equivalents. - */ - -#if !defined (LWS_PLUGIN_STATIC) -#define LWS_DLL -#define LWS_INTERNAL -#include -#endif - -#include -#include - -#define QUEUELEN 32 -/* queue free space below this, rx flow is disabled */ -#define RXFLOW_MIN (4) -/* queue free space above this, rx flow is enabled */ -#define RXFLOW_MAX ((2 * QUEUELEN) / 3) - -#define MAX_MIRROR_INSTANCES 3 - -struct mirror_instance; - -struct per_session_data__lws_mirror { - struct lws *wsi; - struct mirror_instance *mi; - struct per_session_data__lws_mirror *same_mi_pss_list; - uint32_t tail; -}; - -/* this is the element in the ring */ -struct a_message { - void *payload; - size_t len; -}; - -struct mirror_instance { - struct mirror_instance *next; - lws_pthread_mutex(lock) /* protects all mirror instance data */ - struct per_session_data__lws_mirror *same_mi_pss_list; - /**< must hold the the per_vhost_data__lws_mirror.lock as well - * to change mi list membership */ - struct lws_ring *ring; - int messages_allocated; - char name[30]; - char rx_enabled; -}; - -struct per_vhost_data__lws_mirror { - lws_pthread_mutex(lock) /* protects mi_list membership changes */ - struct mirror_instance *mi_list; -}; - - -/* enable or disable rx from all connections to this mirror instance */ -static void -__mirror_rxflow_instance(struct mirror_instance *mi, int enable) -{ - lws_start_foreach_ll(struct per_session_data__lws_mirror *, - pss, mi->same_mi_pss_list) { - lws_rx_flow_control(pss->wsi, enable); - } lws_end_foreach_ll(pss, same_mi_pss_list); - - mi->rx_enabled = enable; -} - -/* - * Find out which connection to this mirror instance has the longest number - * of still unread elements in the ringbuffer and update the lws_ring "oldest - * tail" with it. Elements behind the "oldest tail" are freed and recycled for - * new head content. Elements after the "oldest tail" are still waiting to be - * read by somebody. - * - * If the oldest tail moved on from before, check if it created enough space - * in the queue to re-enable RX flow control for the mirror instance. - * - * Mark connections that are at the oldest tail as being on a 3s timeout to - * transmit something, otherwise the connection will be closed. Without this, - * a choked or nonresponsive connection can block the FIFO from freeing up any - * new space for new data. - * - * You can skip calling this if on your connection, before processing, the tail - * was not equal to the current worst, ie, if the tail you will work on is != - * lws_ring_get_oldest_tail(ring) then no need to call this when the tail - * has changed; it wasn't the oldest so it won't change the oldest. - * - * Returns 0 if oldest unchanged or 1 if oldest changed from this call. - */ -static int -__mirror_update_worst_tail(struct mirror_instance *mi) -{ - uint32_t wai, worst = 0, worst_tail = 0, oldest; - struct per_session_data__lws_mirror *worst_pss = NULL; - - oldest = lws_ring_get_oldest_tail(mi->ring); - - lws_start_foreach_ll(struct per_session_data__lws_mirror *, - pss, mi->same_mi_pss_list) { - wai = (uint32_t)lws_ring_get_count_waiting_elements(mi->ring, - &pss->tail); - if (wai >= worst) { - worst = wai; - worst_tail = pss->tail; - worst_pss = pss; - } - } lws_end_foreach_ll(pss, same_mi_pss_list); - - if (!worst_pss) - return 0; - - lws_ring_update_oldest_tail(mi->ring, worst_tail); - if (oldest == lws_ring_get_oldest_tail(mi->ring)) - return 0; - /* - * The oldest tail did move on. Check if we should re-enable rx flow - * for the mirror instance since we made some space now. - */ - if (!mi->rx_enabled && /* rx is disabled */ - lws_ring_get_count_free_elements(mi->ring) >= RXFLOW_MAX) - /* there is enough space, let's re-enable rx for our instance */ - __mirror_rxflow_instance(mi, 1); - - /* if nothing in queue, no timeout needed */ - if (!worst) - return 1; - - /* - * The guy(s) with the oldest tail block the ringbuffer from recycling - * the FIFO entries he has not read yet. Don't allow those guys to - * block the FIFO operation for very long. - */ - lws_start_foreach_ll(struct per_session_data__lws_mirror *, - pss, mi->same_mi_pss_list) { - if (pss->tail == worst_tail) - /* - * Our policy is if you are the slowest connection, - * you had better transmit something to help with that - * within 3s, or we will hang up on you to stop you - * blocking the FIFO for everyone else. - */ - lws_set_timeout(pss->wsi, - PENDING_TIMEOUT_USER_REASON_BASE, 3); - } lws_end_foreach_ll(pss, same_mi_pss_list); - - return 1; -} - -static void -__mirror_callback_all_in_mi_on_writable(struct mirror_instance *mi) -{ - /* ask for WRITABLE callback for every wsi on this mi */ - lws_start_foreach_ll(struct per_session_data__lws_mirror *, - pss, mi->same_mi_pss_list) { - lws_callback_on_writable(pss->wsi); - } lws_end_foreach_ll(pss, same_mi_pss_list); -} - -static void -__mirror_destroy_message(void *_msg) -{ - struct a_message *msg = _msg; - - free(msg->payload); - msg->payload = NULL; - msg->len = 0; -} - -static int -callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct per_session_data__lws_mirror *pss = - (struct per_session_data__lws_mirror *)user; - struct per_vhost_data__lws_mirror *v = - (struct per_vhost_data__lws_mirror *) - lws_protocol_vh_priv_get(lws_get_vhost(wsi), - lws_get_protocol(wsi)); - char name[300], update_worst, sent_something, *pn = name; - struct mirror_instance *mi = NULL; - const struct a_message *msg; - struct a_message amsg; - uint32_t oldest_tail; - int n, count_mi = 0; - - switch (reason) { - case LWS_CALLBACK_ESTABLISHED: - lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__); - - /* - * mirror instance name... defaults to "", but if URL includes - * "?mirror=xxx", will be "xxx" - */ - name[0] = '\0'; - if (!lws_get_urlarg_by_name(wsi, "mirror", name, - sizeof(name) - 1)) - lwsl_debug("get urlarg failed\n"); - if (strchr(name, '=')) - pn = strchr(name, '=') + 1; - - //lwsl_notice("%s: mirror name '%s'\n", __func__, pn); - - /* is there already a mirror instance of this name? */ - - lws_pthread_mutex_lock(&v->lock); /* vhost lock { */ - - lws_start_foreach_ll(struct mirror_instance *, mi1, - v->mi_list) { - count_mi++; - if (!strcmp(pn, mi1->name)) { - /* yes... we will join it */ - mi = mi1; - break; - } - } lws_end_foreach_ll(mi1, next); - - if (!mi) { - - /* no existing mirror instance for name */ - if (count_mi == MAX_MIRROR_INSTANCES) { - lws_pthread_mutex_unlock(&v->lock); /* } vh lock */ - return -1; - } - - /* create one with this name, and join it */ - mi = malloc(sizeof(*mi)); - if (!mi) - goto bail1; - memset(mi, 0, sizeof(*mi)); - mi->ring = lws_ring_create(sizeof(struct a_message), - QUEUELEN, - __mirror_destroy_message); - if (!mi->ring) { - free(mi); - goto bail1; - } - - mi->next = v->mi_list; - v->mi_list = mi; - lws_snprintf(mi->name, sizeof(mi->name) - 1, "%s", pn); - mi->rx_enabled = 1; - - lws_pthread_mutex_init(&mi->lock); - - lwsl_notice("Created new mi %p '%s'\n", mi, pn); - } - - /* add our pss to list of guys bound to this mi */ - - lws_ll_fwd_insert(pss, same_mi_pss_list, mi->same_mi_pss_list); - - /* init the pss */ - - pss->mi = mi; - pss->tail = lws_ring_get_oldest_tail(mi->ring); - pss->wsi = wsi; - - lws_pthread_mutex_unlock(&v->lock); /* } vhost lock */ - break; - -bail1: - lws_pthread_mutex_unlock(&v->lock); /* } vhost lock */ - return 1; - - case LWS_CALLBACK_CLOSED: - /* detach our pss from the mirror instance */ - mi = pss->mi; - if (!mi) - break; - - lws_pthread_mutex_lock(&v->lock); /* vhost lock { */ - - /* remove our closing pss from its mirror instance list */ - lws_ll_fwd_remove(struct per_session_data__lws_mirror, - same_mi_pss_list, pss, mi->same_mi_pss_list); - pss->mi = NULL; - - if (mi->same_mi_pss_list) { - /* - * Still other pss using the mirror instance. The pss - * going away may have had the oldest tail, reconfirm - * using the remaining pss what is the current oldest - * tail. If the oldest tail moves on, this call also - * will re-enable rx flow control when appropriate. - */ - lws_pthread_mutex_lock(&mi->lock); /* mi lock { */ - __mirror_update_worst_tail(mi); - lws_pthread_mutex_unlock(&mi->lock); /* } mi lock */ - lws_pthread_mutex_unlock(&v->lock); /* } vhost lock */ - break; - } - - /* No more pss using the mirror instance... delete mi */ - - lws_start_foreach_llp(struct mirror_instance **, - pmi, v->mi_list) { - if (*pmi == mi) { - *pmi = (*pmi)->next; - - lws_ring_destroy(mi->ring); - lws_pthread_mutex_destroy(&mi->lock); - - free(mi); - break; - } - } lws_end_foreach_llp(pmi, next); - - lws_pthread_mutex_unlock(&v->lock); /* } vhost lock */ - break; - - case LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: - return 1; /* disallow compression */ - - case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */ - lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi), - lws_get_protocol(wsi), - sizeof(struct per_vhost_data__lws_mirror)); - v = (struct per_vhost_data__lws_mirror *) - lws_protocol_vh_priv_get(lws_get_vhost(wsi), - lws_get_protocol(wsi)); - lws_pthread_mutex_init(&v->lock); - break; - - case LWS_CALLBACK_PROTOCOL_DESTROY: - lws_pthread_mutex_destroy(&v->lock); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - lws_pthread_mutex_lock(&pss->mi->lock); /* instance lock { */ - oldest_tail = lws_ring_get_oldest_tail(pss->mi->ring); - update_worst = oldest_tail == pss->tail; - sent_something = 0; - - do { - msg = lws_ring_get_element(pss->mi->ring, &pss->tail); - if (!msg) - break; - - if (!msg->payload) { - lwsl_err("%s: NULL payload: worst = %d," - " pss->tail = %d\n", __func__, - oldest_tail, pss->tail); - if (lws_ring_consume(pss->mi->ring, &pss->tail, - NULL, 1)) - continue; - break; - } - - n = lws_write(wsi, (unsigned char *)msg->payload + - LWS_PRE, msg->len, LWS_WRITE_TEXT); - if (n < 0) { - lwsl_info("%s: WRITEABLE: %d\n", __func__, n); - - goto bail2; - } - sent_something = 1; - lws_ring_consume(pss->mi->ring, &pss->tail, NULL, 1); - - } while (!lws_send_pipe_choked(wsi)); - - /* if any left for us to send, ask for writeable again */ - if (lws_ring_get_count_waiting_elements(pss->mi->ring, - &pss->tail)) - lws_callback_on_writable(wsi); - - if (!sent_something || !update_worst) - goto done1; - - /* - * We are no longer holding the oldest tail (since we sent - * something. So free us of the timeout related to hogging the - * oldest tail. - */ - lws_set_timeout(pss->wsi, NO_PENDING_TIMEOUT, 0); - /* - * If we were originally at the oldest fifo position of - * all the tails, now we used some up we may have - * changed the oldest fifo position and made some space. - */ - __mirror_update_worst_tail(pss->mi); - -done1: - lws_pthread_mutex_unlock(&pss->mi->lock); /* } instance lock */ - break; - -bail2: - lws_pthread_mutex_unlock(&pss->mi->lock); /* } instance lock */ - - return -1; - - case LWS_CALLBACK_RECEIVE: - lws_pthread_mutex_lock(&pss->mi->lock); /* mi lock { */ - n = (int)lws_ring_get_count_free_elements(pss->mi->ring); - if (!n) { - lwsl_notice("dropping!\n"); - if (pss->mi->rx_enabled) - __mirror_rxflow_instance(pss->mi, 0); - goto req_writable; - } - - amsg.payload = malloc(LWS_PRE + len); - amsg.len = len; - if (!amsg.payload) { - lwsl_notice("OOM: dropping\n"); - goto done2; - } - - memcpy((char *)amsg.payload + LWS_PRE, in, len); - if (!lws_ring_insert(pss->mi->ring, &amsg, 1)) { - __mirror_destroy_message(&amsg); - lwsl_notice("dropping!\n"); - if (pss->mi->rx_enabled) - __mirror_rxflow_instance(pss->mi, 0); - goto req_writable; - } - - if (pss->mi->rx_enabled && - lws_ring_get_count_free_elements(pss->mi->ring) < - RXFLOW_MIN) - __mirror_rxflow_instance(pss->mi, 0); - -req_writable: - __mirror_callback_all_in_mi_on_writable(pss->mi); - -done2: - lws_pthread_mutex_unlock(&pss->mi->lock); /* } mi lock */ - break; - - case LWS_CALLBACK_EVENT_WAIT_CANCELLED: - lwsl_info("LWS_CALLBACK_EVENT_WAIT_CANCELLED\n"); - break; - - default: - break; - } - - return 0; -} - -#define LWS_PLUGIN_PROTOCOL_MIRROR { \ - "lws-mirror-protocol", \ - callback_lws_mirror, \ - sizeof(struct per_session_data__lws_mirror), \ - 4096, /* rx buf size must be >= permessage-deflate rx size */ \ - 0, NULL, 0 \ - } - -#if !defined (LWS_PLUGIN_STATIC) - -static const struct lws_protocols protocols[] = { - LWS_PLUGIN_PROTOCOL_MIRROR -}; - -LWS_EXTERN LWS_VISIBLE int -init_protocol_lws_mirror(struct lws_context *context, - struct lws_plugin_capability *c) -{ - if (c->api_magic != LWS_PLUGIN_API_MAGIC) { - lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC, - c->api_magic); - return 1; - } - - c->protocols = protocols; - c->count_protocols = LWS_ARRAY_SIZE(protocols); - c->extensions = NULL; - c->count_extensions = 0; - - return 0; -} - -LWS_EXTERN LWS_VISIBLE int -destroy_protocol_lws_mirror(struct lws_context *context) -{ - return 0; -} -#endif diff --git a/src/plugins/protocol_lws_status.c b/src/plugins/protocol_lws_status.c deleted file mode 100644 index 8364be4..0000000 --- a/src/plugins/protocol_lws_status.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Written in 2010-2019 by Andy Green - * - * This file is made available under the Creative Commons CC0 1.0 - * Universal Public Domain Dedication. - * - * The person who associated a work with this deed has dedicated - * the work to the public domain by waiving all of his or her rights - * to the work worldwide under copyright law, including all related - * and neighboring rights, to the extent allowed by law. You can copy, - * modify, distribute and perform the work, even for commercial purposes, - * all without asking permission. - * - * The test apps are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ - -#if !defined (LWS_PLUGIN_STATIC) -#define LWS_DLL -#define LWS_INTERNAL -#include -#endif - -#include -#include -#ifdef WIN32 -#include -#include -#endif - - -typedef enum { - WALK_NONE, - WALK_INITIAL, - WALK_LIST, - WALK_FINAL -} e_walk; - -struct per_session_data__lws_status { - struct per_session_data__lws_status *next; - struct lws *wsi; - time_t time_est; - char user_agent[256]; - - e_walk walk; - struct per_session_data__lws_status *walk_next; - unsigned char subsequent:1; - unsigned char changed_partway:1; - unsigned char wss_over_h2:1; -}; - -struct per_vhost_data__lws_status { - struct per_session_data__lws_status *live_pss_list; - struct lws_context *context; - struct lws_vhost *vhost; - const struct lws_protocols *protocol; - int count_live_pss; -}; - -static void -trigger_resend(struct per_vhost_data__lws_status *vhd) -{ - lws_start_foreach_ll(struct per_session_data__lws_status *, pss, - vhd->live_pss_list) { - if (pss->walk == WALK_NONE) { - pss->subsequent = 0; - pss->walk_next = vhd->live_pss_list; - pss->walk = WALK_INITIAL; - } else - pss->changed_partway = 1; - } lws_end_foreach_ll(pss, next); - - lws_callback_on_writable_all_protocol(vhd->context, vhd->protocol); -} - -/* lws-status protocol */ - -int -callback_lws_status(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct per_session_data__lws_status *pss = - (struct per_session_data__lws_status *)user; - struct per_vhost_data__lws_status *vhd = - (struct per_vhost_data__lws_status *) - lws_protocol_vh_priv_get(lws_get_vhost(wsi), - lws_get_protocol(wsi)); - char buf[LWS_PRE + 384], ip[24], *start = buf + LWS_PRE - 1, *p = start, - *end = buf + sizeof(buf) - 1; - int n, m; - - switch (reason) { - - case LWS_CALLBACK_PROTOCOL_INIT: - vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi), - lws_get_protocol(wsi), - sizeof(struct per_vhost_data__lws_status)); - vhd->context = lws_get_context(wsi); - vhd->protocol = lws_get_protocol(wsi); - vhd->vhost = lws_get_vhost(wsi); - break; - - case LWS_CALLBACK_ESTABLISHED: - - /* - * This shows how to stage sending a single ws message in - * multiple fragments. In this case, it lets us trade off - * memory needed to make the data vs time to send it. - */ - - vhd->count_live_pss++; - pss->next = vhd->live_pss_list; - vhd->live_pss_list = pss; - - pss->wss_over_h2 = !!len; - - time(&pss->time_est); - pss->wsi = wsi; - - if (lws_hdr_copy(wsi, pss->user_agent, sizeof(pss->user_agent), - WSI_TOKEN_HTTP_USER_AGENT) < 0) /* too big */ - strcpy(pss->user_agent, "unknown"); - trigger_resend(vhd); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - switch (pss->walk) { - case WALK_INITIAL: - n = LWS_WRITE_TEXT | LWS_WRITE_NO_FIN; - p += lws_snprintf(p, end - p, - "{ \"version\":\"%s\"," - " \"wss_over_h2\":\"%d\"," - " \"hostname\":\"%s\"," - " \"wsi\":\"%d\", \"conns\":[", - lws_get_library_version(), - pss->wss_over_h2, - lws_canonical_hostname(vhd->context), - vhd->count_live_pss); - pss->walk = WALK_LIST; - pss->walk_next = vhd->live_pss_list; - break; - case WALK_LIST: - n = LWS_WRITE_CONTINUATION | LWS_WRITE_NO_FIN; - if (!pss->walk_next) - goto walk_final; - - if (pss->subsequent) - *p++ = ','; - pss->subsequent = 1; - - m = 0; - lws_start_foreach_ll(struct per_session_data__lws_status *, - pss2, vhd->live_pss_list) { - if (pss2 == pss->walk_next) { - m = 1; - break; - } - } lws_end_foreach_ll(pss2, next); - - if (!m) { - /* our next guy went away */ - pss->walk = WALK_FINAL; - pss->changed_partway = 1; - break; - } - - strcpy(ip, "unknown"); - lws_get_peer_simple(pss->walk_next->wsi, ip, sizeof(ip)); - p += lws_snprintf(p, end - p, - "{\"peer\":\"%s\",\"time\":\"%ld\"," - "\"ua\":\"%s\"}", - ip, (unsigned long)pss->walk_next->time_est, - pss->walk_next->user_agent); - pss->walk_next = pss->walk_next->next; - if (!pss->walk_next) - pss->walk = WALK_FINAL; - break; - case WALK_FINAL: -walk_final: - n = LWS_WRITE_CONTINUATION; - p += lws_snprintf(p, 4, "]}"); - if (pss->changed_partway) { - pss->changed_partway = 0; - pss->subsequent = 0; - pss->walk_next = vhd->live_pss_list; - pss->walk = WALK_INITIAL; - } else - pss->walk = WALK_NONE; - break; - default: - return 0; - } - - m = lws_write(wsi, (unsigned char *)start, p - start, n); - if (m < 0) { - lwsl_err("ERROR %d writing to di socket\n", m); - return -1; - } - - if (pss->walk != WALK_NONE) - lws_callback_on_writable(wsi); - break; - - case LWS_CALLBACK_RECEIVE: - lwsl_notice("pmd test: RX len %d\n", (int)len); - break; - - case LWS_CALLBACK_CLOSED: - // lwsl_debug("****** LWS_CALLBACK_CLOSED\n"); - lws_start_foreach_llp(struct per_session_data__lws_status **, - ppss, vhd->live_pss_list) { - if (*ppss == pss) { - *ppss = pss->next; - break; - } - } lws_end_foreach_llp(ppss, next); - - trigger_resend(vhd); - break; - - default: - break; - } - - return 0; -} - -#define LWS_PLUGIN_PROTOCOL_LWS_STATUS \ - { \ - "lws-status", \ - callback_lws_status, \ - sizeof(struct per_session_data__lws_status), \ - 512, /* rx buf size must be >= permessage-deflate rx size */ \ - 0, NULL, 0 \ - } - -#if !defined (LWS_PLUGIN_STATIC) - -static const struct lws_protocols protocols[] = { - LWS_PLUGIN_PROTOCOL_LWS_STATUS -}; - - -LWS_EXTERN LWS_VISIBLE int -init_protocol_lws_status(struct lws_context *context, - struct lws_plugin_capability *c) -{ - if (c->api_magic != LWS_PLUGIN_API_MAGIC) { - lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC, - c->api_magic); - return 1; - } - - c->protocols = protocols; - c->count_protocols = LWS_ARRAY_SIZE(protocols); - c->extensions = NULL; - c->count_extensions = 0; - - return 0; -} - -LWS_EXTERN LWS_VISIBLE int -destroy_protocol_lws_status(struct lws_context *context) -{ - return 0; -} - -#endif diff --git a/src/plugins/protocol_post_demo.c b/src/plugins/protocol_post_demo.c deleted file mode 100644 index 02503c3..0000000 --- a/src/plugins/protocol_post_demo.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * ws protocol handler plugin for "POST demo" - * - * Written in 2010-2019 by Andy Green - * - * This file is made available under the Creative Commons CC0 1.0 - * Universal Public Domain Dedication. - * - * The person who associated a work with this deed has dedicated - * the work to the public domain by waiving all of his or her rights - * to the work worldwide under copyright law, including all related - * and neighboring rights, to the extent allowed by law. You can copy, - * modify, distribute and perform the work, even for commercial purposes, - * all without asking permission. - * - * These test plugins are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ - -#if !defined (LWS_PLUGIN_STATIC) -#define LWS_DLL -#define LWS_INTERNAL -#include -#endif - -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#endif -#include - -struct per_session_data__post_demo { - struct lws_spa *spa; - char result[LWS_PRE + LWS_RECOMMENDED_MIN_HEADER_SPACE]; - char filename[64]; - long file_length; -#if !defined(LWS_WITH_ESP32) - lws_filefd_type fd; -#endif - uint8_t completed:1; - uint8_t sent_headers:1; - uint8_t sent_body:1; -}; - -static const char * const param_names[] = { - "text", - "send", - "file", - "upload", -}; - -enum enum_param_names { - EPN_TEXT, - EPN_SEND, - EPN_FILE, - EPN_UPLOAD, -}; - -static int -file_upload_cb(void *data, const char *name, const char *filename, - char *buf, int len, enum lws_spa_fileupload_states state) -{ - struct per_session_data__post_demo *pss = - (struct per_session_data__post_demo *)data; -#if !defined(LWS_WITH_ESP32) - int n; - - (void)n; -#endif - - switch (state) { - case LWS_UFS_OPEN: - lws_strncpy(pss->filename, filename, sizeof(pss->filename)); - /* we get the original filename in @filename arg, but for - * simple demo use a fixed name so we don't have to deal with - * attacks */ -#if !defined(LWS_WITH_ESP32) - pss->fd = (lws_filefd_type)(long long)lws_open("/tmp/post-file", - O_CREAT | O_TRUNC | O_RDWR, 0600); -#endif - break; - case LWS_UFS_FINAL_CONTENT: - case LWS_UFS_CONTENT: - if (len) { - pss->file_length += len; - - /* if the file length is too big, drop it */ - if (pss->file_length > 100000) - return 1; - -#if !defined(LWS_WITH_ESP32) - n = write((int)(long long)pss->fd, buf, len); - lwsl_info("%s: write %d says %d\n", __func__, len, n); -#else - lwsl_notice("%s: Received chunk size %d\n", __func__, len); -#endif - } - if (state == LWS_UFS_CONTENT) - break; -#if !defined(LWS_WITH_ESP32) - close((int)(long long)pss->fd); - pss->fd = LWS_INVALID_FILE; -#endif - break; - case LWS_UFS_CLOSE: - break; - } - - return 0; -} - -/* - * returns length in bytes - */ - -static int -format_result(struct per_session_data__post_demo *pss) -{ - unsigned char *p, *start, *end; - int n; - - p = (unsigned char *)pss->result + LWS_PRE; - start = p; - end = p + sizeof(pss->result) - LWS_PRE - 1; - - p += lws_snprintf((char *)p, end -p, - "" - "" - "LWS Server Status" - "

Form results (after urldecoding)

" - ""); - - for (n = 0; n < (int)LWS_ARRAY_SIZE(param_names); n++) { - if (!lws_spa_get_string(pss->spa, n)) - p += lws_snprintf((char *)p, end - p, - "", - param_names[n]); - else - p += lws_snprintf((char *)p, end - p, - "", - param_names[n], - lws_spa_get_length(pss->spa, n), - lws_spa_get_string(pss->spa, n)); - } - - p += lws_snprintf((char *)p, end - p, - "
NameLengthValue
%s0" - "NULL
%s%d" - "%s

filename: %s, " - "length %ld", - pss->filename, pss->file_length); - - p += lws_snprintf((char *)p, end - p, ""); - - return (int)lws_ptr_diff(p, start); -} - -static int -callback_post_demo(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct per_session_data__post_demo *pss = - (struct per_session_data__post_demo *)user; - unsigned char *p, *start, *end; - int n; - - switch (reason) { - case LWS_CALLBACK_HTTP_BODY: - /* create the POST argument parser if not already existing */ - if (!pss->spa) { - pss->spa = lws_spa_create(wsi, param_names, - LWS_ARRAY_SIZE(param_names), 1024, - file_upload_cb, pss); - if (!pss->spa) - return -1; - - pss->filename[0] = '\0'; - pss->file_length = 0; - } - - /* let it parse the POST data */ - if (lws_spa_process(pss->spa, in, (int)len)) - return -1; - break; - - case LWS_CALLBACK_HTTP_BODY_COMPLETION: - lwsl_debug("LWS_CALLBACK_HTTP_BODY_COMPLETION: %p\n", wsi); - /* call to inform no more payload data coming */ - lws_spa_finalize(pss->spa); - - pss->completed = 1; - lws_callback_on_writable(wsi); - break; - - case LWS_CALLBACK_HTTP_WRITEABLE: - if (!pss->completed) - break; - - p = (unsigned char *)pss->result + LWS_PRE; - start = p; - end = p + sizeof(pss->result) - LWS_PRE - 1; - - if (!pss->sent_headers) { - n = format_result(pss); - - if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, - &p, end)) - goto bail; - - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)"text/html", 9, - &p, end)) - goto bail; - if (lws_add_http_header_content_length(wsi, n, &p, end)) - goto bail; - if (lws_finalize_http_header(wsi, &p, end)) - goto bail; - - /* first send the headers ... */ - n = lws_write(wsi, start, lws_ptr_diff(p, start), - LWS_WRITE_HTTP_HEADERS); - if (n < 0) - goto bail; - - pss->sent_headers = 1; - lws_callback_on_writable(wsi); - break; - } - - if (!pss->sent_body) { - n = format_result(pss); - - n = lws_write(wsi, (unsigned char *)start, n, - LWS_WRITE_HTTP_FINAL); - - pss->sent_body = 1; - if (n < 0) - return 1; - goto try_to_reuse; - } - break; - - case LWS_CALLBACK_HTTP_DROP_PROTOCOL: - /* called when our wsi user_space is going to be destroyed */ - if (pss->spa) { - lws_spa_destroy(pss->spa); - pss->spa = NULL; - } - break; - - default: - break; - } - - return 0; - -bail: - - return 1; - -try_to_reuse: - if (lws_http_transaction_completed(wsi)) - return -1; - - return 0; -} - -#define LWS_PLUGIN_PROTOCOL_POST_DEMO \ - { \ - "protocol-post-demo", \ - callback_post_demo, \ - sizeof(struct per_session_data__post_demo), \ - 1024, \ - 0, NULL, 0 \ - } - -#if !defined (LWS_PLUGIN_STATIC) - -static const struct lws_protocols protocols[] = { - LWS_PLUGIN_PROTOCOL_POST_DEMO -}; - -LWS_EXTERN LWS_VISIBLE int -init_protocol_post_demo(struct lws_context *context, - struct lws_plugin_capability *c) -{ - if (c->api_magic != LWS_PLUGIN_API_MAGIC) { - lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC, - c->api_magic); - return 1; - } - - c->protocols = protocols; - c->count_protocols = LWS_ARRAY_SIZE(protocols); - c->extensions = NULL; - c->count_extensions = 0; - - return 0; -} - -LWS_EXTERN LWS_VISIBLE int -destroy_protocol_post_demo(struct lws_context *context) -{ - return 0; -} - -#endif diff --git a/src/web/web-server.cpp b/src/web/web-server.cpp deleted file mode 100644 index 16b6e78..0000000 --- a/src/web/web-server.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/*! - * web-server.cpp - * - * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * @Author: NADAL Jean-Baptiste - * @Date: 13/11/2019 - * - */ - -// This is an independent project of an individual developer. Dear PVS-Studio, please check it. -// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com - -/*------------------------------- INCLUDES ----------------------------------*/ - -#include - -#include "web-server.h" - -//404前回调(未找到页面/文件时回调,此功能便于程序返回自定义功能);返回0表示没有适合的处理请求,需要发送404错误 -char on_request(void* data, uv_stream_t* client, tw_peerAddr* pa, tw_reqHeads* heads) -{ -// struct sockaddr_in serveraddr, peeraddr; -// char serv_ip[17],peer_ip[17], tmp[1024]; -// int addrlen = sizeof(struct sockaddr); -// int r; -// -// //获取clientAddr: http://www.codes51.com/article/detail_113112.html -// //本地接入地址 -// r = uv_tcp_getsockname((uv_tcp_t*)client, (struct sockaddr*)&serveraddr, &addrlen); -// //网络字节序转换成主机字符序 -// uv_ip4_name(&serveraddr, (char*)serv_ip, sizeof(serv_ip)); -// //客户端的地址 -// r = uv_tcp_getpeername((uv_tcp_t*)client, (struct sockaddr*)&peeraddr, &addrlen); -// //网络字节序转换成主机字符序 -// uv_ip4_name(&peeraddr, (char*)peer_ip, sizeof(peer_ip)); -// -// sprintf(tmp, "

Page not found:

%s
%s



server:%s:%d\t\tpeer:%s:%d\n", heads->path, (heads->query?heads->query:""), serv_ip, ntohs(serveraddr.sin_port), peer_ip, ntohs(peeraddr.sin_port)); -//#ifdef _MSC_VER //Windows下需要转换编码 -// size_t ll = strlen(tmp); -// char *ch = GB2U8(tmp, &ll); -// tw_send_200_OK(client, "text/html", ch, -1, 0); -// free(ch); -//#else //linux 下,系统是和源代码文件编码都是是utf8的,就不需要转换 -// tw_send_200_OK(client, "text/html", tmp, -1, 0); -//#endif // _MSC_VER -// - printf(" sk:%zd Request:\n",pa->sk); - printf(" Query: %s\n",heads->query); - printf(" Path: %s\n",heads->path); - printf(" Host: %s\n",heads->host); - printf(" Cookie: %s\n", heads->cookie); - printf(" Range: %lld-%lld\n",heads->Range_frm,heads->Range_to); - printf(" data(%zd): %s\n", heads->len,heads->data); - if (!heads->cookie) - { - char ck[512]; - tw_make_setcookie(ck, 255,"TINYSSID","FDSAFdfafdsafds", 3600 * 8, NULL, heads->path); - tw_make_setcookie(ck + strlen(ck),255,"TINYSSID2","faFDSAF45dsafds", 0, heads->host, NULL); - sprintf(ck + strlen(ck), "WWW-Authenticate: Basic realm=\".\"\r\n"); - size_t len; - char* rp = tw_format_http_respone(client, "401 Unauthorized", ck, "text/plan", "", -1, &len); - tw_send_data(client, rp, len, 0, 1); - return 1; - } - return 0; -} - -char on_socket_data(void* data, uv_stream_t* client, tw_peerAddr* pa, membuf_t* buf) -{ - if (buf->size < 1) - return 1;//防止发生数据为空 - if (pa->flag & 0x2) { //WebSocket - printf((const char*)buf->data, buf->size < 256 ? buf->size : 256); - printf("-------------------------------------------ws:%zd dlen=%zd\n%s\n-------------------------------------------\n",pa->sk, buf->size, buf->data); - ulong len = buf->size; - char* p = WebSocketMakeFrame(buf->data, &len, 1);//文本帧 - tw_send_data(client, p, len, 0, 1); - } else { //Socket - printf("-------------------------------------------sk:%zd dlen=%zd\n%s\n-------------------------------------------\n",pa->sk, buf->size, buf->data); - tw_send_data(client, buf->data, buf->size, 1, 0); - } - return 1; -} - -char on_close(void* data, uv_stream_t* client, tw_peerAddr* pa) -{ - //printf("closed: sk=%zd [%s:%d] from:%s:%d cli:%d\n", pa->sk, pa->ip, pa->port, pa->fip, pa->fport, client->loop->active_tcp_streams); - return 0; -} - -char on_connect(void* data, uv_stream_t* client, tw_peerAddr* pa) -{ - //printf("connected: sk=%zd [%s:%d] from:%s:%d cli:%d\n",pa->sk,pa->ip,pa->port,pa->fip,pa->fport, client->loop->active_tcp_streams); - return 0; -} - -char on_error(void* data, uv_stream_t* client, tw_peerAddr* pa, int errcode, char* errstr) -{ - //printf("error: sk=%zd [%s:%d] from:%s:%d cli:%d %s\n", pa->sk, pa->ip, pa->port, pa->fip, pa->fport, client->loop->active_tcp_streams,errstr); - return 0; -} - -/*! ---------------------------------------------------------------------------- - * @fn WebServer - * - * @brief Constructor of the Web Server Object. - */ -WebServer::WebServer(void) -{ -} - -/*! ---------------------------------------------------------------------------- - * @fn ~WebServer - * - * @brief Destructor of the Web Server Object. - */ - -WebServer::~WebServer(void) -{ -} - -/*! ---------------------------------------------------------------------------- - * @fn setup - * - * @brief Setup the Web server - */ -int WebServer::setup(char *a_document_root, int a_port, uv_loop_t *an_evt_loop) -{ - memset(&m_conf, 0, sizeof(m_conf)); - m_conf.dirlist = 1;//目录列表 - //conf.ip = NULL;// "127.0.0.1"; - m_conf.port = a_port; - m_conf.doc_dir = a_document_root; - m_conf.doc_index = NULL;// Default homepage - //m_conf.doc_dir = NULL;// The directory where the default program files are located - - m_conf.on_request = on_request; - m_conf.on_data = on_socket_data; - m_conf.on_close = on_close; - m_conf.on_connect = on_connect; - m_conf.on_error = on_error; - - tinyweb_start(an_evt_loop, &m_conf); - return 0; -} diff --git a/src/web/web-server.h b/src/web/web-server.h deleted file mode 100644 index 438dd7e..0000000 --- a/src/web/web-server.h +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * web-server.h - * - * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * @Author: NADAL Jean-Baptiste - * @Date: 13/11/2019 - * - */ - -#ifndef _WEB_SERVER_H -#define _WEB_SERVER_H - -/*------------------------------- INCLUDES ----------------------------------*/ -#include -#include - -/*---------------------------------- Deps -----------------------------------*/ - -/*--------------------------------- CLASS ----------------------------------*/ - -class WebServer -{ -public: - WebServer(void); - ~WebServer(void); - - int setup(char *a_document_root, int a_port, uv_loop_t *an_evt_loop); - -private: - tw_config m_conf; -}; - -#endif /* __WEB_SERVER_H */