Lawouach / WebSocket-for-Python

WebSocket client and server library for Python 2 and 3 as well as PyPy (ws4py 0.5.1)
https://ws4py.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
1.12k stars 288 forks source link

Upgrading from 0.3.4 to 0.3.5 broke "protocols" #179

Closed mpf82 closed 6 years ago

mpf82 commented 8 years ago

Hello,

I have a demo application (basically a slightly modified version of the echo demo) that uses protocols, however after upgrading to 0.3.5 yesterday, I get an error in process_handshake_header() whenever I set matching protocols for server and client (Interestingly: omitting the protocols on either server or client, or giving server and client non-matching protocols works!)

  File "..\ws4py-0.3.5-py3.4.egg\ws4py\client\__init__.py", line 233, in connect
    self.protocols, self.extensions = self.process_handshake_header(headers)
  File "..\ws4py-0.3.5-py3.4.egg\ws4py\client\__init__.py", line 326, in process_handshake_header
    protocols = ','.join(value)
TypeError: sequence item 0: expected str instance, int found

Environment: Python 3.4 64 bit, cherrypy

    class EchoWebSocketHandler(WebSocket):
        # nothing special here, just echo the message

    cherrypy.quickstart(Root(args.host, args.port, args.ssl), '', config={
        '/ws_echo': {
            'tools.websocket.on': True,
            'tools.websocket.handler_cls': EchoWebSocketHandler,
            'tools.websocket.protocols': ['ws4py-echo', 'ws4py-test'], # omitting this line works
            },
        }
    )
            ws = EchoClient(ws_url, protocols=['ws4py-test', 'ws4py-echo']) # -> error
            #ws = EchoClient(ws_url, protocols=[]) # this works
            ws.connect()

Suggested fix in client/init.py:

            elif header == b'sec-websocket-protocol':
#                 protocols = ','.join(value) # original line
                protocols = [x.strip() for x in value.split(b',')] # replacement

I'm not even sure how the original code ever worked in the first place. Isn't value always a (byte)string? not sure how joining the (byte)string can result in an array.

If this really fixes the problem, you should consider to do the same for extensions.

Cheers, Mike

nicklasb commented 8 years ago

Hi, if you want to propose a change, please create a PR. That way it is tested and done when the maintainer checks it.

mikemccracken commented 8 years ago

I've hit this too. The original code probably "worked" because it was never executed, since it was comparing bytes in header to a regular string "sec-websocket-protocol", up until 0.3.5