mirror of
https://github.com/fcwu/docker-ubuntu-vnc-desktop
synced 2026-08-06 08:12:40 +02:00
refactor: clean code
This commit is contained in:
@@ -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'>
|
||||
Port: <input id='port' style='width:50'>
|
||||
Encrypt: <input id='encrypt' type='checkbox'>
|
||||
<input id='connectButton' type='button' value='Start' style='width:100px'
|
||||
onclick="connect();">
|
||||
|
||||
|
||||
<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
@@ -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
@@ -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'>
|
||||
Port: <input id='port' style='width:50'>
|
||||
Encrypt: <input id='encrypt' type='checkbox'>
|
||||
<br>
|
||||
Payload Size: <input id='payload_size' style='width:50'>
|
||||
Send Delay (ms): <input id='sendDelay' style='width:50' value="10">
|
||||
<input id='connectButton' type='button' value='Start' style='width:100px'
|
||||
onclick="connect();">
|
||||
|
||||
<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'>
|
||||
Port: <input id='port' style='width:50'>
|
||||
Encrypt: <input id='encrypt' type='checkbox'>
|
||||
Send Delay (ms): <input id='sendDelay' style='width:50' value="100">
|
||||
<input id='connectButton' type='button' value='Start' style='width:100px'
|
||||
onclick="connect();">
|
||||
|
||||
<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
@@ -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'>
|
||||
Port: <input id='port' style='width:50'>
|
||||
Encrypt: <input id='encrypt' type='checkbox'>
|
||||
<input id='connectButton' type='button' value='Start' style='width:100px'
|
||||
onclick="connect();">
|
||||
|
||||
|
||||
<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'>
|
||||
<input id='connectButton' type='button' value='Connect'
|
||||
onclick="connect();">
|
||||
<br> <br>
|
||||
<input id='sendText'>
|
||||
<input id='sendButton' type='button' value='Send' disabled
|
||||
onclick="send();">
|
||||
<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)
|
||||
Reference in New Issue
Block a user