mirror of
https://git.proxmox.com/git/mirror_novnc
synced 2025-08-09 02:53:56 +00:00
Support WebSockets 76 (hixie-76, hybi-00).
Looks like disabling web-socket-js debug messages by default that we get a minor speedup. Python proxy should support both 75 and 76 (00) modes. Also, update ws test to more reliably hit the WebSockets ordering/drop issue.
This commit is contained in:
parent
7dfa20b8fd
commit
486cd527f2
@ -2,8 +2,6 @@ Short Term:
|
|||||||
|
|
||||||
- Test on IE 9 preview 3.
|
- Test on IE 9 preview 3.
|
||||||
|
|
||||||
- Support WebSockets version 76 in proxy (Chrome 6 and Safari 5).
|
|
||||||
|
|
||||||
- Support Opera 10.60.
|
- Support Opera 10.60.
|
||||||
|
|
||||||
- Possibly support IE <= 8.0 using excanvas:
|
- Possibly support IE <= 8.0 using excanvas:
|
||||||
|
@ -36,3 +36,9 @@ WebSocket gets converted to UTF-8 and vice-versa. So, one additional
|
|||||||
(and necessary) function of the proxy is base64 encoding/decoding what
|
(and necessary) function of the proxy is base64 encoding/decoding what
|
||||||
is sent to/from the browser. Another option that I want to explore is
|
is sent to/from the browser. Another option that I want to explore is
|
||||||
UTF-8 encoding in the proxy.
|
UTF-8 encoding in the proxy.
|
||||||
|
|
||||||
|
|
||||||
|
Building web-socket-js emulator:
|
||||||
|
|
||||||
|
cd include/web-socket-js/flash-src
|
||||||
|
mxmlc -static-link-runtime-shared-libraries WebSocketMain.as
|
||||||
|
Binary file not shown.
@ -1,6 +1,18 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head><title>WebSockets Test</title></head>
|
<head>
|
||||||
|
<title>WebSockets Test</title>
|
||||||
|
<script src="include/mootools.js"></script>
|
||||||
|
<script src="include/base64.js"></script>
|
||||||
|
<script src="include/util.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>
|
<body>
|
||||||
|
|
||||||
@ -31,16 +43,6 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
||||||
<!-- Uncomment to activate firebug lite -->
|
|
||||||
<!--
|
|
||||||
<script type='text/javascript'
|
|
||||||
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script src="include/mootools.js"></script>
|
|
||||||
<script src="include/base64.js"></script>
|
|
||||||
<script src="include/util.js"></script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function error(str) {
|
function error(str) {
|
||||||
@ -226,7 +228,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* If no builtin websockets then load web_socket.js */
|
/* If no builtin websockets then load web_socket.js */
|
||||||
if (! window.WebSocket) {
|
if (window.WebSocket) {
|
||||||
|
VNC_native_ws = true;
|
||||||
|
} else {
|
||||||
|
VNC_native_ws = false;
|
||||||
console.log("Loading web-socket-js flash bridge");
|
console.log("Loading web-socket-js flash bridge");
|
||||||
var extra = "<script src='include/web-socket-js/swfobject.js'><\/script>";
|
var extra = "<script src='include/web-socket-js/swfobject.js'><\/script>";
|
||||||
extra += "<script src='include/web-socket-js/FABridge.js'><\/script>";
|
extra += "<script src='include/web-socket-js/FABridge.js'><\/script>";
|
||||||
@ -236,7 +241,11 @@
|
|||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
console.log("onload");
|
console.log("onload");
|
||||||
WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
|
if (!VNC_native_ws) {
|
||||||
|
console.log("initializing web-socket-js flash bridge");
|
||||||
|
WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
|
||||||
|
WebSocket.__initialize();
|
||||||
|
}
|
||||||
var url = document.location.href;
|
var url = document.location.href;
|
||||||
$('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
|
$('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
|
||||||
$('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
|
$('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
|
||||||
|
@ -15,6 +15,7 @@ sys.path.insert(0,os.path.dirname(__file__) + "/../utils/")
|
|||||||
from websocket import *
|
from websocket import *
|
||||||
|
|
||||||
buffer_size = 65536
|
buffer_size = 65536
|
||||||
|
max_packet_size = 10000
|
||||||
recv_cnt = send_cnt = 0
|
recv_cnt = send_cnt = 0
|
||||||
|
|
||||||
|
|
||||||
@ -76,8 +77,8 @@ def check(buf):
|
|||||||
|
|
||||||
def generate():
|
def generate():
|
||||||
global send_cnt, rand_array
|
global send_cnt, rand_array
|
||||||
length = random.randint(10, 100000)
|
length = random.randint(10, max_packet_size)
|
||||||
numlist = rand_array[100000-length:]
|
numlist = rand_array[max_packet_size-length:]
|
||||||
# Error in length
|
# Error in length
|
||||||
#numlist.append(5)
|
#numlist.append(5)
|
||||||
chksum = sum(numlist)
|
chksum = sum(numlist)
|
||||||
@ -156,7 +157,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
print "Prepopulating random array"
|
print "Prepopulating random array"
|
||||||
rand_array = []
|
rand_array = []
|
||||||
for i in range(0, 100000):
|
for i in range(0, max_packet_size):
|
||||||
rand_array.append(random.randint(0, 9))
|
rand_array.append(random.randint(0, 9))
|
||||||
|
|
||||||
settings['listen_port'] = listen_port
|
settings['listen_port'] = listen_port
|
||||||
|
@ -9,9 +9,10 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, socket, ssl, traceback
|
import sys, socket, ssl, struct, traceback
|
||||||
import os, resource, errno, signal # daemonizing
|
import os, resource, errno, signal # daemonizing
|
||||||
from base64 import b64encode, b64decode
|
from base64 import b64encode, b64decode
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
'listen_host' : '',
|
'listen_host' : '',
|
||||||
@ -30,11 +31,11 @@ send_seq = 0
|
|||||||
server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
|
server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
|
||||||
Upgrade: WebSocket\r
|
Upgrade: WebSocket\r
|
||||||
Connection: Upgrade\r
|
Connection: Upgrade\r
|
||||||
WebSocket-Origin: %s\r
|
%sWebSocket-Origin: %s\r
|
||||||
WebSocket-Location: %s://%s%s\r
|
%sWebSocket-Location: %s://%s%s\r
|
||||||
WebSocket-Protocol: sample\r
|
%sWebSocket-Protocol: sample\r
|
||||||
\r
|
\r
|
||||||
"""
|
%s"""
|
||||||
|
|
||||||
policy_response = """<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>\n"""
|
policy_response = """<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>\n"""
|
||||||
|
|
||||||
@ -104,13 +105,11 @@ def do_handshake(sock):
|
|||||||
scheme = "ws"
|
scheme = "ws"
|
||||||
print " using plain (not SSL) socket"
|
print " using plain (not SSL) socket"
|
||||||
handshake = retsock.recv(4096)
|
handshake = retsock.recv(4096)
|
||||||
req_lines = handshake.split("\r\n")
|
print "handshake: " + repr(handshake)
|
||||||
_, path, _ = req_lines[0].split(" ")
|
h = parse_handshake(handshake)
|
||||||
_, origin = req_lines[4].split(" ")
|
|
||||||
_, host = req_lines[3].split(" ")
|
|
||||||
|
|
||||||
# Parse client settings from the GET path
|
# Parse client settings from the GET path
|
||||||
cvars = path.partition('?')[2].partition('#')[0].split('&')
|
cvars = h['path'].partition('?')[2].partition('#')[0].split('&')
|
||||||
for cvar in [c for c in cvars if c]:
|
for cvar in [c for c in cvars if c]:
|
||||||
name, _, val = cvar.partition('=')
|
name, _, val = cvar.partition('=')
|
||||||
if name not in ['b64encode', 'seq_num']: continue
|
if name not in ['b64encode', 'seq_num']: continue
|
||||||
@ -118,9 +117,56 @@ def do_handshake(sock):
|
|||||||
client_settings[name] = value
|
client_settings[name] = value
|
||||||
print " %s=%s" % (name, value)
|
print " %s=%s" % (name, value)
|
||||||
|
|
||||||
retsock.send(server_handshake % (origin, scheme, host, path))
|
if h.get('key3'):
|
||||||
|
trailer = gen_md5(h)
|
||||||
|
pre = "Sec-"
|
||||||
|
else:
|
||||||
|
trailer = ""
|
||||||
|
pre = ""
|
||||||
|
|
||||||
|
response = server_handshake % (pre, h['Origin'], pre, scheme,
|
||||||
|
h['Host'], h['path'], pre, trailer)
|
||||||
|
|
||||||
|
print "sending response:", repr(response)
|
||||||
|
|
||||||
|
retsock.send(response)
|
||||||
return retsock
|
return retsock
|
||||||
|
|
||||||
|
def parse_handshake(handshake):
|
||||||
|
ret = {}
|
||||||
|
req_lines = handshake.split("\r\n")
|
||||||
|
if not req_lines[0].startswith("GET "):
|
||||||
|
raise "Invalid handshake: no GET request line"
|
||||||
|
ret['path'] = req_lines[0].split(" ")[1]
|
||||||
|
for line in req_lines[1:]:
|
||||||
|
if line == "": break
|
||||||
|
var, delim, val = line.partition(": ")
|
||||||
|
ret[var] = val
|
||||||
|
|
||||||
|
if req_lines[-2] == "":
|
||||||
|
ret['key3'] = req_lines[-1]
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def gen_md5(keys):
|
||||||
|
key1 = keys['Sec-WebSocket-Key1']
|
||||||
|
key2 = keys['Sec-WebSocket-Key2']
|
||||||
|
key3 = keys['key3']
|
||||||
|
spaces1 = key1.count(" ")
|
||||||
|
spaces2 = key2.count(" ")
|
||||||
|
num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
|
||||||
|
num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2
|
||||||
|
|
||||||
|
packed = struct.pack('>II8s', num1, num2, key3)
|
||||||
|
digest = md5(packed).digest()
|
||||||
|
print "num1:", num1
|
||||||
|
print "num2:", num2
|
||||||
|
print "key3:", repr(key3)
|
||||||
|
print "packed:", packed
|
||||||
|
print "digest:", repr(digest)
|
||||||
|
|
||||||
|
return digest
|
||||||
|
|
||||||
def daemonize():
|
def daemonize():
|
||||||
os.umask(0)
|
os.umask(0)
|
||||||
os.chdir('/')
|
os.chdir('/')
|
||||||
|
Loading…
Reference in New Issue
Block a user