post example in test server
[platform/upstream/libwebsockets.git] / test-server / test.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4  <meta charset=utf-8 http-equiv="Content-Language" content="en"/>
5  <title>Minimal Websocket test app</title>
6 <style type="text/css">
7         span.title { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#000000; }
8         .browser { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#ffff00; vertical-align:middle; text-align:center; background:#d0b070; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px;}
9         .group2 { vertical-align:middle;
10                 text-align:center;
11                 background:#f0f0e0; 
12                 padding:12px; 
13                 -webkit-border-radius:10px; 
14                 -moz-border-radius:10px;
15                 border-radius:10px; }
16         .explain { vertical-align:middle;
17                 text-align:center;
18                 background:#f0f0c0; padding:12px;
19                 -webkit-border-radius:10px;
20                 -moz-border-radius:10px;
21                 border-radius:10px;
22                 color:#404000; }
23         td.wsstatus { vertical-align:middle; width:200px; height:50px;
24                 text-align:center;
25                 background:#f0f0c0; padding:6px;
26                 -webkit-border-radius:8px;
27                 -moz-border-radius:8px;
28                 border-radius:8px;
29                 color:#404000; }
30         td.l { vertical-align:middle;
31                 text-align:center;
32                 background:#d0d0b0; 
33                 padding:3px; 
34                 -webkit-border-radius:3px; 
35                 -moz-border-radius:3px;
36                 border-radius:3px; }
37         .content { vertical-align:top; text-align:center; background:#fffff0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
38         .canvas { vertical-align:top; text-align:center; background:#efefd0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
39 .tabs {
40   position: relative;   
41   min-height: 750px; /* This part sucks */
42   clear: both;
43   margin: 25px 0;
44 }
45 .tab {
46   float: left;
47 }
48 .tab label {
49   background: #eee; 
50   padding: 10px; 
51   border: 1px solid #ccc; 
52   margin-left: -1px; 
53   position: relative;
54   left: 1px; 
55 }
56 .tab [type=radio] {
57   display: none;   
58 }
59 .content {
60   position: absolute;
61   top: 28px;
62   left: 0;
63   background: white;
64   right: 0;
65   bottom: 0;
66   padding: 20px;
67   border: 1px solid #ccc; 
68 }
69 [type=radio]:checked ~ label {
70   background: white;
71   border-bottom: 1px solid white;
72   z-index: 2;
73 }
74 [type=radio]:checked ~ label ~ .content {
75   z-index: 1;
76 }
77 </style>
78 </head>
79
80 <body>
81 <header></header>
82 <article>
83
84 <table><tr><td>
85
86 <table width=600px>
87  <tr>
88   <td valign=middle align=center>
89    <a href="https://libwebsockets.org">
90     <img src="libwebsockets.org-logo.png"></a></td><td>
91         <section class="browser">Detected Browser: 
92         <div id=brow>...</div></section>
93   </td>
94  </tr>
95
96 </table>
97 </td></tr>
98 <tr><td colspan=2 align=center>
99 Click <a href="leaf.jpg" target="_blank">Here</a> to
100 have the test server send a big picture by http.
101 </td></tr>
102 <tr><td colspan=2>
103 <div class="tabs">
104
105    <div class="tab">
106        <input type="radio" id="tab-1" name="tab-group-1" checked>
107        <label for="tab-1">Dumb Increment Demo</label>
108        
109        <div class="content">
110         <div id="dumb" class="group2">
111          <table>
112           <tr>
113            <td id=wsdi_statustd align=center class="wsstatus">
114              <span id=wsdi_status>Websocket connection not initialized</span></td>
115            <td><span class="title">dumb increment-protocol</span></td>
116            </tr>
117            <tr>
118            <td class="explain" colspan=2>
119 The incrementing number is coming from the server at 20Hz and is individual for
120 each connection to the server... try opening a second browser window.
121 <br/><br/>
122 The button sends a message over the websocket link to ask the server
123 to zero just this connection's number.
124            </td>
125           </tr>
126            <tr>
127             <td align=center><div id=number style="font-size:120%;"> </div></td>
128             <td align=center>
129              <input type=button id=offset value="Reset counter" onclick="reset();" >
130              <input type=button id=junk value="Send junk" onclick="junk();" >
131             </td>
132             </tr>
133          </table>
134         </div>
135        </div> 
136    </div>
137
138    <div class="tab">
139     <input type="radio" id="tab-2" name="tab-group-1">
140     <label for="tab-2">Mirror Demo</label>
141        
142     <div class="content">
143      <div id="mirror" class="group2">
144       <table>
145        <tr>
146          <td colspan=1 id=wslm_statustd align=center class="wsstatus">
147          <span id=wslm_status>Websocket connection not initialized</span>
148         </td>
149         <td>
150          <span class="title">lws-mirror-protocol</span>
151         </td>
152        </tr>
153        <tr>
154        <td colspan=2>
155          <div class="explain">
156 Use the mouse to draw on the canvas below -- all other browser windows open
157 on this page see your drawing in realtime and you can see any of theirs as
158 well.
159 <br/><br/>
160 The lws-mirror protocol doesn't interpret what is being sent to it, it just
161 re-sends it to every other websocket it has a connection with using that
162 protocol, including the guy who sent the packet.
163 <br/><br/>
164 <b>libwebsockets-test-client</b> joins in by spamming circles on to this shared canvas when
165 run.
166          </div>
167         </td>
168        </tr>
169        <tr>
170         <td colspan=2>Drawing color:
171           <select id="color" onchange="update_color();">
172                 <option value=#000000>Black</option>
173                 <option value=#0000ff>Blue</option>
174                 <option value=#20ff20>Green</option>
175                 <option value=#802020>Dark Red</option>
176           </select>
177        </tr>
178        <tr>
179          <td colspan=2 width=500 height=320>
180                 <div id="wslm_drawing" style="background:white"></div>
181         </td>
182        </tr>
183       </table>
184      </div>
185     </div> 
186    </div>
187     
188     <div class="tab">
189        <input type="radio" id="tab-3" name="tab-group-1">
190        <label for="tab-3">Close Testing</label>
191      
192        <div class="content">
193 <div id="ot" class="group2">
194       <table>
195        <tr>
196         <td>
197
198                 </td></tr>
199                 <tr><td id=ot_statustd align=center class="wsstatus">
200                  <span id=ot_status>Websocket connection not initialized</span>
201                 </td>
202                 <td colspan=2><span class="title">Open and close testing</span></td>
203                 </tr>
204                 <tr>    
205 <td class="explain" colspan=3 style="padding:3">
206 To help with open and close testing, you can open and close a connection by hand using
207  the buttons.<br>
208  "<b>Close</b>" closes the connection from the browser with code 3000
209   and reason 'Bye!".<br>
210  "<b>Request Server Close</b>" sends a message asking the server to
211 initiate the close, which it does with code 1001 and reason "Seeya".
212 </td></tr>
213                 <tr>
214                 <td align=center><input type=button id=ot_open_btn value="Open" onclick="ot_open();" ></td>
215                 <td align=center><input type=button id=ot_close_btn disabled value="Close" onclick="ot_close();" ></td>
216                 <td align=center><input type=button id=ot_req_close_btn disabled value="Request Server Close" onclick="ot_req_close();" ></td>
217                 </tr>
218
219 </table>
220
221 </div>
222        </div> 
223    </div>
224    
225     <div class="tab">
226        <input type="radio" id="tab-4" name="tab-group-1">
227        <label for="tab-4">Server info</label>
228
229        <div class="content">
230 <div id="ot" class="group2">
231       <table>
232        <tr>
233         <td id=s_statustd align=center class="wsstatus">
234          <div id=s_status>Websocket connection not initialized</div>
235         </td>
236                 <td colspan=1>
237 <span class="title">Server Info</span>
238         </td>
239         </tr><tr>
240 <td class="explain" colspan=2>
241 This information is sent by the server over a ws[s] link and updated live
242 whenever the information changes server-side.
243 </td></tr>
244         <tr>
245         <td align=center colspan=2><div id=servinfo></div></td>
246         </tr>
247         <tr>
248         <td align=center colspan=2><div id=conninfo style="border : solid 2px #e0d040; padding : 4px; width : 500px; height : 350px; overflow : auto; "></</div></td>
249         </tr>
250 </table>
251 </div>
252        </div> 
253    </div>
254
255     <div class="tab">
256        <input type="radio" id="tab-5" name="tab-group-1">
257        <label for="tab-5">POST</label>
258
259        <div class="content">
260 <div id="ot" class="group2">
261       <table>
262        <tr>
263                 <td colspan=1>
264 <span class="title">POST Form testing</span>
265         </td>
266         </tr><tr>
267 <td class="explain" colspan=2>
268 This tests POST handling in lws.
269 </td></tr>
270         <tr>
271         <td align=center colspan=2><div id=postinfo>
272         <form action="formtest" method="post">
273   Some text:<br>
274   <input type="text" name="Text" value="Give me some text"><br>
275   <input type="submit" value="Send the form">
276         </form>
277         </div></td>
278         </tr>
279 </table>
280 </div>
281        </div> 
282    </div>
283
284 </div>
285 </td></tr></table>
286
287 Looking for support? <a href="https://libwebsockets.org">https://libwebsockets.org</a>, <a href="https://github.com/warmcat/libwebsockets">https://github.com/warmcat/libwebsockets</a></a><br/>
288 Join the mailing list: <a href="https://libwebsockets.org/mailman/listinfo/libwebsockets">https://libwebsockets.org/mailman/listinfo/libwebsockets</a>
289
290 </article>
291
292 <script>
293
294 /*
295  * We display untrusted stuff in html context... reject anything
296  * that has HTML stuff in it
297  */
298
299 function san(s)
300 {
301         if (s.search("<") != -1)
302                 return "invalid string";
303         
304         return s;
305 }
306
307 /* BrowserDetect came from http://www.quirksmode.org/js/detect.html */
308
309 var BrowserDetect = {
310         init: function () {
311                 this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
312                 this.version = this.searchVersion(navigator.userAgent)
313                         || this.searchVersion(navigator.appVersion)
314                         || "an unknown version";
315                 this.OS = this.searchString(this.dataOS) || "an unknown OS";
316         },
317         searchString: function (data) {
318                 for (var i=0;i<data.length;i++) {
319                         var dataString = data[i].string;
320                         var dataProp = data[i].prop;
321                         this.versionSearchString = data[i].versionSearch || data[i].identity;
322                         if (dataString) {
323                                 if (dataString.indexOf(data[i].subString) != -1)
324                                         return data[i].identity;
325                         }
326                         else if (dataProp)
327                                 return data[i].identity;
328                 }
329         },
330         searchVersion: function (dataString) {
331                 var index = dataString.indexOf(this.versionSearchString);
332                 if (index == -1) return;
333                 return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
334         },
335         dataBrowser: [
336                 {
337                         string: navigator.userAgent,
338                         subString: "Chrome",
339                         identity: "Chrome"
340                 },
341                 {       string: navigator.userAgent,
342                         subString: "OmniWeb",
343                         versionSearch: "OmniWeb/",
344                         identity: "OmniWeb"
345                 },
346                 {
347                         string: navigator.vendor,
348                         subString: "Apple",
349                         identity: "Safari",
350                         versionSearch: "Version"
351                 },
352                 {
353                         prop: window.opera,
354                         identity: "Opera",
355                         versionSearch: "Version"
356                 },
357                 {
358                         string: navigator.vendor,
359                         subString: "iCab",
360                         identity: "iCab"
361                 },
362                 {
363                         string: navigator.vendor,
364                         subString: "KDE",
365                         identity: "Konqueror"
366                 },
367                 {
368                         string: navigator.userAgent,
369                         subString: "Firefox",
370                         identity: "Firefox"
371                 },
372                 {
373                         string: navigator.vendor,
374                         subString: "Camino",
375                         identity: "Camino"
376                 },
377                 {               // for newer Netscapes (6+)
378                         string: navigator.userAgent,
379                         subString: "Netscape",
380                         identity: "Netscape"
381                 },
382                 {
383                         string: navigator.userAgent,
384                         subString: "MSIE",
385                         identity: "Explorer",
386                         versionSearch: "MSIE"
387                 },
388                 {
389                         string: navigator.userAgent,
390                         subString: "Gecko",
391                         identity: "Mozilla",
392                         versionSearch: "rv"
393                 },
394                 {               // for older Netscapes (4-)
395                         string: navigator.userAgent,
396                         subString: "Mozilla",
397                         identity: "Netscape",
398                         versionSearch: "Mozilla"
399                 }
400         ],
401         dataOS : [
402                 {
403                         string: navigator.platform,
404                         subString: "Win",
405                         identity: "Windows"
406                 },
407                 {
408                         string: navigator.platform,
409                         subString: "Mac",
410                         identity: "Mac"
411                 },
412                 {
413                            string: navigator.userAgent,
414                            subString: "iPhone",
415                            identity: "iPhone/iPod"
416             },
417                 {
418                         string: navigator.platform,
419                         subString: "Linux",
420                         identity: "Linux"
421                 }
422         ]
423
424 };
425 BrowserDetect.init();
426
427 document.getElementById("brow").textContent = " " + BrowserDetect.browser + " "
428         + BrowserDetect.version +" " + BrowserDetect.OS +" ";
429
430         var pos = 0;
431
432 function get_appropriate_ws_url()
433 {
434         var pcol;
435         var u = document.URL;
436
437         /*
438          * We open the websocket encrypted if this page came on an
439          * https:// url itself, otherwise unencrypted
440          */
441
442         if (u.substring(0, 5) == "https") {
443                 pcol = "wss://";
444                 u = u.substr(8);
445         } else {
446                 pcol = "ws://";
447                 if (u.substring(0, 4) == "http")
448                         u = u.substr(7);
449         }
450
451         u = u.split('/');
452
453         /* + "/xxx" bit is for IE10 workaround */
454
455         return pcol + u[0] + "/xxx";
456 }
457
458
459 document.getElementById("number").textContent = get_appropriate_ws_url();
460
461 /* dumb increment protocol */
462         
463         var socket_di;
464
465         if (typeof MozWebSocket != "undefined") {
466                 socket_di = new MozWebSocket(get_appropriate_ws_url(),
467                                    "dumb-increment-protocol");
468         } else {
469                 socket_di = new WebSocket(get_appropriate_ws_url(),
470                                    "dumb-increment-protocol");
471         }
472
473
474         try {
475                 socket_di.onopen = function() {
476                         document.getElementById("wsdi_statustd").style.backgroundColor = "#40ff40";
477                         document.getElementById("wsdi_status").innerHTML =
478                                 " <b>websocket connection opened</b><br>" +
479                                 san(socket_di.extensions);
480                 } 
481
482                 socket_di.onmessage =function got_packet(msg) {
483                         document.getElementById("number").textContent = msg.data + "\n";
484                 } 
485
486                 socket_di.onclose = function(){
487                         document.getElementById("wsdi_statustd").style.backgroundColor = "#ff4040";
488                         document.getElementById("wsdi_status").textContent = " websocket connection CLOSED ";
489                 }
490         } catch(exception) {
491                 alert('<p>Error' + exception);  
492         }
493         
494         var socket_status, jso, s;
495
496         if (typeof MozWebSocket != "undefined") {
497                 socket_status = new MozWebSocket(get_appropriate_ws_url(),
498                                    "lws-status");
499         } else {
500                 socket_status = new WebSocket(get_appropriate_ws_url(),
501                                    "lws-status");
502         }
503
504
505         try {
506                 socket_status.onopen = function() {
507                         document.getElementById("s_statustd").style.backgroundColor = "#40ff40";
508                         document.getElementById("s_status").innerHTML =
509                                 " <b>websocket connection opened</b><br>" +
510                                 san(socket_status.extensions);
511                 } 
512
513                 socket_status.onmessage =function got_packet(msg) {
514                         jso = JSON.parse(msg.data);
515                         
516                         document.getElementById("servinfo").innerHTML = 
517                                 "<table><tr><td class=l>Build info</td><td>"+
518                                         san(jso.version) + "</td></tr>" +
519                                         "<tr><td class=l>Server info</td><td>" +
520                                         san(jso.hostname) + "</td></tr>" +
521                                         "</table>";
522                         s="<table>";
523                         var n;
524                         for (n = 0; n < jso.conns.length; n++)
525                                 s = s + "<tr><td class=l>client " + (n + 1) +
526                                 "</td><td><b>" + san(jso.conns[n].peer) +
527                                 "</b><br>" + san(jso.conns[n].time) +
528                                 "<br>" + san(jso.conns[n].ua) +
529                                 "</td></tr>";
530                         s = s + "</table>";
531                         
532                         document.getElementById("conninfo").innerHTML = s;
533                 } 
534
535                 socket_status.onclose = function(){
536                         document.getElementById("s_statustd").style.backgroundColor = "#ff4040";
537                         document.getElementById("s_status").textContent = " websocket connection CLOSED ";
538                 }
539         } catch(exception) {
540                 alert('<p>Error' + exception);  
541         }
542
543 function reset() {
544         socket_di.send("reset\n");
545 }
546
547
548 function junk() {
549         for(var word = ''; word.length < 9000; word += 'a'){}
550         socket_di.send(word);
551 }
552
553 var socket_ot;
554
555 function ot_open() {
556         if (typeof MozWebSocket != "undefined") {
557                 socket_ot = new MozWebSocket(get_appropriate_ws_url(),
558                                    "dumb-increment-protocol");
559         } else {
560                 socket_ot = new WebSocket(get_appropriate_ws_url(),
561                                    "dumb-increment-protocol");
562         }
563         try {
564                 socket_ot.onopen = function() {
565                         document.getElementById("ot_statustd").style.backgroundColor = "#40ff40";
566                         document.getElementById("ot_status").innerHTML = " <b>websocket connection opened</b><br>" + san(socket_di.extensions);
567                         document.getElementById("ot_open_btn").disabled = true;
568                         document.getElementById("ot_close_btn").disabled = false;
569                         document.getElementById("ot_req_close_btn").disabled = false;
570                 } 
571
572                 socket_ot.onclose = function(e){
573                         document.getElementById("ot_statustd").style.backgroundColor = "#ff4040";
574                         document.getElementById("ot_status").textContent = " websocket connection CLOSED, code: " + e.code +
575                         ", reason: " + e.reason;
576                         document.getElementById("ot_open_btn").disabled = false;
577                         document.getElementById("ot_close_btn").disabled = true;
578                         document.getElementById("ot_req_close_btn").disabled = true;
579                 }
580         } catch(exception) {
581                 alert('<p>Error' + exception);  
582         }
583 }
584
585 /* browser will close the ws in a controlled way */
586 function ot_close() {
587         socket_ot.close(3000, "Bye!");
588 }
589
590 /* we ask the server to close the ws in a controlled way */
591 function ot_req_close() {
592         socket_ot.send("closeme\n");
593 }
594
595 /* lws-mirror protocol */
596
597         var down = 0;
598         var no_last = 1;
599         var last_x = 0, last_y = 0;
600         var ctx;
601         var socket_lm;
602         var color = "#000000";
603
604         if (typeof MozWebSocket != "undefined") {
605                 socket_lm = new MozWebSocket(get_appropriate_ws_url(),
606                                    "lws-mirror-protocol");
607         } else {
608                 socket_lm = new WebSocket(get_appropriate_ws_url(),
609                                    "lws-mirror-protocol");
610         }
611
612
613         try {
614                 socket_lm.onopen = function() {
615                         document.getElementById("wslm_statustd").style.backgroundColor = "#40ff40";
616                         document.getElementById("wslm_status").innerHTML =
617                                 " <b>websocket connection opened</b><br>" +
618                                 san(socket_lm.extensions);
619                 } 
620
621                 socket_lm.onmessage =function got_packet(msg) {
622                         j = msg.data.split(';');
623                         f = 0;
624                         while (f < j.length - 1) {
625                                 i = j[f].split(' ');
626                                 if (i[0] == 'd') {
627                                         ctx.strokeStyle = i[1];
628                                         ctx.beginPath();
629                                         ctx.moveTo(+(i[2]), +(i[3]));
630                                         ctx.lineTo(+(i[4]), +(i[5]));
631                                         ctx.stroke();
632                                 }
633                                 if (i[0] == 'c') {
634                                         ctx.strokeStyle = i[1];
635                                         ctx.beginPath();
636                                         ctx.arc(+(i[2]), +(i[3]), +(i[4]), 0, Math.PI*2, true); 
637                                         ctx.stroke();
638                                 }
639
640                                 f++;
641                         }
642                 }
643
644                 socket_lm.onclose = function(){
645                         document.getElementById("wslm_statustd").style.backgroundColor = "#ff4040";
646                         document.getElementById("wslm_status").textContent = " websocket connection CLOSED ";
647                 }
648         } catch(exception) {
649                 alert('<p>Error' + exception);  
650         }
651
652         var canvas = document.createElement('canvas');
653         canvas.height = 300;
654         canvas.width = 480;
655         ctx = canvas.getContext("2d");
656
657         document.getElementById('wslm_drawing').appendChild(canvas);
658
659         canvas.addEventListener('mousemove', ev_mousemove, false);
660         canvas.addEventListener('mousedown', ev_mousedown, false);
661         canvas.addEventListener('mouseup', ev_mouseup, false);
662
663         offsetX = offsetY = 0;
664         element = canvas;
665       if (element.offsetParent) {
666         do {
667           offsetX += element.offsetLeft;
668           offsetY += element.offsetTop;
669         } while ((element = element.offsetParent));
670       }
671  
672 function update_color() {
673         color = document.getElementById("color").value;
674 }
675
676 function ev_mousedown (ev) {
677         down = 1;
678 }
679
680 function ev_mouseup(ev) {
681         down = 0;
682         no_last = 1;
683 }
684
685 function ev_mousemove (ev) {
686         var x, y;
687
688         if (ev.offsetX) {
689                 x = ev.offsetX;
690                 y = ev.offsetY;
691         } else {
692                 x = ev.layerX - offsetX;
693                 y = ev.layerY - offsetY;
694
695         }
696
697         if (!down)
698                 return;
699         if (no_last) {
700                 no_last = 0;
701                 last_x = x;
702                 last_y = y;
703                 return;
704         }
705         socket_lm.send("d " + color + " " + last_x + " " + last_y + " " + x + ' ' + y + ';');
706
707         last_x = x;
708         last_y = y;
709 }
710
711
712 </script>
713
714 </body>
715 </html>