websockify: better multi-python version support.
Pull from websockify: 008a5118e728. Should address issue https://github.com/kanaka/noVNC/issues/107 - Also add ability to force use of web-socket-js using window.WEB_SOCKET_FORCE_FLASH - in websock.js, for rQshift*, assume length is the full length if not specified.
This commit is contained in:
parent
b688a909b0
commit
f2d856767d
|
@ -17,9 +17,9 @@
|
|||
|
||||
// Load Flash WebSocket emulator if needed
|
||||
|
||||
if (window.WebSocket) {
|
||||
if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
|
||||
Websock_native = true;
|
||||
} else if (window.MozWebSocket) {
|
||||
} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
|
||||
Websock_native = true;
|
||||
window.WebSocket = window.MozWebSocket;
|
||||
} else {
|
||||
|
@ -119,6 +119,7 @@ function rQshift32() {
|
|||
(rQ[rQi++] );
|
||||
}
|
||||
function rQshiftStr(len) {
|
||||
if (typeof(len) === 'undefined') { len = rQlen(); }
|
||||
var arr = rQ.slice(rQi, rQi + len);
|
||||
rQi += len;
|
||||
return arr.map(function (num) {
|
||||
|
@ -126,6 +127,7 @@ function rQshiftStr(len) {
|
|||
|
||||
}
|
||||
function rQshiftBytes(len) {
|
||||
if (typeof(len) === 'undefined') { len = rQlen(); }
|
||||
rQi += len;
|
||||
return rQ.slice(rQi-len, rQi);
|
||||
}
|
||||
|
|
|
@ -17,48 +17,54 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
|
|||
'''
|
||||
|
||||
import os, sys, time, errno, signal, socket, traceback, select
|
||||
import struct, array
|
||||
import array, struct
|
||||
from cgi import parse_qsl
|
||||
from base64 import b64encode, b64decode
|
||||
|
||||
# Imports that vary by python version
|
||||
|
||||
# python 3.0 differences
|
||||
if sys.hexversion > 0x3000000:
|
||||
# python >= 3.0
|
||||
from io import StringIO
|
||||
from http.server import SimpleHTTPRequestHandler
|
||||
from urllib.parse import urlsplit
|
||||
b2s = lambda buf: buf.decode('latin_1')
|
||||
s2b = lambda s: s.encode('latin_1')
|
||||
s2a = lambda s: s
|
||||
else:
|
||||
# python 2.X
|
||||
from cStringIO import StringIO
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
from urlparse import urlsplit
|
||||
# No-ops
|
||||
b2s = lambda buf: buf
|
||||
s2b = lambda s: s
|
||||
b2s = lambda buf: buf # No-op
|
||||
s2b = lambda s: s # No-op
|
||||
s2a = lambda s: [ord(c) for c in s]
|
||||
try: from io import StringIO
|
||||
except: from cStringIO import StringIO
|
||||
try: from http.server import SimpleHTTPRequestHandler
|
||||
except: from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
try: from urllib.parse import urlsplit
|
||||
except: from urlparse import urlsplit
|
||||
|
||||
if sys.hexversion >= 0x2060000:
|
||||
# python >= 2.6
|
||||
from multiprocessing import Process
|
||||
from hashlib import md5, sha1
|
||||
else:
|
||||
# python < 2.6
|
||||
Process = None
|
||||
from md5 import md5
|
||||
from sha import sha as sha1
|
||||
# python 2.6 differences
|
||||
try: from hashlib import md5, sha1
|
||||
except: from md5 import md5; from sha import sha as sha1
|
||||
|
||||
# python 2.5 differences
|
||||
try:
|
||||
from struct import pack, unpack_from
|
||||
except:
|
||||
from struct import pack
|
||||
def unpack_from(fmt, buf, offset=0):
|
||||
slice = buffer(buf, offset, struct.calcsize(fmt))
|
||||
return struct.unpack(fmt, slice)
|
||||
|
||||
# Degraded functionality if these imports are missing
|
||||
for mod, sup in [('numpy', 'HyBi protocol'),
|
||||
('ssl', 'TLS/SSL/wss'), ('resource', 'daemonizing')]:
|
||||
for mod, sup in [('numpy', 'HyBi protocol'), ('ssl', 'TLS/SSL/wss'),
|
||||
('multiprocessing', 'Multi-Processing'),
|
||||
('resource', 'daemonizing')]:
|
||||
try:
|
||||
globals()[mod] = __import__(mod)
|
||||
except ImportError:
|
||||
globals()[mod] = None
|
||||
print("WARNING: no '%s' module, %s decode may be slower" % (
|
||||
print("WARNING: no '%s' module, %s is slower or disabled" % (
|
||||
mod, sup))
|
||||
if multiprocessing and sys.platform == 'win32':
|
||||
# make sockets pickle-able/inheritable
|
||||
import multiprocessing.reduction
|
||||
|
||||
|
||||
class WebSocketServer(object):
|
||||
|
@ -265,11 +271,11 @@ Sec-WebSocket-Accept: %s\r
|
|||
b1 = 0x80 | (opcode & 0x0f) # FIN + opcode
|
||||
payload_len = len(buf)
|
||||
if payload_len <= 125:
|
||||
header = struct.pack('>BB', b1, payload_len)
|
||||
header = pack('>BB', b1, payload_len)
|
||||
elif payload_len > 125 and payload_len < 65536:
|
||||
header = struct.pack('>BBH', b1, 126, payload_len)
|
||||
header = pack('>BBH', b1, 126, payload_len)
|
||||
elif payload_len >= 65536:
|
||||
header = struct.pack('>BBQ', b1, 127, payload_len)
|
||||
header = pack('>BBQ', b1, 127, payload_len)
|
||||
|
||||
#print("Encoded: %s" % repr(header + buf))
|
||||
|
||||
|
@ -306,7 +312,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
if blen < f['hlen']:
|
||||
return f # Incomplete frame header
|
||||
|
||||
b1, b2 = struct.unpack_from(">BB", buf)
|
||||
b1, b2 = unpack_from(">BB", buf)
|
||||
f['opcode'] = b1 & 0x0f
|
||||
f['fin'] = (b1 & 0x80) >> 7
|
||||
has_mask = (b2 & 0x80) >> 7
|
||||
|
@ -317,12 +323,12 @@ Sec-WebSocket-Accept: %s\r
|
|||
f['hlen'] = 4
|
||||
if blen < f['hlen']:
|
||||
return f # Incomplete frame header
|
||||
(f['length'],) = struct.unpack_from('>xxH', buf)
|
||||
(f['length'],) = unpack_from('>xxH', buf)
|
||||
elif f['length'] == 127:
|
||||
f['hlen'] = 10
|
||||
if blen < f['hlen']:
|
||||
return f # Incomplete frame header
|
||||
(f['length'],) = struct.unpack_from('>xxQ', buf)
|
||||
(f['length'],) = unpack_from('>xxQ', buf)
|
||||
|
||||
full_len = f['hlen'] + has_mask * 4 + f['length']
|
||||
|
||||
|
@ -351,7 +357,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
|
||||
if f['opcode'] == 0x08:
|
||||
if f['length'] >= 2:
|
||||
f['close_code'] = struct.unpack_from(">H", f['payload'])
|
||||
f['close_code'] = unpack_from(">H", f['payload'])
|
||||
if f['length'] > 3:
|
||||
f['close_reason'] = f['payload'][2:]
|
||||
|
||||
|
@ -381,7 +387,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
|
||||
num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2
|
||||
|
||||
return b2s(md5(struct.pack('>II8s',
|
||||
return b2s(md5(pack('>II8s',
|
||||
int(num1), int(num2), key3)).digest())
|
||||
|
||||
#
|
||||
|
@ -532,7 +538,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
if self.version.startswith("hybi"):
|
||||
msg = s2b('')
|
||||
if code != None:
|
||||
msg = struct.pack(">H%ds" % (len(reason)), code)
|
||||
msg = pack(">H%ds" % (len(reason)), code)
|
||||
|
||||
buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
|
||||
self.client.send(buf)
|
||||
|
@ -791,7 +797,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
|
||||
# Allow override of SIGINT
|
||||
signal.signal(signal.SIGINT, self.do_SIGINT)
|
||||
if not Process:
|
||||
if not multiprocessing:
|
||||
# os.fork() (python 2.4) child reaper
|
||||
signal.signal(signal.SIGCHLD, self.fallback_SIGCHLD)
|
||||
|
||||
|
@ -837,9 +843,10 @@ Sec-WebSocket-Accept: %s\r
|
|||
self.msg('%s: exiting due to --run-once'
|
||||
% address[0])
|
||||
break
|
||||
elif Process:
|
||||
elif multiprocessing:
|
||||
self.vmsg('%s: new handler Process' % address[0])
|
||||
p = Process(target=self.top_new_client,
|
||||
p = multiprocessing.Process(
|
||||
target=self.top_new_client,
|
||||
args=(startsock, address))
|
||||
p.start()
|
||||
# child will not return
|
||||
|
|
Loading…
Reference in New Issue