On 12/12/14 18:30, Rafael Schloming wrote:
Hmm, so I hacked websockify to ignore what is specifed in the
protocols header and hard coded it first to use binary, and second to
use base64. Neither option seemed to work.
Hi again Rafi,
My bet is that when you hacked Websockify you didn't update the
response, my hack of websockify/websockify.py (do_websocket_handshake)
looks like:
def do_websocket_handshake(self, headers, path):
h = self.headers = headers
self.path = path
prot = 'WebSocket-Protocol'
protocols = h.get('Sec-'+prot, h.get(prot, '')).split(',')
ver = h.get('Sec-WebSocket-Version')
if ver:
# HyBi/IETF version of the protocol
# HyBi-07 report version 7
# HyBi-08 - HyBi-12 report version 8
# HyBi-13 reports version 13
if ver in ['7', '8', '13']:
self.version = "hybi-%02d" % int(ver)
else:
raise self.EClose('Unsupported protocol version %s' % ver)
key = h['Sec-WebSocket-Key']
# Choose binary unless the client explicityly asks for Base64
if 'base64' in protocols:
self.base64 = True
else:
self.base64 = False
#raise self.EClose("Client must support 'binary' or
'base64' protocol")
# Generate the hash value for the accept header
accept = b64encode(sha1(s2b(key + self.GUID)).digest())
response = self.server_handshake_hybi % b2s(accept)
if self.base64:
response += "Sec-WebSocket-Protocol: base64\r\n"
else:
response += "Sec-WebSocket-Protocol: " + ',
'.join(protocols) + "\r\n"
response += "\r\n"
else:
# Hixie version of the protocol (75 or 76)
if h.get('key3'):
trailer = self.gen_md5(h)
pre = "Sec-"
self.version = "hixie-76"
else:
trailer = ""
pre = ""
self.version = "hixie-75"
# We only support base64 in Hixie era
self.base64 = True
response = self.server_handshake_hixie % (pre,
h['Origin'], pre, self.scheme, h['Host'], path)
if 'base64' in protocols:
response += "%sWebSocket-Protocol: base64\r\n" % pre
else:
self.msg("Warning: client does not report 'base64'
protocol support")
response += "\r\n" + trailer
return response
The changed bits are:
# Choose binary unless the client explicitly asks for Base64
if 'base64' in protocols:
self.base64 = True
else:
self.base64 = False
#raise self.EClose("Client must support 'binary' or
'base64' protocol")
and
if self.base64:
response += "Sec-WebSocket-Protocol: base64\r\n"
else:
response += "Sec-WebSocket-Protocol: " + ',
'.join(protocols) + "\r\n"
BTW for info I also tried hacking the JavaScript binding CMakeLists.txt
to remove the
-s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\"
and that works too (emscripten defaults to 'binary' unless a WebSocket
sub-protocol is specified, that's done mainly so Websockify works out of
the box, 'cause Websockify is what's used on the emscripten tests). The
relevant bits are in emscripten/src/settings.js:
// As well as being configurable at compile time via the "-s" option the
WEBSOCKET_URL and WEBSOCKET_SUBPROTOCOL
// settings may configured at run time via the Module object e.g.
// Module['websocket'] = {subprotocol: 'base64, binary, text'};
// Module['websocket'] = {url: 'wss://', subprotocol: 'base64'};
// Run time configuration may be useful as it lets an application select
multiple different services.
var WEBSOCKET_URL = 'ws://'; // A string containing either a WebSocket
URL prefix (ws:// or wss://) or a complete
// RFC 6455 URL - "ws[s]:" "//" host [ ":"
port ] path [ "?" query ].
// In the (default) case of only a prefix
being specified the URL will be constructed from
// prefix + addr + ':' + port
// where addr and port are derived from
the socket connect/bind/accept calls.
var WEBSOCKET_SUBPROTOCOL = 'binary'; // A string containing a comma
separated list of WebSocket subprotocols
// as would be present in the
Sec-WebSocket-Protocol header.
Less drastically than changing this at compile time it's also perfectly
possible to do it at run time.
If you look in say send.js you'll see a line that looks like:
var proton = require("qpid-proton");
if after that line you do:
proton['websocket']['subprotocol'] = 'binary';
That will make it work with an unhacked Websockify too, though as I
mentioned yesterday by setting this to binary rather than AMQPWSB10 it
will work with Websockify but not the Java Broker.
At least the last approach puts control firmly in your hands so you can
make it configurable. Actually I've just this moment tried:
proton['websocket']['subprotocol'] = 'binary, AMQPWSB10';
and that actually works with WebSockify too, but I've not yet checked
whether that would work with the Java Broker, if it does that might be
worth changing the compile/link flag to (though I suspect that it would
make it even more off-spec wrt. the AMQP JavaScript binding spec.).
proxy.js is tolerant to all these shenanigans though :-D I'd be the
first to admit that it needs some work in the error handling department
but it felt worth including 'cause it's pretty simple, is Node.js based
(which is already needed to compile the JavaScript binding, so no extra
dependencies), is Apache licensed.
HTH, and thanks for taking the time to have a play with the JavaScript
binding.
Cheers,
Frase
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]