Commit f2d85676 authored by Joel Martin's avatar Joel Martin

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.
parent b688a909
......@@ -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]
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
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
# 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment