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]

Reply via email to