1
0
mirror of https://github.com/fcwu/docker-ubuntu-vnc-desktop synced 2026-08-05 16:12:41 +02:00

refactor: code structure

1. move folders from /usr/* to /usr/local/*
2. supervisord controls everything
This commit is contained in:
Doro Wu
2018-03-13 16:42:22 +08:00
parent 9e608482c8
commit f5da5d152f
232 changed files with 41 additions and 45 deletions
@@ -0,0 +1,147 @@
<html>
<head>
<title>WebSockets Echo Test</title>
<script src="include/util.js"></script>
<script src="include/webutil.js"></script>
<script src="include/websock.js"></script>
<!-- Uncomment to activate firebug lite -->
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
</head>
<body>
Host: <input id='host' style='width:100'>&nbsp;
Port: <input id='port' style='width:50'>&nbsp;
Encrypt: <input id='encrypt' type='checkbox'>&nbsp;
<input id='connectButton' type='button' value='Start' style='width:100px'
onclick="connect();">&nbsp;
<br>
Log:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
</body>
<script>
var ws, host = null, port = null,
msg_cnt = 0, send_cnt = 1, echoDelay = 500,
echo_ref;
function message(str) {
console.log(str);
cell = $D('messages');
cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
msg_cnt++;
}
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i < n; i++) {
this.push(str.charCodeAt(i));
}
}
function send_msg() {
var str = "Message #" + send_cnt;
ws.send_string(str);
message("Sent message: '" + str + "'");
send_cnt++;
}
function update_stats() {
$D('sent').innerHTML = sent;
$D('received').innerHTML = received;
$D('errors').innerHTML = errors;
}
function connect() {
var host = $D('host').value,
port = $D('port').value,
scheme = "ws://", uri;
console.log(">> connect");
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
if ($D('encrypt').checked) {
scheme = "wss://";
}
uri = scheme + host + ":" + port;
message("connecting to " + uri);
ws = new Websock();
ws.open(uri);
ws.on('message', function(e) {
//console.log(">> WebSockets.onmessage");
var str = ws.rQshiftStr();
message("Received message '" + str + "'");
//console.log("<< WebSockets.onmessage");
});
ws.on('open', function(e) {
console.log(">> WebSockets.onopen");
echo_ref = setInterval(send_msg, echoDelay);
console.log("<< WebSockets.onopen");
});
ws.on('close', function(e) {
console.log(">> WebSockets.onclose");
if (echo_ref) {
clearInterval(echo_ref);
echo_ref = null;
}
console.log("<< WebSockets.onclose");
});
ws.on('error', function(e) {
console.log(">> WebSockets.onerror");
if (echo_ref) {
clearInterval(echo_ref);
echo_ref = null;
}
console.log("<< WebSockets.onerror");
});
$D('connectButton').value = "Stop";
$D('connectButton').onclick = disconnect;
console.log("<< connect");
}
function disconnect() {
console.log(">> disconnect");
if (ws) {
ws.close();
}
if (echo_ref) {
clearInterval(echo_ref);
}
$D('connectButton').value = "Start";
$D('connectButton').onclick = connect;
console.log("<< disconnect");
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = (url.match(/host=([^&#]*)/) || ['',window.location.hostname])[1];
$D('port').value = (url.match(/port=([^&#]*)/) || ['',window.location.port])[1];
}
</script>
</html>
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python
'''
A WebSocket server that echos back whatever it receives from the client.
Copyright 2010 Joel Martin
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
You can make a cert/key with openssl using:
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
as taken from http://docs.python.org/dev/library/ssl.html#certificates
'''
import os, sys, select, optparse, logging
sys.path.insert(0,os.path.join(os.path.dirname(__file__), ".."))
from websockify.websockifyserver import WebSockifyServer, WebSockifyRequestHandler
class WebSocketEcho(WebSockifyRequestHandler):
"""
WebSockets server that echos back whatever is received from the
client. """
buffer_size = 8096
def new_websocket_client(self):
"""
Echo back whatever is received.
"""
cqueue = []
c_pend = 0
cpartial = ""
rlist = [self.request]
while True:
wlist = []
if cqueue or c_pend: wlist.append(self.request)
ins, outs, excepts = select.select(rlist, wlist, [], 1)
if excepts: raise Exception("Socket exception")
if self.request in outs:
# Send queued target data to the client
c_pend = self.send_frames(cqueue)
cqueue = []
if self.request in ins:
# Receive client data, decode it, and send it back
frames, closed = self.recv_frames()
cqueue.extend(frames)
if closed:
break
if __name__ == '__main__':
parser = optparse.OptionParser(usage="%prog [options] listen_port")
parser.add_option("--verbose", "-v", action="store_true",
help="verbose messages and per frame traffic")
parser.add_option("--cert", default="self.pem",
help="SSL certificate file")
parser.add_option("--key", default=None,
help="SSL key file (if separate from cert)")
parser.add_option("--ssl-only", action="store_true",
help="disallow non-encrypted connections")
(opts, args) = parser.parse_args()
try:
if len(args) != 1: raise
opts.listen_port = int(args[0])
except:
parser.error("Invalid arguments")
logging.basicConfig(level=logging.INFO)
opts.web = "."
server = WebSockifyServer(WebSocketEcho, **opts.__dict__)
server.start_server()
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env ruby
# A WebSocket server that echos back whatever it receives from the client.
# Copyright 2011 Joel Martin
# Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
require 'socket'
$: << "other"
$: << "../other"
require 'websocket'
class WebSocketEcho < WebSocketServer
# Echo back whatever is received
def new_websocket_client(client)
cqueue = []
c_pend = 0
rlist = [client]
loop do
wlist = []
if cqueue.length > 0 or c_pend
wlist << client
end
ins, outs, excepts = IO.select(rlist, wlist, nil, 1)
if excepts.length > 0
raise Exception, "Socket exception"
end
if outs.include?(client)
# Send queued data to the client
c_pend = send_frames(cqueue)
cqueue = []
end
if ins.include?(client)
# Receive client data, decode it, and send it back
frames, closed = recv_frames
cqueue += frames
if closed
raise EClose, closed
end
end
end # loop
end
end
port = ARGV[0].to_i || 8080
puts "Starting server on port #{port}"
server_cert = nil
server_key = nil
if ARGV.length > 2
server_cert = ARGV[1]
server_key = ARGV[2]
end
server = WebSocketEcho.new('listen_port' => port, 'verbose' => true,
'server_cert' => server_cert, 'server_key' => server_key)
server.start
server.join
puts "Server has been terminated"
# vim: sw=2
@@ -0,0 +1,70 @@
#!/usr/bin/env python
import os
import sys
import optparse
import select
sys.path.insert(0,os.path.join(os.path.dirname(__file__), ".."))
from websockify.websocket import WebSocket, \
WebSocketWantReadError, WebSocketWantWriteError
parser = optparse.OptionParser(usage="%prog URL")
(opts, args) = parser.parse_args()
try:
if len(args) != 1: raise
URL = args[0]
except:
parser.error("Invalid arguments")
sock = WebSocket()
print("Connecting to %s..." % URL)
sock.connect(URL)
print("Connected.")
def send(msg):
while True:
try:
sock.sendmsg(msg)
break
except WebSocketWantReadError:
msg = ''
ins, outs, excepts = select.select([sock], [], [])
if excepts: raise Exception("Socket exception")
except WebSocketWantWriteError:
msg = ''
ins, outs, excepts = select.select([], [sock], [])
if excepts: raise Exception("Socket exception")
def read():
while True:
try:
return sock.recvmsg()
except WebSocketWantReadError:
ins, outs, excepts = select.select([sock], [], [])
if excepts: raise Exception("Socket exception")
except WebSocketWantWriteError:
ins, outs, excepts = select.select([], [sock], [])
if excepts: raise Exception("Socket exception")
counter = 1
while True:
msg = "Message #%d" % counter
counter += 1
send(msg)
print("Sent message: %r" % msg)
while True:
ins, outs, excepts = select.select([sock], [], [], 1.0)
if excepts: raise Exception("Socket exception")
if ins == []:
break
while True:
msg = read()
print("Received message: %r" % msg)
if not sock.pending():
break
@@ -0,0 +1 @@
../include
@@ -0,0 +1,272 @@
<html>
<head>
<title>WebSockets Latency Test</title>
<script src="include/util.js"></script>
<script src="include/webutil.js"></script>
<script src="include/websock.js"></script>
<!-- Uncomment to activate firebug lite -->
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
</head>
<body>
Host: <input id='host' style='width:100'>&nbsp;
Port: <input id='port' style='width:50'>&nbsp;
Encrypt: <input id='encrypt' type='checkbox'>
<br>
Payload Size: <input id='payload_size' style='width:50'>&nbsp;
Send Delay (ms): <input id='sendDelay' style='width:50' value="10">&nbsp;
<input id='connectButton' type='button' value='Start' style='width:100px'
onclick="connect();">&nbsp;
<br><br>
<table border=1>
<tr>
<th align="right">Packets sent:</th>
<td align="right"><div id='sent'></div></td>
</tr><tr>
<th align="right">Packets Received:</th>
<td align="right"><div id='received'></div></td>
</tr><tr>
<th align="right">Average Latency:</th>
<td align="right"><div id='laverage'></div></td>
</tr><tr>
<th align="right">40 Frame Running Average Latency:</th>
<td align="right"><div id='lrunning'></div></td>
</tr><tr>
<th align="right">Minimum Latency:</th>
<td align="right"><div id='lmin'></div></td>
</tr><tr>
<th align="right">Maximum Latency:</th>
<td align="right"><div id='lmax'></div></td>
</tr>
</table>
<br>
Messages:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=10></textarea>
</body>
<script>
var host = null, port = null, sendDelay = 0,
ws = null, send_ref = null,
sent, received, latencies, ltotal, laverage, lrunning, lmin, lmax,
run_length = 40,
payload_size = 2000, payload,
msg_cnt = 0, recv_seq = 0, send_seq = 0;
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i < n; i++) {
this.push(str.charCodeAt(i));
}
}
function message(str) {
console.log(str);
cell = $D('messages');
msg_cnt++;
cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
}
function add (x,y) {
return parseInt(x,10)+parseInt(y,10);
}
function recvMsg(data) {
//console.log(">> check_respond");
var i, now, arr, first, last, arr, latency;
now = (new Date()).getTime(); // Early as possible
arr = ws.rQshiftBytes(ws.rQlen());
first = String.fromCharCode(arr[0]);
last = String.fromCharCode(arr[arr.length-1]);
if (first != "^") {
message("Error: packet missing start char '^'");
disconnect();
return;
}
if (last != "$") {
message("Error: packet missing end char '$'");
disconnect();
return;
}
text = ''
for (var i = 1; i < arr.length-1; i++) {
text += String.fromCharCode(arr[i]);
}
arr = text.split(':');
seq = arr[0];
timestamp = parseInt(arr[1],10);
rpayload = arr[2];
if (seq != recv_seq) {
message("Error: expected seq " + recv_seq + " but got " + seq);
disconnect();
return;
}
recv_seq++;
if (payload !== rpayload) {
message("Payload corrupt");
disconnect();
return;
}
received++;
latency = now - timestamp;
latencies.push(latency);
if (latencies.length > run_length) {
latencies.shift();
}
ltotal += latency;
laverage = ltotal / received;
lrunning = 0;
for (var i=0; i < latencies.length; i++) {
lrunning += latencies[i];
}
lrunning = lrunning / latencies.length;
if (latency < lmin) {
lmin = latency;
}
if (latency > lmax) {
lmax = latency;
}
showStats();
//console.log("<< check_respond");
}
function sendMsg() {
var arr = [];
timestamp = (new Date()).getTime();
arr.pushStr("^" + send_seq + ":" + timestamp + ":" + payload + "$");
send_seq ++;
ws.send(arr);
sent++;
showStats();
send_ref = setTimeout(sendMsg, sendDelay);
}
function showStats() {
$D('sent').innerHTML = sent;
$D('received').innerHTML = received;
$D('laverage').innerHTML = laverage.toFixed(2);
$D('lrunning').innerHTML = lrunning.toFixed(2);
$D('lmin').innerHTML = lmin.toFixed(2);
$D('lmax').innerHTML = lmax.toFixed(2);
}
function init_ws() {
console.log(">> init_ws");
var scheme = "ws://";
if ($D('encrypt').checked) {
scheme = "wss://";
}
var uri = scheme + host + ":" + port;
console.log("connecting to " + uri);
ws = new Websock();
ws.maxBufferedAmount = 5000;
ws.open(uri);
ws.on('message', function() {
recvMsg();
});
ws.on('open', function() {
send_ref = setTimeout(sendMsg, sendDelay);
});
ws.on('close', function(e) {
disconnect();
});
ws.on('error', function(e) {
message("Websock error: " + e);
disconnect();
});
console.log("<< init_ws");
}
function connect() {
console.log(">> connect");
host = $D('host').value;
port = $D('port').value;
payload_size = parseInt($D('payload_size').value, 10);
sendDelay = parseInt($D('sendDelay').value, 10);
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
init_ws();
// Populate payload data
var numlist = []
for (var i=0; i < payload_size; i++) {
numlist.push( Math.floor(Math.random()*10) );
}
payload = numlist.join('');
// Initialize stats
sent = 0;
received = 0;
latencies = [];
ltotal = 0;
laverage = 0;
lrunning = 0;
lmin = 999999999;
lmax = 0;
$D('connectButton').value = "Stop";
$D('connectButton').onclick = disconnect;
console.log("<< connect");
}
function disconnect() {
console.log(">> disconnect");
if (ws) {
ws.close();
}
if (send_ref) {
clearInterval(send_ref);
send_ref = null;
}
showStats(); // Final numbers
recv_seq = 0;
send_seq = 0;
$D('connectButton').value = "Start";
$D('connectButton').onclick = connect;
console.log("<< disconnect");
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = (url.match(/host=([^&#]*)/) || ['',window.location.hostname])[1];
$D('port').value = (url.match(/port=([^&#]*)/) || ['',window.location.port])[1];
$D('payload_size').value = payload_size;
}
</script>
</html>
@@ -0,0 +1 @@
echo.py
@@ -0,0 +1,231 @@
<html>
<head>
<title>WebSockets Load Test</title>
<script src="include/util.js"></script>
<script src="include/webutil.js"></script>
<script src="include/websock.js"></script>
<!-- Uncomment to activate firebug lite -->
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
</head>
<body>
Host: <input id='host' style='width:100'>&nbsp;
Port: <input id='port' style='width:50'>&nbsp;
Encrypt: <input id='encrypt' type='checkbox'>&nbsp;
Send Delay (ms): <input id='sendDelay' style='width:50' value="100">&nbsp;
<input id='connectButton' type='button' value='Start' style='width:100px'
onclick="connect();">&nbsp;
<br><br>
<table border=1>
<tr>
<th align="right">Packets sent:</th>
<td align="right"><div id='sent'>0</div></td>
</tr><tr>
<th align="right">Good Packets Received:</th>
<td align="right"><div id='received'>0</div></td>
</tr><tr>
<th align="right">Errors (Bad Packets Received:)</th>
<td align="right"><div id='errors'>0</div></td>
</tr>
</table>
<br>
Errors:<br>
<textarea id="error" style="font-size: 9;" cols=80 rows=25></textarea>
</body>
<script>
function error(str) {
console.error(str);
cell = $D('error');
cell.innerHTML += errors + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
}
var host = null, port = null, sendDelay = 0;
var ws = null, update_ref = null, send_ref = null;
var sent = 0, received = 0, errors = 0;
var max_send = 2000;
var recv_seq = 0, send_seq = 0;
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i < n; i++) {
this.push(str.charCodeAt(i));
}
}
function add (x,y) {
return parseInt(x,10)+parseInt(y,10);
}
function check_respond(data) {
//console.log(">> check_respond");
var first, last, str, length, chksum, nums, arr;
first = String.fromCharCode(data.shift());
last = String.fromCharCode(data.pop());
if (first != "^") {
errors++;
error("Packet missing start char '^'");
return;
}
if (last != "$") {
errors++;
error("Packet missing end char '$'");
return;
}
arr = data.map(function(num) {
return String.fromCharCode(num);
} ).join('').split(':');
seq = arr[0];
length = arr[1];
chksum = arr[2];
nums = arr[3];
//console.log(" length:" + length + " chksum:" + chksum + " nums:" + nums);
if (seq != recv_seq) {
errors++;
error("Expected seq " + recv_seq + " but got " + seq);
recv_seq = parseInt(seq,10) + 1; // Back on track
return;
}
recv_seq++;
if (nums.length != length) {
errors++;
error("Expected length " + length + " but got " + nums.length);
return;
}
//real_chksum = nums.reduce(add);
real_chksum = 0;
for (var i=0; i < nums.length; i++) {
real_chksum += parseInt(nums.charAt(i), 10);
}
if (real_chksum != chksum) {
errors++
error("Expected chksum " + chksum + " but real chksum is " + real_chksum);
return;
}
received++;
//console.log(" Packet checks out: length:" + length + " chksum:" + chksum);
//console.log("<< check_respond");
}
function send() {
var length = Math.floor(Math.random()*(max_send-9)) + 10; // 10 - max_send
var numlist = [], arr = [];
for (var i=0; i < length; i++) {
numlist.push( Math.floor(Math.random()*10) );
}
//chksum = numlist.reduce(add);
chksum = 0;
for (var i=0; i < numlist.length; i++) {
chksum += parseInt(numlist[i], 10);
}
var nums = numlist.join('');
arr.pushStr("^" + send_seq + ":" + length + ":" + chksum + ":" + nums + "$")
send_seq ++;
ws.send(arr);
sent++;
}
function update_stats() {
$D('sent').innerHTML = sent;
$D('received').innerHTML = received;
$D('errors').innerHTML = errors;
}
function init_ws() {
console.log(">> init_ws");
var scheme = "ws://";
if ($D('encrypt').checked) {
scheme = "wss://";
}
var uri = scheme + host + ":" + port;
console.log("connecting to " + uri);
ws = new Websock();
ws.open(uri);
ws.on('message', function() {
//console.log(">> WebSockets.onmessage");
arr = ws.rQshiftBytes(ws.rQlen());
check_respond(arr);
//console.log("<< WebSockets.onmessage");
});
ws.on('open', function() {
console.log(">> WebSockets.onopen");
send_ref = setInterval(send, sendDelay);
console.log("<< WebSockets.onopen");
});
ws.on('close', function(e) {
console.log(">> WebSockets.onclose");
clearInterval(send_ref);
console.log("<< WebSockets.onclose");
});
ws.on('error', function(e) {
console.log(">> WebSockets.onerror");
console.log(" " + e);
console.log("<< WebSockets.onerror");
});
console.log("<< init_ws");
}
function connect() {
console.log(">> connect");
host = $D('host').value;
port = $D('port').value;
sendDelay = parseInt($D('sendDelay').value, 10);
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
init_ws();
update_ref = setInterval(update_stats, 1);
$D('connectButton').value = "Stop";
$D('connectButton').onclick = disconnect;
console.log("<< connect");
}
function disconnect() {
console.log(">> disconnect");
if (ws) {
ws.close();
}
clearInterval(update_ref);
update_stats(); // Final numbers
recv_seq = 0;
send_seq = 0;
$D('connectButton').value = "Start";
$D('connectButton').onclick = connect;
console.log("<< disconnect");
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
$D('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
}
</script>
</html>
+168
View File
@@ -0,0 +1,168 @@
#!/usr/bin/env python
'''
WebSocket server-side load test program. Sends and receives traffic
that has a random payload (length and content) that is checksummed and
given a sequence number. Any errors are reported and counted.
'''
import sys, os, select, random, time, optparse, logging
sys.path.insert(0,os.path.join(os.path.dirname(__file__), ".."))
from websockify.websockifyserver import WebSockifyServer, WebSockifyRequestHandler
class WebSocketLoadServer(WebSockifyServer):
recv_cnt = 0
send_cnt = 0
def __init__(self, *args, **kwargs):
self.delay = kwargs.pop('delay')
WebSockifyServer.__init__(self, *args, **kwargs)
class WebSocketLoad(WebSockifyRequestHandler):
max_packet_size = 10000
def new_websocket_client(self):
print "Prepopulating random array"
self.rand_array = []
for i in range(0, self.max_packet_size):
self.rand_array.append(random.randint(0, 9))
self.errors = 0
self.send_cnt = 0
self.recv_cnt = 0
self.responder(self.request)
print "accumulated errors:", self.errors
self.errors = 0
def responder(self, client):
c_pend = 0
cqueue = []
cpartial = ""
socks = [client]
last_send = time.time() * 1000
while True:
ins, outs, excepts = select.select(socks, socks, socks, 1)
if excepts: raise Exception("Socket exception")
if client in ins:
frames, closed = self.recv_frames()
err = self.check(frames)
if err:
self.errors = self.errors + 1
print err
if closed:
break
now = time.time() * 1000
if client in outs:
if c_pend:
last_send = now
c_pend = self.send_frames()
elif now > (last_send + self.server.delay):
last_send = now
c_pend = self.send_frames([self.generate()])
def generate(self):
length = random.randint(10, self.max_packet_size)
numlist = self.rand_array[self.max_packet_size-length:]
# Error in length
#numlist.append(5)
chksum = sum(numlist)
# Error in checksum
#numlist[0] = 5
nums = "".join( [str(n) for n in numlist] )
data = "^%d:%d:%d:%s$" % (self.send_cnt, length, chksum, nums)
self.send_cnt += 1
return data
def check(self, frames):
err = ""
for data in frames:
if data.count('$') > 1:
raise Exception("Multiple parts within single packet")
if len(data) == 0:
self.traffic("_")
continue
if data[0] != "^":
err += "buf did not start with '^'\n"
continue
try:
cnt, length, chksum, nums = data[1:-1].split(':')
cnt = int(cnt)
length = int(length)
chksum = int(chksum)
except:
print "\n<BOF>" + repr(data) + "<EOF>"
err += "Invalid data format\n"
continue
if self.recv_cnt != cnt:
err += "Expected count %d but got %d\n" % (self.recv_cnt, cnt)
self.recv_cnt = cnt + 1
continue
self.recv_cnt += 1
if len(nums) != length:
err += "Expected length %d but got %d\n" % (length, len(nums))
continue
inv = nums.translate(None, "0123456789")
if inv:
err += "Invalid characters found: %s\n" % inv
continue
real_chksum = 0
for num in nums:
real_chksum += int(num)
if real_chksum != chksum:
err += "Expected checksum %d but real chksum is %d\n" % (chksum, real_chksum)
return err
if __name__ == '__main__':
parser = optparse.OptionParser(usage="%prog [options] listen_port")
parser.add_option("--verbose", "-v", action="store_true",
help="verbose messages and per frame traffic")
parser.add_option("--cert", default="self.pem",
help="SSL certificate file")
parser.add_option("--key", default=None,
help="SSL key file (if separate from cert)")
parser.add_option("--ssl-only", action="store_true",
help="disallow non-encrypted connections")
(opts, args) = parser.parse_args()
try:
if len(args) != 1: raise
opts.listen_port = int(args[0])
if len(args) not in [1,2]: raise
opts.listen_port = int(args[0])
if len(args) == 2:
opts.delay = int(args[1])
else:
opts.delay = 10
except:
parser.error("Invalid arguments")
logging.basicConfig(level=logging.INFO)
opts.web = "."
server = WebSocketLoadServer(WebSocketLoad, **opts.__dict__)
server.start_server()
@@ -0,0 +1,150 @@
<html>
<head>
<title>WebSockets Echo Test</title>
<script src="include/util.js"></script>
<script src="include/webutil.js"></script>
<!-- Uncomment to activate firebug lite -->
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
</head>
<body>
Host: <input id='host' style='width:100'>&nbsp;
Port: <input id='port' style='width:50'>&nbsp;
Encrypt: <input id='encrypt' type='checkbox'>&nbsp;
<input id='connectButton' type='button' value='Start' style='width:100px'
onclick="connect();">&nbsp;
<br>
Log:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
</body>
<script>
var ws, host = null, port = null,
msg_cnt = 0, send_cnt = 1, echoDelay = 500,
echo_ref;
function message(str) {
console.log(str);
cell = $D('messages');
cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
msg_cnt++;
}
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i < n; i++) {
this.push(str.charCodeAt(i));
}
}
function send_msg() {
if (ws.bufferedAmount > 0) {
console.log("Delaying send");
return;
}
var str = "Message #" + send_cnt, arr = [];
ws.send(str);
message("Sent message: '" + str + "'");
send_cnt++;
}
function update_stats() {
$D('sent').innerHTML = sent;
$D('received').innerHTML = received;
$D('errors').innerHTML = errors;
}
function init_ws() {
console.log(">> init_ws");
console.log("<< init_ws");
}
function connect() {
var host = $D('host').value,
port = $D('port').value,
scheme = "ws://", uri;
console.log(">> connect");
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
if ($D('encrypt').checked) {
scheme = "wss://";
}
uri = scheme + host + ":" + port;
message("connecting to " + uri);
ws = new WebSocket(uri);
ws.onmessage = function(e) {
//console.log(">> WebSockets.onmessage");
message("Received message '" + e.data + "'");
//console.log("<< WebSockets.onmessage");
};
ws.onopen = function(e) {
console.log(">> WebSockets.onopen");
echo_ref = setInterval(send_msg, echoDelay);
console.log("<< WebSockets.onopen");
};
ws.onclose = function(e) {
console.log(">> WebSockets.onclose");
if (echo_ref) {
clearInterval(echo_ref);
echo_ref = null;
}
console.log("<< WebSockets.onclose");
};
ws.onerror = function(e) {
console.log(">> WebSockets.onerror");
if (echo_ref) {
clearInterval(echo_ref);
echo_ref = null;
}
console.log("<< WebSockets.onerror");
};
$D('connectButton').value = "Stop";
$D('connectButton').onclick = disconnect;
console.log("<< connect");
}
function disconnect() {
console.log(">> disconnect");
if (ws) {
ws.close();
}
if (echo_ref) {
clearInterval(echo_ref);
}
$D('connectButton').value = "Start";
$D('connectButton').onclick = connect;
console.log("<< disconnect");
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
$D('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
}
</script>
</html>
@@ -0,0 +1,67 @@
<html>
<head>
<title>Websock Simple Client</title>
<script src="include/util.js"></script>
<script src="include/websock.js"></script>
</head>
<body>
WebSocket/websockify URI: <input id='target'>&nbsp;
<input id='connectButton' type='button' value='Connect'
onclick="connect();">
<br> <br>
<input id='sendText'>&nbsp;
<input id='sendButton' type='button' value='Send' disabled
onclick="send();">&nbsp;
<br> <br>
Log:<br><textarea id="messages" cols=80 rows=25></textarea>
</body>
<script>
var $D = function(id) { return document.getElementById(id); },
ws = null, msgs = $D('messages');
function msg(str) {
msgs.innerHTML += str + "\n";
msgs.scrollTop = msgs.scrollHeight;
}
function connect() {
var uri = $D('target').value;
ws = new Websock()
msg("connecting to: " + uri);
ws.open(uri);
ws.on('open', function () {
msg("Connected");
});
ws.on('message', function () {
msg("Received: " + ws.rQshiftStr());
});
ws.on('close', function () {
disconnect();
msg("Disconnected");
});
$D('connectButton').value = "Disconnect";
$D('connectButton').onclick = disconnect;
$D('sendButton').disabled = false;
}
function disconnect() {
if (ws) { ws.close(); }
ws = null;
$D('connectButton').value = "Connect";
$D('connectButton').onclick = connect;
$D('sendButton').disabled = true;
}
function send() {
msg("Sending: " + $D('sendText').value);
ws.send_string($D('sendText').value);
};
</script>
</html>
@@ -0,0 +1,28 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
""" Unit tests for Authentication plugins"""
from websockify.auth_plugins import BasicHTTPAuth, AuthenticationError
import unittest
class BasicHTTPAuthTestCase(unittest.TestCase):
def setUp(self):
self.plugin = BasicHTTPAuth('Aladdin:open sesame')
def test_no_auth(self):
headers = {}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')
def test_invalid_password(self):
headers = {'Authorization': 'Basic QWxhZGRpbjpzZXNhbWUgc3RyZWV0'}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')
def test_valid_password(self):
headers = {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
self.plugin.authenticate(headers, 'localhost', '1234')
def test_garbage_auth(self):
headers = {'Authorization': 'Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')
@@ -0,0 +1,186 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright(c)2013 NTT corp. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
""" Unit tests for websocket """
import unittest
from websockify import websocket
class FakeSocket:
def __init__(self):
self.data = b''
def send(self, buf):
self.data += buf
return len(buf)
class AcceptTestCase(unittest.TestCase):
def test_success(self):
ws = websocket.WebSocket()
sock = FakeSocket()
ws.accept(sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
self.assertEqual(sock.data[:13], b'HTTP/1.1 101 ')
self.assertTrue(b'\r\nUpgrade: websocket\r\n' in sock.data)
self.assertTrue(b'\r\nConnection: Upgrade\r\n' in sock.data)
self.assertTrue(b'\r\nSec-WebSocket-Accept: pczpYSQsvE1vBpTQYjFQPcuoj6M=\r\n' in sock.data)
def test_bad_version(self):
ws = websocket.WebSocket()
sock = FakeSocket()
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '5',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '20',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
def test_bad_upgrade(self):
ws = websocket.WebSocket()
sock = FakeSocket()
self.assertRaises(Exception, ws.accept,
sock, {'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket2',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
def test_missing_key(self):
ws = websocket.WebSocket()
sock = FakeSocket()
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13'})
def test_protocol(self):
class ProtoSocket(websocket.WebSocket):
def select_subprotocol(self, protocol):
return 'gazonk'
ws = ProtoSocket()
sock = FakeSocket()
ws.accept(sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q==',
'Sec-WebSocket-Protocol': 'foobar gazonk'})
self.assertEqual(sock.data[:13], b'HTTP/1.1 101 ')
self.assertTrue(b'\r\nSec-WebSocket-Protocol: gazonk\r\n' in sock.data)
def test_no_protocol(self):
ws = websocket.WebSocket()
sock = FakeSocket()
ws.accept(sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q=='})
self.assertEqual(sock.data[:13], b'HTTP/1.1 101 ')
self.assertFalse(b'\r\nSec-WebSocket-Protocol:' in sock.data)
def test_missing_protocol(self):
ws = websocket.WebSocket()
sock = FakeSocket()
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q==',
'Sec-WebSocket-Protocol': 'foobar gazonk'})
def test_protocol(self):
class ProtoSocket(websocket.WebSocket):
def select_subprotocol(self, protocol):
return 'oddball'
ws = ProtoSocket()
sock = FakeSocket()
self.assertRaises(Exception, ws.accept,
sock, {'upgrade': 'websocket',
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q==',
'Sec-WebSocket-Protocol': 'foobar gazonk'})
class HyBiEncodeDecodeTestCase(unittest.TestCase):
def test_decode_hybi_text(self):
buf = b'\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58'
ws = websocket.WebSocket()
res = ws._decode_hybi(buf)
self.assertEqual(res['fin'], 1)
self.assertEqual(res['opcode'], 0x1)
self.assertEqual(res['masked'], True)
self.assertEqual(res['length'], len(buf))
self.assertEqual(res['payload'], b'Hello')
def test_decode_hybi_binary(self):
buf = b'\x82\x04\x01\x02\x03\x04'
ws = websocket.WebSocket()
res = ws._decode_hybi(buf)
self.assertEqual(res['fin'], 1)
self.assertEqual(res['opcode'], 0x2)
self.assertEqual(res['length'], len(buf))
self.assertEqual(res['payload'], b'\x01\x02\x03\x04')
def test_decode_hybi_extended_16bit_binary(self):
data = (b'\x01\x02\x03\x04' * 65) # len > 126 -- len == 260
buf = b'\x82\x7e\x01\x04' + data
ws = websocket.WebSocket()
res = ws._decode_hybi(buf)
self.assertEqual(res['fin'], 1)
self.assertEqual(res['opcode'], 0x2)
self.assertEqual(res['length'], len(buf))
self.assertEqual(res['payload'], data)
def test_decode_hybi_extended_64bit_binary(self):
data = (b'\x01\x02\x03\x04' * 65) # len > 126 -- len == 260
buf = b'\x82\x7f\x00\x00\x00\x00\x00\x00\x01\x04' + data
ws = websocket.WebSocket()
res = ws._decode_hybi(buf)
self.assertEqual(res['fin'], 1)
self.assertEqual(res['opcode'], 0x2)
self.assertEqual(res['length'], len(buf))
self.assertEqual(res['payload'], data)
def test_decode_hybi_multi(self):
buf1 = b'\x01\x03\x48\x65\x6c'
buf2 = b'\x80\x02\x6c\x6f'
ws = websocket.WebSocket()
res1 = ws._decode_hybi(buf1)
self.assertEqual(res1['fin'], 0)
self.assertEqual(res1['opcode'], 0x1)
self.assertEqual(res1['length'], len(buf1))
self.assertEqual(res1['payload'], b'Hel')
res2 = ws._decode_hybi(buf2)
self.assertEqual(res2['fin'], 1)
self.assertEqual(res2['opcode'], 0x0)
self.assertEqual(res2['length'], len(buf2))
self.assertEqual(res2['payload'], b'lo')
def test_encode_hybi_basic(self):
ws = websocket.WebSocket()
res = ws._encode_hybi(0x1, b'Hello')
expected = b'\x81\x05\x48\x65\x6c\x6c\x6f'
self.assertEqual(res, expected)
@@ -0,0 +1,146 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright(c) 2015 Red Hat, Inc All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
""" Unit tests for websocketproxy """
import unittest
import unittest
import socket
from mox3 import stubout
from websockify import websockifyserver
from websockify import websocketproxy
from websockify import token_plugins
from websockify import auth_plugins
try:
from StringIO import StringIO
BytesIO = StringIO
except ImportError:
from io import StringIO
from io import BytesIO
class FakeSocket(object):
def __init__(self, data=''):
if isinstance(data, bytes):
self._data = data
else:
self._data = data.encode('latin_1')
def recv(self, amt, flags=None):
res = self._data[0:amt]
if not (flags & socket.MSG_PEEK):
self._data = self._data[amt:]
return res
def makefile(self, mode='r', buffsize=None):
if 'b' in mode:
return BytesIO(self._data)
else:
return StringIO(self._data.decode('latin_1'))
class FakeServer(object):
class EClose(Exception):
pass
def __init__(self):
self.token_plugin = None
self.auth_plugin = None
self.wrap_cmd = None
self.ssl_target = None
self.unix_target = None
class ProxyRequestHandlerTestCase(unittest.TestCase):
def setUp(self):
super(ProxyRequestHandlerTestCase, self).setUp()
self.stubs = stubout.StubOutForTesting()
self.handler = websocketproxy.ProxyRequestHandler(
FakeSocket(''), "127.0.0.1", FakeServer())
self.handler.path = "https://localhost:6080/websockify?token=blah"
self.handler.headers = None
self.stubs.Set(websockifyserver.WebSockifyServer, 'socket',
staticmethod(lambda *args, **kwargs: None))
def tearDown(self):
self.stubs.UnsetAll()
super(ProxyRequestHandlerTestCase, self).tearDown()
def test_get_target(self):
class TestPlugin(token_plugins.BasePlugin):
def lookup(self, token):
return ("some host", "some port")
host, port = self.handler.get_target(
TestPlugin(None), self.handler.path)
self.assertEqual(host, "some host")
self.assertEqual(port, "some port")
def test_get_target_unix_socket(self):
class TestPlugin(token_plugins.BasePlugin):
def lookup(self, token):
return ("unix_socket", "/tmp/socket")
_, socket = self.handler.get_target(
TestPlugin(None), self.handler.path)
self.assertEqual(socket, "/tmp/socket")
def test_get_target_raises_error_on_unknown_token(self):
class TestPlugin(token_plugins.BasePlugin):
def lookup(self, token):
return None
self.assertRaises(FakeServer.EClose, self.handler.get_target,
TestPlugin(None), "https://localhost:6080/websockify?token=blah")
def test_token_plugin(self):
class TestPlugin(token_plugins.BasePlugin):
def lookup(self, token):
return (self.source + token).split(',')
self.stubs.Set(websocketproxy.ProxyRequestHandler, 'send_auth_error',
staticmethod(lambda *args, **kwargs: None))
self.handler.server.token_plugin = TestPlugin("somehost,")
self.handler.validate_connection()
self.assertEqual(self.handler.server.target_host, "somehost")
self.assertEqual(self.handler.server.target_port, "blah")
def test_auth_plugin(self):
class TestPlugin(auth_plugins.BasePlugin):
def authenticate(self, headers, target_host, target_port):
if target_host == self.source:
raise auth_plugins.AuthenticationError(response_msg="some_error")
self.stubs.Set(websocketproxy.ProxyRequestHandler, 'send_auth_error',
staticmethod(lambda *args, **kwargs: None))
self.handler.server.auth_plugin = TestPlugin("somehost")
self.handler.server.target_host = "somehost"
self.handler.server.target_port = "someport"
self.assertRaises(auth_plugins.AuthenticationError,
self.handler.validate_connection)
self.handler.server.target_host = "someotherhost"
self.handler.validate_connection()
@@ -0,0 +1,347 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright(c)2013 NTT corp. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
""" Unit tests for websockifyserver """
import errno
import os
import logging
import select
import shutil
import socket
import ssl
from mox3 import stubout
import sys
import tempfile
import unittest
import socket
import signal
from websockify import websockifyserver
try:
from BaseHTTPServer import BaseHTTPRequestHandler
except ImportError:
from http.server import BaseHTTPRequestHandler
try:
from StringIO import StringIO
BytesIO = StringIO
except ImportError:
from io import StringIO
from io import BytesIO
def raise_oserror(*args, **kwargs):
raise OSError('fake error')
class FakeSocket(object):
def __init__(self, data=''):
if isinstance(data, bytes):
self._data = data
else:
self._data = data.encode('latin_1')
def recv(self, amt, flags=None):
res = self._data[0:amt]
if not (flags & socket.MSG_PEEK):
self._data = self._data[amt:]
return res
def makefile(self, mode='r', buffsize=None):
if 'b' in mode:
return BytesIO(self._data)
else:
return StringIO(self._data.decode('latin_1'))
class WebSockifyRequestHandlerTestCase(unittest.TestCase):
def setUp(self):
super(WebSockifyRequestHandlerTestCase, self).setUp()
self.stubs = stubout.StubOutForTesting()
self.tmpdir = tempfile.mkdtemp('-websockify-tests')
# Mock this out cause it screws tests up
self.stubs.Set(os, 'chdir', lambda *args, **kwargs: None)
self.stubs.Set(BaseHTTPRequestHandler, 'send_response',
lambda *args, **kwargs: None)
def tearDown(self):
"""Called automatically after each test."""
self.stubs.UnsetAll()
os.rmdir(self.tmpdir)
super(WebSockifyRequestHandlerTestCase, self).tearDown()
def _get_server(self, handler_class=websockifyserver.WebSockifyRequestHandler,
**kwargs):
web = kwargs.pop('web', self.tmpdir)
return websockifyserver.WebSockifyServer(
handler_class, listen_host='localhost',
listen_port=80, key=self.tmpdir, web=web,
record=self.tmpdir, daemon=False, ssl_only=0, idle_timeout=1,
**kwargs)
def test_normal_get_with_only_upgrade_returns_error(self):
server = self._get_server(web=None)
handler = websockifyserver.WebSockifyRequestHandler(
FakeSocket('GET /tmp.txt HTTP/1.1'), '127.0.0.1', server)
def fake_send_response(self, code, message=None):
self.last_code = code
self.stubs.Set(BaseHTTPRequestHandler, 'send_response',
fake_send_response)
handler.do_GET()
self.assertEqual(handler.last_code, 405)
def test_list_dir_with_file_only_returns_error(self):
server = self._get_server(file_only=True)
handler = websockifyserver.WebSockifyRequestHandler(
FakeSocket('GET / HTTP/1.1'), '127.0.0.1', server)
def fake_send_response(self, code, message=None):
self.last_code = code
self.stubs.Set(BaseHTTPRequestHandler, 'send_response',
fake_send_response)
handler.path = '/'
handler.do_GET()
self.assertEqual(handler.last_code, 404)
class WebSockifyServerTestCase(unittest.TestCase):
def setUp(self):
super(WebSockifyServerTestCase, self).setUp()
self.stubs = stubout.StubOutForTesting()
self.tmpdir = tempfile.mkdtemp('-websockify-tests')
# Mock this out cause it screws tests up
self.stubs.Set(os, 'chdir', lambda *args, **kwargs: None)
def tearDown(self):
"""Called automatically after each test."""
self.stubs.UnsetAll()
os.rmdir(self.tmpdir)
super(WebSockifyServerTestCase, self).tearDown()
def _get_server(self, handler_class=websockifyserver.WebSockifyRequestHandler,
**kwargs):
return websockifyserver.WebSockifyServer(
handler_class, listen_host='localhost',
listen_port=80, key=self.tmpdir, web=self.tmpdir,
record=self.tmpdir, **kwargs)
def test_daemonize_raises_error_while_closing_fds(self):
server = self._get_server(daemon=True, ssl_only=1, idle_timeout=1)
self.stubs.Set(os, 'fork', lambda *args: 0)
self.stubs.Set(signal, 'signal', lambda *args: None)
self.stubs.Set(os, 'setsid', lambda *args: None)
self.stubs.Set(os, 'close', raise_oserror)
self.assertRaises(OSError, server.daemonize, keepfd=None, chdir='./')
def test_daemonize_ignores_ebadf_error_while_closing_fds(self):
def raise_oserror_ebadf(fd):
raise OSError(errno.EBADF, 'fake error')
server = self._get_server(daemon=True, ssl_only=1, idle_timeout=1)
self.stubs.Set(os, 'fork', lambda *args: 0)
self.stubs.Set(os, 'setsid', lambda *args: None)
self.stubs.Set(signal, 'signal', lambda *args: None)
self.stubs.Set(os, 'close', raise_oserror_ebadf)
self.stubs.Set(os, 'open', raise_oserror)
self.assertRaises(OSError, server.daemonize, keepfd=None, chdir='./')
def test_handshake_fails_on_not_ready(self):
server = self._get_server(daemon=True, ssl_only=0, idle_timeout=1)
def fake_select(rlist, wlist, xlist, timeout=None):
return ([], [], [])
self.stubs.Set(select, 'select', fake_select)
self.assertRaises(
websockifyserver.WebSockifyServer.EClose, server.do_handshake,
FakeSocket(), '127.0.0.1')
def test_empty_handshake_fails(self):
server = self._get_server(daemon=True, ssl_only=0, idle_timeout=1)
sock = FakeSocket('')
def fake_select(rlist, wlist, xlist, timeout=None):
return ([sock], [], [])
self.stubs.Set(select, 'select', fake_select)
self.assertRaises(
websockifyserver.WebSockifyServer.EClose, server.do_handshake,
sock, '127.0.0.1')
def test_handshake_policy_request(self):
# TODO(directxman12): implement
pass
def test_handshake_ssl_only_without_ssl_raises_error(self):
server = self._get_server(daemon=True, ssl_only=1, idle_timeout=1)
sock = FakeSocket('some initial data')
def fake_select(rlist, wlist, xlist, timeout=None):
return ([sock], [], [])
self.stubs.Set(select, 'select', fake_select)
self.assertRaises(
websockifyserver.WebSockifyServer.EClose, server.do_handshake,
sock, '127.0.0.1')
def test_do_handshake_no_ssl(self):
class FakeHandler(object):
CALLED = False
def __init__(self, *args, **kwargs):
type(self).CALLED = True
FakeHandler.CALLED = False
server = self._get_server(
handler_class=FakeHandler, daemon=True,
ssl_only=0, idle_timeout=1)
sock = FakeSocket('some initial data')
def fake_select(rlist, wlist, xlist, timeout=None):
return ([sock], [], [])
self.stubs.Set(select, 'select', fake_select)
self.assertEqual(server.do_handshake(sock, '127.0.0.1'), sock)
self.assertTrue(FakeHandler.CALLED, True)
def test_do_handshake_ssl(self):
# TODO(directxman12): implement this
pass
def test_do_handshake_ssl_without_ssl_raises_error(self):
# TODO(directxman12): implement this
pass
def test_do_handshake_ssl_without_cert_raises_error(self):
server = self._get_server(daemon=True, ssl_only=0, idle_timeout=1,
cert='afdsfasdafdsafdsafdsafdas')
sock = FakeSocket("\x16some ssl data")
def fake_select(rlist, wlist, xlist, timeout=None):
return ([sock], [], [])
self.stubs.Set(select, 'select', fake_select)
self.assertRaises(
websockifyserver.WebSockifyServer.EClose, server.do_handshake,
sock, '127.0.0.1')
def test_do_handshake_ssl_error_eof_raises_close_error(self):
server = self._get_server(daemon=True, ssl_only=0, idle_timeout=1)
sock = FakeSocket("\x16some ssl data")
def fake_select(rlist, wlist, xlist, timeout=None):
return ([sock], [], [])
def fake_wrap_socket(*args, **kwargs):
raise ssl.SSLError(ssl.SSL_ERROR_EOF)
self.stubs.Set(select, 'select', fake_select)
self.stubs.Set(ssl, 'wrap_socket', fake_wrap_socket)
self.assertRaises(
websockifyserver.WebSockifyServer.EClose, server.do_handshake,
sock, '127.0.0.1')
def test_fallback_sigchld_handler(self):
# TODO(directxman12): implement this
pass
def test_start_server_error(self):
server = self._get_server(daemon=False, ssl_only=1, idle_timeout=1)
sock = server.socket('localhost')
def fake_select(rlist, wlist, xlist, timeout=None):
raise Exception("fake error")
self.stubs.Set(websockifyserver.WebSockifyServer, 'socket',
lambda *args, **kwargs: sock)
self.stubs.Set(websockifyserver.WebSockifyServer, 'daemonize',
lambda *args, **kwargs: None)
self.stubs.Set(select, 'select', fake_select)
server.start_server()
def test_start_server_keyboardinterrupt(self):
server = self._get_server(daemon=False, ssl_only=0, idle_timeout=1)
sock = server.socket('localhost')
def fake_select(rlist, wlist, xlist, timeout=None):
raise KeyboardInterrupt
self.stubs.Set(websockifyserver.WebSockifyServer, 'socket',
lambda *args, **kwargs: sock)
self.stubs.Set(websockifyserver.WebSockifyServer, 'daemonize',
lambda *args, **kwargs: None)
self.stubs.Set(select, 'select', fake_select)
server.start_server()
def test_start_server_systemexit(self):
server = self._get_server(daemon=False, ssl_only=0, idle_timeout=1)
sock = server.socket('localhost')
def fake_select(rlist, wlist, xlist, timeout=None):
sys.exit()
self.stubs.Set(websockifyserver.WebSockifyServer, 'socket',
lambda *args, **kwargs: sock)
self.stubs.Set(websockifyserver.WebSockifyServer, 'daemonize',
lambda *args, **kwargs: None)
self.stubs.Set(select, 'select', fake_select)
server.start_server()
def test_socket_set_keepalive_options(self):
keepcnt = 12
keepidle = 34
keepintvl = 56
server = self._get_server(daemon=False, ssl_only=0, idle_timeout=1)
sock = server.socket('localhost',
tcp_keepcnt=keepcnt,
tcp_keepidle=keepidle,
tcp_keepintvl=keepintvl)
if hasattr(socket, 'TCP_KEEPCNT'):
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPCNT), keepcnt)
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPIDLE), keepidle)
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPINTVL), keepintvl)
sock = server.socket('localhost',
tcp_keepalive=False,
tcp_keepcnt=keepcnt,
tcp_keepidle=keepidle,
tcp_keepintvl=keepintvl)
if hasattr(socket, 'TCP_KEEPCNT'):
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPCNT), keepcnt)
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPIDLE), keepidle)
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPINTVL), keepintvl)