Remove Base64 support
This is an older protocol used before browsers got native support for Websockets.
This commit is contained in:
parent
56a4ccbf74
commit
4099949984
|
@ -3,8 +3,6 @@ docs/LICENSE.LGPL-3) with the following exceptions:
|
|||
|
||||
include/websock.js : MPL 2.0
|
||||
|
||||
include/base64.js : MPL 2.0
|
||||
|
||||
include/des.js : Various BSD style licenses
|
||||
|
||||
include/web-socket-js/ : New BSD license (3-clause). Source code at
|
||||
|
|
15
README.md
15
README.md
|
@ -33,16 +33,8 @@ href="http://www.twitter.com/noVNC">@noVNC</a> if you do.
|
|||
### WebSockets binary data
|
||||
|
||||
Starting with websockify 0.5.0, only the HyBi / IETF
|
||||
6455 WebSocket protocol is supported.
|
||||
|
||||
Websockify negotiates whether to base64 encode traffic to and from the
|
||||
client via the subprotocol header (Sec-WebSocket-Protocol). The valid
|
||||
subprotocol values are 'binary' and 'base64' and if the client sends
|
||||
both then the server (the python implementation) will prefer 'binary'.
|
||||
The 'binary' subprotocol indicates that the data will be sent raw
|
||||
using binary WebSocket frames. Some HyBi clients (such as the Flash
|
||||
fallback and older Chrome and iOS versions) do not support binary data
|
||||
which is why the negotiation is necessary.
|
||||
6455 WebSocket protocol is supported. There is no support for the older
|
||||
Base64 encoded data format.
|
||||
|
||||
|
||||
### Encrypted WebSocket connections (wss://)
|
||||
|
@ -77,8 +69,7 @@ and then also to the key with `--key`. Finally, use `--ssl-only` as needed.
|
|||
The `include/websock.js` Javascript library library provides a Websock
|
||||
object that is similar to the standard WebSocket object but Websock
|
||||
enables communication with raw TCP sockets (i.e. the binary stream)
|
||||
via websockify. This is accomplished by base64 encoding the data
|
||||
stream between Websock and websockify.
|
||||
via websockify.
|
||||
|
||||
Websock has built-in receive queue buffering; the message event
|
||||
does not contain actual data but is simply a notification that
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
|
||||
|
||||
/*jslint white: false, bitwise: false, plusplus: false */
|
||||
/*global console */
|
||||
|
||||
var Base64 = {
|
||||
|
||||
/* Convert data (an array of integers) to a Base64 string. */
|
||||
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''),
|
||||
base64Pad : '=',
|
||||
|
||||
encode: function (data) {
|
||||
"use strict";
|
||||
var result = '';
|
||||
var toBase64Table = Base64.toBase64Table;
|
||||
var base64Pad = Base64.base64Pad;
|
||||
var length = data.length;
|
||||
var i;
|
||||
// Convert every three bytes to 4 ascii characters.
|
||||
/* BEGIN LOOP */
|
||||
for (i = 0; i < (length - 2); i += 3) {
|
||||
result += toBase64Table[data[i] >> 2];
|
||||
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
|
||||
result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
|
||||
result += toBase64Table[data[i+2] & 0x3f];
|
||||
}
|
||||
/* END LOOP */
|
||||
|
||||
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
|
||||
if (length%3) {
|
||||
i = length - (length%3);
|
||||
result += toBase64Table[data[i] >> 2];
|
||||
if ((length%3) === 2) {
|
||||
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
|
||||
result += toBase64Table[(data[i+1] & 0x0f) << 2];
|
||||
result += base64Pad;
|
||||
} else {
|
||||
result += toBase64Table[(data[i] & 0x03) << 4];
|
||||
result += base64Pad + base64Pad;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/* Convert Base64 data to a string */
|
||||
toBinaryTable : [
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
|
||||
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
|
||||
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
|
||||
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
||||
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
|
||||
],
|
||||
|
||||
decode: function (data, offset) {
|
||||
"use strict";
|
||||
offset = typeof(offset) !== 'undefined' ? offset : 0;
|
||||
var toBinaryTable = Base64.toBinaryTable;
|
||||
var base64Pad = Base64.base64Pad;
|
||||
var result, result_length, idx, i, c, padding;
|
||||
var leftbits = 0; // number of bits decoded, but yet to be appended
|
||||
var leftdata = 0; // bits decoded, but yet to be appended
|
||||
var data_length = data.indexOf('=') - offset;
|
||||
|
||||
if (data_length < 0) { data_length = data.length - offset; }
|
||||
|
||||
/* Every four characters is 3 resulting numbers */
|
||||
result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5);
|
||||
result = new Array(result_length);
|
||||
|
||||
// Convert one by one.
|
||||
/* BEGIN LOOP */
|
||||
for (idx = 0, i = offset; i < data.length; i++) {
|
||||
c = toBinaryTable[data.charCodeAt(i) & 0x7f];
|
||||
padding = (data.charAt(i) === base64Pad);
|
||||
// Skip illegal characters and whitespace
|
||||
if (c === -1) {
|
||||
console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Collect data into leftdata, update bitcount
|
||||
leftdata = (leftdata << 6) | c;
|
||||
leftbits += 6;
|
||||
|
||||
// If we have 8 or more bits, append 8 bits to the result
|
||||
if (leftbits >= 8) {
|
||||
leftbits -= 8;
|
||||
// Append if not padding.
|
||||
if (!padding) {
|
||||
result[idx++] = (leftdata >> leftbits) & 0xff;
|
||||
}
|
||||
leftdata &= (1 << leftbits) - 1;
|
||||
}
|
||||
}
|
||||
/* END LOOP */
|
||||
|
||||
// If there are any bits left, the base64 string was corrupted
|
||||
if (leftbits) {
|
||||
throw {name: 'Base64-Error',
|
||||
message: 'Corrupted base64 string'};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}; /* End of Base64 namespace */
|
|
@ -5,8 +5,7 @@
|
|||
*
|
||||
* Websock is similar to the standard WebSocket object but Websock
|
||||
* enables communication with raw TCP sockets (i.e. the binary stream)
|
||||
* via websockify. This is accomplished by base64 encoding the data
|
||||
* stream between Websock and websockify.
|
||||
* via websockify.
|
||||
*
|
||||
* Websock has built-in receive queue buffering; the message event
|
||||
* does not contain actual data but is simply a notification that
|
||||
|
@ -15,7 +14,7 @@
|
|||
*/
|
||||
|
||||
/*jslint browser: true, bitwise: false, plusplus: false */
|
||||
/*global Util, Base64 */
|
||||
/*global Util */
|
||||
|
||||
|
||||
// Load Flash WebSocket emulator if needed
|
||||
|
@ -52,7 +51,6 @@ function Websock() {
|
|||
|
||||
var api = {}, // Public API
|
||||
websocket = null, // WebSocket object
|
||||
mode = 'base64', // Current WebSocket mode: 'binary', 'base64'
|
||||
rQ = [], // Receive queue
|
||||
rQi = 0, // Receive queue index
|
||||
rQmax = 10000, // Max receive queue size before compacting
|
||||
|
@ -154,36 +152,6 @@ function rQwait(msg, num, goback) {
|
|||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Private utility routines
|
||||
//
|
||||
|
||||
function encode_message() {
|
||||
if (mode === 'binary') {
|
||||
// Put in a binary arraybuffer
|
||||
return (new Uint8Array(sQ)).buffer;
|
||||
} else {
|
||||
// base64 encode
|
||||
return Base64.encode(sQ);
|
||||
}
|
||||
}
|
||||
|
||||
function decode_message(data) {
|
||||
//Util.Debug(">> decode_message: " + data);
|
||||
if (mode === 'binary') {
|
||||
// push arraybuffer values onto the end
|
||||
var u8 = new Uint8Array(data);
|
||||
for (var i = 0; i < u8.length; i++) {
|
||||
rQ.push(u8[i]);
|
||||
}
|
||||
} else {
|
||||
// base64 decode and concat to the end
|
||||
rQ = rQ.concat(Base64.decode(data, 0));
|
||||
}
|
||||
//Util.Debug(">> decode_message, rQ: " + rQ);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public Send functions
|
||||
//
|
||||
|
@ -196,7 +164,7 @@ function flush() {
|
|||
//Util.Debug("arr: " + arr);
|
||||
//Util.Debug("sQ: " + sQ);
|
||||
if (sQ.length > 0) {
|
||||
websocket.send(encode_message(sQ));
|
||||
websocket.send((new Uint8Array(sQ)).buffer);
|
||||
sQ = [];
|
||||
}
|
||||
return true;
|
||||
|
@ -227,7 +195,10 @@ function recv_message(e) {
|
|||
//Util.Debug(">> recv_message: " + e.data.length);
|
||||
|
||||
try {
|
||||
decode_message(e.data);
|
||||
var u8 = new Uint8Array(e.data);
|
||||
for (var i = 0; i < u8.length; i++) {
|
||||
rQ.push(u8[i]);
|
||||
}
|
||||
if (rQlen() > 0) {
|
||||
eventHandlers.message();
|
||||
// Compact the receive queue
|
||||
|
@ -262,92 +233,27 @@ function on(evt, handler) {
|
|||
eventHandlers[evt] = handler;
|
||||
}
|
||||
|
||||
function init(protocols, ws_schema) {
|
||||
function init() {
|
||||
rQ = [];
|
||||
rQi = 0;
|
||||
sQ = [];
|
||||
websocket = null;
|
||||
|
||||
var bt = false,
|
||||
wsbt = false,
|
||||
try_binary = false;
|
||||
|
||||
// Check for full typed array support
|
||||
if (('Uint8Array' in window) &&
|
||||
('set' in Uint8Array.prototype)) {
|
||||
bt = true;
|
||||
}
|
||||
// Check for full binary type support in WebSocket
|
||||
// Inspired by:
|
||||
// https://github.com/Modernizr/Modernizr/issues/370
|
||||
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets/binary.js
|
||||
try {
|
||||
if (bt && ('binaryType' in WebSocket.prototype ||
|
||||
!!(new WebSocket(ws_schema + '://.').binaryType))) {
|
||||
Util.Info("Detected binaryType support in WebSockets");
|
||||
wsbt = true;
|
||||
}
|
||||
} catch (exc) {
|
||||
// Just ignore failed test localhost connections
|
||||
}
|
||||
|
||||
// Default protocols if not specified
|
||||
if (typeof(protocols) === "undefined") {
|
||||
if (wsbt) {
|
||||
protocols = ['binary', 'base64'];
|
||||
} else {
|
||||
protocols = 'base64';
|
||||
}
|
||||
}
|
||||
|
||||
// If no binary support, make sure it was not requested
|
||||
if (!wsbt) {
|
||||
if (protocols === 'binary') {
|
||||
throw("WebSocket binary sub-protocol requested but not supported");
|
||||
}
|
||||
if (typeof(protocols) === "object") {
|
||||
var new_protocols = [];
|
||||
for (var i = 0; i < protocols.length; i++) {
|
||||
if (protocols[i] === 'binary') {
|
||||
Util.Error("Skipping unsupported WebSocket binary sub-protocol");
|
||||
} else {
|
||||
new_protocols.push(protocols[i]);
|
||||
}
|
||||
}
|
||||
if (new_protocols.length > 0) {
|
||||
protocols = new_protocols;
|
||||
} else {
|
||||
throw("Only WebSocket binary sub-protocol was requested and not supported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return protocols;
|
||||
}
|
||||
|
||||
function open(uri, protocols) {
|
||||
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
|
||||
protocols = init(protocols, ws_schema);
|
||||
init();
|
||||
|
||||
if (test_mode) {
|
||||
websocket = {};
|
||||
} else {
|
||||
websocket = new WebSocket(uri, protocols);
|
||||
if (protocols.indexOf('binary') >= 0) {
|
||||
websocket.binaryType = 'arraybuffer';
|
||||
}
|
||||
websocket.binaryType = 'arraybuffer';
|
||||
}
|
||||
|
||||
websocket.onmessage = recv_message;
|
||||
websocket.onopen = function() {
|
||||
Util.Debug(">> WebSock.onopen");
|
||||
if (websocket.protocol) {
|
||||
mode = websocket.protocol;
|
||||
Util.Info("Server chose sub-protocol: " + websocket.protocol);
|
||||
} else {
|
||||
mode = 'base64';
|
||||
Util.Error("Server select no sub-protocol!: " + websocket.protocol);
|
||||
}
|
||||
eventHandlers.open();
|
||||
Util.Debug("<< WebSock.onopen");
|
||||
};
|
||||
|
@ -376,9 +282,8 @@ function close() {
|
|||
|
||||
// Override internal functions for testing
|
||||
// Takes a send function, returns reference to recv function
|
||||
function testMode(override_send, data_mode) {
|
||||
function testMode(override_send) {
|
||||
test_mode = true;
|
||||
mode = data_mode;
|
||||
api.send = override_send;
|
||||
api.close = function () {};
|
||||
return recv_message;
|
||||
|
|
|
@ -42,11 +42,7 @@ new_client = function(client) {
|
|||
target.on('data', function(data) {
|
||||
//log("sending message: " + data);
|
||||
try {
|
||||
if (client.protocol === 'base64') {
|
||||
client.send(new Buffer(data).toString('base64'));
|
||||
} else {
|
||||
client.send(data,{binary: true});
|
||||
}
|
||||
client.send(data);
|
||||
} catch(e) {
|
||||
log("Client closed, cleaning up target");
|
||||
target.end();
|
||||
|
@ -64,11 +60,7 @@ new_client = function(client) {
|
|||
|
||||
client.on('message', function(msg) {
|
||||
//log('got message: ' + msg);
|
||||
if (client.protocol === 'base64') {
|
||||
target.write(new Buffer(msg, 'base64'));
|
||||
} else {
|
||||
target.write(msg,'binary');
|
||||
}
|
||||
target.write(msg);
|
||||
});
|
||||
client.on('close', function(code, reason) {
|
||||
log('WebSocket client disconnected: ' + code + ' [' + reason + ']');
|
||||
|
@ -123,18 +115,6 @@ http_request = function (request, response) {
|
|||
});
|
||||
};
|
||||
|
||||
// Select 'binary' or 'base64' subprotocol, preferring 'binary'
|
||||
selectProtocol = function(protocols, callback) {
|
||||
if (protocols.indexOf('binary') >= 0) {
|
||||
callback(true, 'binary');
|
||||
} else if (protocols.indexOf('base64') >= 0) {
|
||||
callback(true, 'base64');
|
||||
} else {
|
||||
console.log("Client must support 'binary' or 'base64' protocol");
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
// parse source and target arguments into parts
|
||||
try {
|
||||
source_arg = argv._[0].toString();
|
||||
|
@ -183,8 +163,7 @@ if (argv.cert) {
|
|||
webServer = http.createServer(http_request);
|
||||
}
|
||||
webServer.listen(source_port, function() {
|
||||
wsServer = new WebSocketServer({server: webServer,
|
||||
handleProtocols: selectProtocol});
|
||||
wsServer = new WebSocketServer({server: webServer});
|
||||
wsServer.on('connection', new_client);
|
||||
});
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ require 'openssl'
|
|||
require 'stringio'
|
||||
require 'digest/md5'
|
||||
require 'digest/sha1'
|
||||
require 'base64'
|
||||
|
||||
unless OpenSSL::SSL::SSLSocket.instance_methods.index("read_nonblock")
|
||||
module OpenSSL
|
||||
|
@ -92,7 +91,6 @@ Sec-WebSocket-Accept: %s\r
|
|||
t[:my_client_id] = @@client_id
|
||||
t[:send_parts] = []
|
||||
t[:recv_part] = nil
|
||||
t[:base64] = nil
|
||||
|
||||
puts "in serve, client: #{t[:my_client_id].inspect}"
|
||||
|
||||
|
@ -151,11 +149,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
return data
|
||||
end
|
||||
|
||||
def encode_hybi(buf, opcode, base64=false)
|
||||
if base64
|
||||
buf = Base64.encode64(buf).gsub(/\n/, '')
|
||||
end
|
||||
|
||||
def encode_hybi(buf, opcode)
|
||||
b1 = 0x80 | (opcode & 0x0f) # FIN + opcode
|
||||
payload_len = buf.length
|
||||
if payload_len <= 125
|
||||
|
@ -170,7 +164,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
return [header + buf, header.length, 0]
|
||||
end
|
||||
|
||||
def decode_hybi(buf, base64=false)
|
||||
def decode_hybi(buf)
|
||||
f = {'fin' => 0,
|
||||
'opcode' => 0,
|
||||
'hlen' => 2,
|
||||
|
@ -216,10 +210,6 @@ Sec-WebSocket-Accept: %s\r
|
|||
f['payload'] = buf[f['hlen']...full_len]
|
||||
end
|
||||
|
||||
if base64 and [1, 2].include?(f['opcode'])
|
||||
f['payload'] = Base64.decode64(f['payload'])
|
||||
end
|
||||
|
||||
# close frame
|
||||
if f['opcode'] == 0x08
|
||||
if f['length'] >= 2
|
||||
|
@ -251,13 +241,8 @@ Sec-WebSocket-Accept: %s\r
|
|||
encbuf = ""
|
||||
bufs.each do |buf|
|
||||
if t[:version].start_with?("hybi")
|
||||
if t[:base64]
|
||||
encbuf, lenhead, lentail = encode_hybi(
|
||||
buf, opcode=1, base64=true)
|
||||
else
|
||||
encbuf, lenhead, lentail = encode_hybi(
|
||||
buf, opcode=2, base64=false)
|
||||
end
|
||||
encbuf, lenhead, lentail = encode_hybi(
|
||||
buf, opcode=2)
|
||||
else
|
||||
encbuf, lenhead, lentail = encode_hixie(buf)
|
||||
end
|
||||
|
@ -302,7 +287,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
|
||||
while buf.length > 0
|
||||
if t[:version].start_with?("hybi")
|
||||
frame = decode_hybi(buf, base64=t[:base64])
|
||||
frame = decode_hybi(buf)
|
||||
|
||||
if frame['payload'] == nil
|
||||
traffic "}."
|
||||
|
@ -359,7 +344,7 @@ Sec-WebSocket-Accept: %s\r
|
|||
msg = [reason.length, code].pack("na8")
|
||||
end
|
||||
|
||||
buf, lenh, lent = encode_hybi(msg, opcode=0x08, base64=false)
|
||||
buf, lenh, lent = encode_hybi(msg, opcode=0x08)
|
||||
t[:client].write(buf)
|
||||
elsif t[:version] == "hixie-76"
|
||||
buf = "\xff\x00"
|
||||
|
@ -412,73 +397,29 @@ Sec-WebSocket-Accept: %s\r
|
|||
protocols = h.fetch("sec-websocket-protocol", h["websocket-protocol"])
|
||||
ver = h.fetch('sec-websocket-version', nil)
|
||||
|
||||
if ver
|
||||
# HyBi/IETF vesrion of the protocol
|
||||
|
||||
# HyBi 07 reports version 7
|
||||
# HyBi 08 - 12 report version 8
|
||||
# HyBi 13 and up report version 13
|
||||
if ['7', '8', '13'].include?(ver)
|
||||
t[:version] = "hybi-%02d" % [ver.to_i]
|
||||
else
|
||||
raise EClose, "Unsupported protocol version %s" % [ver]
|
||||
end
|
||||
|
||||
# choose binary if client supports it
|
||||
if protocols.include?('binary')
|
||||
t[:base64] = false
|
||||
elsif protocols.include?('base64')
|
||||
t[:base64] = true
|
||||
else
|
||||
raise EClose, "Client must support 'binary' or 'base64' sub-protocol"
|
||||
end
|
||||
|
||||
key = h['sec-websocket-key']
|
||||
|
||||
# Generate the hash value for the accpet header
|
||||
accept = Base64.encode64(
|
||||
Digest::SHA1.digest(key + @@GUID)).gsub(/\n/, '')
|
||||
|
||||
response = @@Server_handshake_hybi % [accept]
|
||||
|
||||
if t[:base64]
|
||||
response += "Sec-WebSocket-Protocol: base64\r\n"
|
||||
else
|
||||
response += "Sec-WebSocket-Protocol: binary\r\n"
|
||||
end
|
||||
response += "\r\n"
|
||||
# HyBi/IETF vesrion of the protocol
|
||||
|
||||
# HyBi 07 reports version 7
|
||||
# HyBi 08 - 12 report version 8
|
||||
# HyBi 13 and up report version 13
|
||||
if ['7', '8', '13'].include?(ver)
|
||||
t[:version] = "hybi-%02d" % [ver.to_i]
|
||||
else
|
||||
# Hixie vesrion of the protocol (75 or 76)
|
||||
body = handshake.match(/\r\n\r\n(........)/)
|
||||
if body
|
||||
h['key3'] = body[1]
|
||||
trailer = gen_md5(h)
|
||||
pre = "Sec-"
|
||||
t[:version] = "hixie-76"
|
||||
else
|
||||
trailer = ""
|
||||
pre = ""
|
||||
t[:version] = "hixie-75"
|
||||
end
|
||||
|
||||
# base64 required for Hixie since payload is only UTF-8
|
||||
t[:base64] = true
|
||||
|
||||
response = @@Server_handshake_hixie % [pre, h['origin'], pre,
|
||||
"ws", h['host'], t[:path]]
|
||||
|
||||
if protocols && protocols.include?('base64')
|
||||
response += "%sWebSocket-Protocol: base64\r\n" % [pre]
|
||||
else
|
||||
msg "Warning: client does not report 'base64' protocol support"
|
||||
end
|
||||
|
||||
response += "\r\n" + trailer
|
||||
raise EClose, "Unsupported protocol version %s" % [ver]
|
||||
end
|
||||
|
||||
key = h['sec-websocket-key']
|
||||
|
||||
# Generate the hash value for the accpet header
|
||||
accept = Base64.encode64(
|
||||
Digest::SHA1.digest(key + @@GUID)).gsub(/\n/, '')
|
||||
|
||||
response = @@Server_handshake_hybi % [accept]
|
||||
|
||||
response += "\r\n"
|
||||
|
||||
msg "%s WebSocket connection" % [stype]
|
||||
msg "Version %s, base64: '%s'" % [t[:version], t[:base64]]
|
||||
msg "Version %s" % [t[:version]]
|
||||
if t[:path] then msg "Path: '%s'" % [t[:path]] end
|
||||
|
||||
#puts "sending reponse #{response.inspect}"
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from base64 import b64encode, b64decode
|
||||
from codecs import (utf_8_encode, utf_8_decode,
|
||||
latin_1_encode, latin_1_decode)
|
||||
import random, time
|
||||
|
||||
buf_len = 10000
|
||||
iterations = 10000
|
||||
|
||||
print "Generating random input buffer"
|
||||
r = random.Random()
|
||||
buf = "".join([chr(r.randint(0, 255)) for i in range(buf_len)])
|
||||
|
||||
tests = {'UTF8 encode': lambda: utf_8_encode(unicode(buf, 'latin-1'))[0],
|
||||
'B64 encode': lambda: b64encode(buf)}
|
||||
utf8_buf = tests['UTF8 encode']()
|
||||
b64_buf = tests['B64 encode']()
|
||||
tests.update({'UTF8 decode': lambda: latin_1_encode(utf_8_decode(utf8_buf)[0])[0],
|
||||
'B64 decode': lambda: b64decode(b64_buf)})
|
||||
|
||||
print "Running tests"
|
||||
for test in 'UTF8 encode', 'B64 encode', 'UTF8 decode', 'B64 decode':
|
||||
start = time.time()
|
||||
for i in range(iterations):
|
||||
res_buf = tests[test]()
|
||||
print "%s took %s seconds (result size %s)" % (
|
||||
test, (time.time() - start), len(res_buf))
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Native Base64 Tests</title>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
<script src="include/base64.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Native Base64 Tests</h1>
|
||||
|
||||
<br>
|
||||
Messages:<br>
|
||||
<textarea id="debug" style="font-size: 9px;" cols=80 rows=25></textarea>
|
||||
|
||||
<br>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function debug(str) {
|
||||
console.log(str);
|
||||
cell = $D('debug');
|
||||
cell.innerHTML += str + "\n";
|
||||
cell.scrollTop = cell.scrollHeight;
|
||||
}
|
||||
|
||||
function assertRun(code, result) {
|
||||
try {
|
||||
var actual = eval(code);
|
||||
} catch (exc) {
|
||||
debug("FAIL: '" + code + "' threw an exception");
|
||||
fail += 1;
|
||||
return false;
|
||||
}
|
||||
if (actual !== result) {
|
||||
debug("FAIL: '" + code + "' returned '" + actual + "', expected '" + result + "'");
|
||||
fail += 1;
|
||||
return false;
|
||||
}
|
||||
debug("PASS: '" + code + "' returned expected '" + result +"'");
|
||||
pass += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function Base64_decode(data) {
|
||||
var arr = Base64.decode (data);
|
||||
return arr.map(function (num) {
|
||||
return String.fromCharCode(num); } ).join('');
|
||||
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
var str;
|
||||
debug('onload');
|
||||
fail = 0;
|
||||
pass = 0;
|
||||
assertRun('window.btoa("hello world")', 'aGVsbG8gd29ybGQ=');
|
||||
assertRun('window.btoa("a")', 'YQ==');
|
||||
assertRun('window.btoa("ab")', 'YWI=');
|
||||
assertRun('window.btoa("abc")', 'YWJj');
|
||||
assertRun('window.btoa("abcd")', 'YWJjZA==');
|
||||
assertRun('window.btoa("abcde")', 'YWJjZGU=');
|
||||
assertRun('window.btoa("abcdef")', 'YWJjZGVm');
|
||||
assertRun('window.btoa("abcdefg")', 'YWJjZGVmZw==');
|
||||
assertRun('window.btoa("abcdefgh")', 'YWJjZGVmZ2g=');
|
||||
|
||||
assertRun('window.atob("aGVsbG8gd29ybGQ=")', 'hello world');
|
||||
assertRun('Base64_decode("aGVsbG8gd29ybGQ=")', 'hello world');
|
||||
assertRun('window.atob("YQ==")', 'a');
|
||||
assertRun('Base64_decode("YQ==")', 'a');
|
||||
assertRun('window.atob("YWI=")', 'ab');
|
||||
assertRun('Base64_decode("YWI=")', 'ab');
|
||||
assertRun('window.atob("YWJj")', 'abc');
|
||||
assertRun('Base64_decode("YWJj")', 'abc');
|
||||
assertRun('window.atob("YWJjZA==")', 'abcd');
|
||||
assertRun('Base64_decode("YWJjZA==")', 'abcd');
|
||||
assertRun('window.atob("YWJjZGU=")', 'abcde');
|
||||
assertRun('Base64_decode("YWJjZGU=")', 'abcde');
|
||||
assertRun('window.atob("YWJjZGVm")', 'abcdef');
|
||||
assertRun('Base64_decode("YWJjZGVm")', 'abcdef');
|
||||
|
||||
assertRun('typeof window.btoa', 'function');
|
||||
assertRun('window.btoa("")', '');
|
||||
assertRun('window.btoa(null)', '');
|
||||
assertRun('window.atob(window.btoa(window))', window.toString()); // "[object DOMWindow]"
|
||||
assertRun('window.btoa("\\u0080\\u0081")', 'gIE=');
|
||||
|
||||
debug("Tests failed: " + fail);
|
||||
debug("Tests passed: " + pass);
|
||||
}
|
||||
</script>
|
|
@ -1,12 +0,0 @@
|
|||
// The following results in 'hello [MANGLED]'
|
||||
//
|
||||
// Filed as https://github.com/ry/node/issues/issue/402
|
||||
|
||||
var sys = require("sys"),
|
||||
buf = new Buffer(1024), len,
|
||||
str1 = "aGVsbG8g", // 'hello '
|
||||
str2 = "d29ybGQ=", // 'world'
|
||||
|
||||
len = buf.write(str1, 0, 'base64');
|
||||
len += buf.write(str2, len, 'base64');
|
||||
sys.log("decoded result: " + buf.toString('binary', 0, len));
|
|
@ -4,7 +4,6 @@
|
|||
<title>WebSockets Echo Test</title>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
<!-- Uncomment to activate firebug lite -->
|
||||
<!--
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
<head>
|
||||
<title>WebSockets Latency Test</title>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<title>WebSockets Load Test</title>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
<!-- Uncomment to activate firebug lite -->
|
||||
<!--
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
}
|
||||
uri = scheme + host + ":" + port;
|
||||
message("connecting to " + uri);
|
||||
ws = new WebSocket(uri, "base64");
|
||||
ws = new WebSocket(uri);
|
||||
|
||||
ws.onmessage = function(e) {
|
||||
//console.log(">> WebSockets.onmessage");
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<head>
|
||||
<title>Websock Simple Client</title>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
'''
|
||||
Display UTF-8 encoding for 0-255.'''
|
||||
|
||||
import sys, os, socket, ssl, time, traceback
|
||||
from select import select
|
||||
sys.path.insert(0,os.path.join(os.path.dirname(__file__), ".."))
|
||||
from websockify.websocket import WebSocketServer
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "val: hybi_base64 | hybi_binary"
|
||||
for c in range(0, 256):
|
||||
hybi_base64 = WebSocketServer.encode_hybi(chr(c), opcode=1,
|
||||
base64=True)
|
||||
hybi_binary = WebSocketServer.encode_hybi(chr(c), opcode=2,
|
||||
base64=False)
|
||||
print "%d: %s | %s" % (c, repr(hybi_base64), repr(hybi_binary))
|
||||
|
|
@ -18,7 +18,7 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
|
|||
|
||||
import os, sys, time, errno, signal, socket, select, logging
|
||||
import array, ssl, multiprocessing
|
||||
from base64 import b64encode, b64decode
|
||||
from base64 import b64encode
|
||||
from hashlib import sha1
|
||||
from struct import pack, unpack_from
|
||||
|
||||
|
@ -141,7 +141,7 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
return data.tostring()
|
||||
|
||||
@staticmethod
|
||||
def encode_hybi(buf, opcode, base64=False):
|
||||
def encode_hybi(buf, opcode):
|
||||
""" Encode a HyBi style WebSocket frame.
|
||||
Optional opcode:
|
||||
0x0 - continuation
|
||||
|
@ -151,8 +151,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
0x9 - ping
|
||||
0xA - pong
|
||||
"""
|
||||
if base64:
|
||||
buf = b64encode(buf)
|
||||
|
||||
b1 = 0x80 | (opcode & 0x0f) # FIN + opcode
|
||||
payload_len = len(buf)
|
||||
|
@ -168,7 +166,7 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
return header + buf, len(header), 0
|
||||
|
||||
@staticmethod
|
||||
def decode_hybi(buf, base64=False, logger=None, strict=True):
|
||||
def decode_hybi(buf, logger=None, strict=True):
|
||||
""" Decode HyBi style WebSocket packets.
|
||||
Returns:
|
||||
{'fin' : 0_or_1,
|
||||
|
@ -240,14 +238,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
f['payload'] = buf[(f['hlen'] + f['masked'] * 4):full_len]
|
||||
|
||||
if base64 and f['opcode'] in [1, 2]:
|
||||
try:
|
||||
f['payload'] = b64decode(f['payload'])
|
||||
except:
|
||||
logger.exception("Exception while b64decoding buffer: %s" %
|
||||
(repr(buf)))
|
||||
raise
|
||||
|
||||
if f['opcode'] == 0x08:
|
||||
if f['length'] >= 2:
|
||||
f['close_code'] = unpack_from(">H", f['payload'])[0]
|
||||
|
@ -297,10 +287,7 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
if bufs:
|
||||
for buf in bufs:
|
||||
if self.base64:
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=1, base64=True)
|
||||
else:
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=2, base64=False)
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=2)
|
||||
|
||||
if self.rec:
|
||||
self.rec.write("%s,\n" %
|
||||
|
@ -345,7 +332,7 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
self.recv_part = None
|
||||
|
||||
while buf:
|
||||
frame = self.decode_hybi(buf, base64=self.base64,
|
||||
frame = self.decode_hybi(buf,
|
||||
logger=self.logger,
|
||||
strict=self.strict_mode)
|
||||
#self.msg("Received buf: %s, frame: %s", repr(buf), frame)
|
||||
|
@ -399,17 +386,17 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
""" Send a WebSocket orderly close frame. """
|
||||
|
||||
msg = pack(">H%ds" % len(reason), code, s2b(reason))
|
||||
buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
|
||||
buf, h, t = self.encode_hybi(msg, opcode=0x08)
|
||||
self.request.send(buf)
|
||||
|
||||
def send_pong(self, data=''):
|
||||
""" Send a WebSocket pong frame. """
|
||||
buf, h, t = self.encode_hybi(s2b(data), opcode=0x0A, base64=False)
|
||||
buf, h, t = self.encode_hybi(s2b(data), opcode=0x0A)
|
||||
self.request.send(buf)
|
||||
|
||||
def send_ping(self, data=''):
|
||||
""" Send a WebSocket ping frame. """
|
||||
buf, h, t = self.encode_hybi(s2b(data), opcode=0x09, base64=False)
|
||||
buf, h, t = self.encode_hybi(s2b(data), opcode=0x09)
|
||||
self.request.send(buf)
|
||||
|
||||
def do_websocket_handshake(self):
|
||||
|
@ -433,15 +420,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
key = h['Sec-WebSocket-Key']
|
||||
|
||||
# Choose binary if client supports it
|
||||
if 'binary' in protocols:
|
||||
self.base64 = False
|
||||
elif 'base64' in protocols:
|
||||
self.base64 = True
|
||||
else:
|
||||
self.send_error(400, "Client must support 'binary' or 'base64' protocol")
|
||||
return False
|
||||
|
||||
# Generate the hash value for the accept header
|
||||
accept = b64encode(sha1(s2b(key + self.GUID)).digest())
|
||||
|
||||
|
@ -449,10 +427,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
self.send_header("Upgrade", "websocket")
|
||||
self.send_header("Connection", "Upgrade")
|
||||
self.send_header("Sec-WebSocket-Accept", b2s(accept))
|
||||
if self.base64:
|
||||
self.send_header("Sec-WebSocket-Protocol", "base64")
|
||||
else:
|
||||
self.send_header("Sec-WebSocket-Protocol", "binary")
|
||||
self.end_headers()
|
||||
|
||||
# Other requests cannot follow Websocket data
|
||||
|
@ -501,8 +475,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
self.log_message("%s: %s WebSocket connection", client_addr,
|
||||
self.stype)
|
||||
self.log_message("%s: Version %s, base64: '%s'", client_addr,
|
||||
self.version, self.base64)
|
||||
if self.path != '/':
|
||||
self.log_message("%s: Path: '%s'", client_addr, self.path)
|
||||
|
||||
|
@ -512,10 +484,6 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
self.handler_id)
|
||||
self.log_message("opening record file: %s", fname)
|
||||
self.rec = open(fname, 'w+')
|
||||
encoding = "binary"
|
||||
if self.base64: encoding = "base64"
|
||||
self.rec.write("var VNC_frame_encoding = '%s';\n"
|
||||
% encoding)
|
||||
self.rec.write("var VNC_frame_data = [\n")
|
||||
|
||||
try:
|
||||
|
|
|
@ -220,9 +220,7 @@ Traffic Legend:
|
|||
class WebSocketProxy(websocket.WebSocketServer):
|
||||
"""
|
||||
Proxy traffic to and from a WebSockets client to a normal TCP
|
||||
socket server target. All traffic to/from the client is base64
|
||||
encoded/decoded to allow binary data to be sent/received to/from
|
||||
the target.
|
||||
socket server target.
|
||||
"""
|
||||
|
||||
buffer_size = 65536
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
<head>
|
||||
<title>IRC Client using WebSockets</title>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
<head>
|
||||
<title>Telnet client using WebSockets</title>
|
||||
<script src="include/base64.js"></script>
|
||||
<script src="include/util.js"></script>
|
||||
<script src="include/websock.js"></script>
|
||||
<script src="include/webutil.js"></script>
|
||||
|
|
Loading…
Reference in New Issue