Ejemplo n.º 1
0
 def __init__(self, url, protocols, extensions):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
     WebSocket.__init__(self, sock, protocols=protocols, extensions=extensions)
     self.stream.always_mask = True
     self.stream.expect_masking = False
     self.key = b64encode(os.urandom(16))
     self.url = url
Ejemplo n.º 2
0
    def test_cannot_process_more_data_when_stream_is_terminated(self):
        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.client_terminated = True
        ws.server_terminated = True

        self.assertFalse(ws.once())
Ejemplo n.º 3
0
 def __init__(self, *args, **kw):
     WebSocket.__init__(self, *args, **kw)
     print str(self) + "connected"
     SUBSCRIBERS.add(self)
     global NextUID
     NextUID = NextUID + 1
     UID = NextUID
    def test_cannot_process_more_data_when_stream_is_terminated(self):
        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.client_terminated = True
        ws.server_terminated = True

        self.assertFalse(ws.once())
Ejemplo n.º 5
0
 def __init__(self, *args, **kw):
     """
     Constructor. This will be called automatically
     by the server upon connection
     """
     WebSocket.__init__(self, *args, **kw)
     self.close_callback = None
Ejemplo n.º 6
0
 def __init__(self, url, protocols, extensions):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
     WebSocket.__init__(self, sock, protocols=protocols, extensions=extensions)
     self.stream.always_mask = True
     self.stream.expect_masking = False
     self.key = b64encode(os.urandom(16))
     self.url = url
Ejemplo n.º 7
0
	def __init__(self, *args, **kw):
		WebSocket.__init__(self, *args, **kw)
		print str(self) + "connected"
		SUBSCRIBERS.add(self)
		global NextUID
		NextUID = NextUID + 1
		UID = NextUID
Ejemplo n.º 8
0
    def __init__(self, *args, **kwargs):
        self.widget_wslock = threading.Lock()

        # We don't know what DB they are connected to
        self.db = None
        self.session = drayerdb.Session(isClientSide=True)
        WebSocket.__init__(self, *args, **kwargs)
 def test_sending_ping(self):
     tm = PingControlMessage("hello").single(mask=False)
     
     m = MagicMock()
     ws = WebSocket(sock=m)
     ws.ping("hello")
     m.sendall.assert_called_once_with(tm)
Ejemplo n.º 10
0
 def test_send_message_without_masking(self):
     tm = TextMessage(b'hello world')
     
     m = MagicMock()
     ws = WebSocket(sock=m)
     ws.send(tm)
     m.sendall.assert_called_once_with(tm.single())
Ejemplo n.º 11
0
    def test_send_message_without_masking(self):
        tm = TextMessage(b'hello world')

        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.send(tm)
        m.sendall.assert_called_once_with(tm.single())
Ejemplo n.º 12
0
    def test_sending_ping(self):
        tm = PingControlMessage("hello").single(mask=False)

        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.ping("hello")
        m.sendall.assert_called_once_with(tm)
Ejemplo n.º 13
0
 def __init__(self, *args, **kw):
     """
     Constructor. This will be called automatically
     by the server upon connection
     """
     WebSocket.__init__(self, *args, **kw)
     self.close_callback = None
Ejemplo n.º 14
0
    def __init__(self, *args, **kwargs):
        """
        This passes all arguments to the parent constructor.  In addition, it
        defines the following instance variables:

        send_lock: Used to guarantee thread-safety when sending RPC responses.

        client_locks: A dict mapping client ids to locks used by those clients.

        passthru_subscriptions: When we recieve a subscription request for a
            service method registered on a remote service, we pass that request
            along to the remote service and send back the responses.  This
            dictionary maps client ids to those subscription objects.

        session_fields: We copy session data for the  currently-authenticated
            user who made the incoming websocket connection; by default we only
            copy the username, but this can be overridden in configuration.
            Remember that Sideboard exposes two websocket handlers at /ws and
            /wsrpc, with /ws being auth-protected (so the username field will be
            meaningful) and /wsrpc being client-cert protected (so the username
            will always be 'rpc').

        header_fields: We copy header fields from the request that initiated the
            websocket connection.

        cached_queries and cached_fingerprints: When we receive a subscription
            update, Sideboard re-runs all of the subscription methods to see if
            new data needs to be pushed out.  We do this by storing all of the
            rpc methods and an MD5 hash of their return values.  We store a hash
            rather than the return values themselves to save on memory, since
            return values may be very large.

            The cached_queries dict has this structure:
                {
                    'client_id': {
                        'callback_id': (func, args, kwargs, client_data),
                        ...
                    },
                    ...
                }

            The cached_fingerprints dict has this structure:
                {
                    'client_id': {
                        'callback_id': 'md5_hash_of_return_value',
                        ...
                    },
                    ...
                }
        """
        WebSocket.__init__(self, *args, **kwargs)
        self.instances.add(self)
        self.send_lock = RLock()
        self.passthru_subscriptions = {}
        self.client_locks = defaultdict(RLock)
        self.cached_queries, self.cached_fingerprints = defaultdict(
            dict), defaultdict(dict)
        self.session_fields = self.check_authentication()
        self.header_fields = self.fetch_headers()
Ejemplo n.º 15
0
            def closed(self, *args):
                try:
                    WebSocket.closed(self, *args)

                    if handler[0]:
                        handler[0].onClosed()
                except:
                    logging.error("error in websocket handler:\n%s", traceback.format_exc())
Ejemplo n.º 16
0
 def __init__(self,
              sock,
              protocols=None,
              extensions=None,
              environ=None,
              heartbeat_freq=None):
     WebSocket.__init__(self, sock, protocols, extensions, environ,
                        heartbeat_freq)
Ejemplo n.º 17
0
 def __init__(self, app_name, *args, **kw):
     self.app_name = app_name
     self.backend = get_backend()
     self.verbose = self.backend.verbose
     cherrypy.log.access_log.info(
         'Creating %s with args=%s and keywords=%s.' % (self.app_name, args, kw))
     WebSocket.__init__(self, *args, **kw)
     self.backend.register(self)
Ejemplo n.º 18
0
    def __init__(self, *args, **kwargs):
        """
        This passes all arguments to the parent constructor.  In addition, it
        defines the following instance variables:

        send_lock: Used to guarantee thread-safety when sending RPC responses.

        client_locks: A dict mapping client ids to locks used by those clients.

        passthru_subscriptions: When we recieve a subscription request for a
            service method registered on a remote service, we pass that request
            along to the remote service and send back the responses.  This
            dictionary maps client ids to those subscription objects.

        session_fields: We copy session data for the  currently-authenticated
            user who made the incoming websocket connection; by default we only
            copy the username, but this can be overridden in configuration.
            Remember that Sideboard exposes two websocket handlers at /ws and
            /wsrpc, with /ws being auth-protected (so the username field will be
            meaningful) and /wsrpc being client-cert protected (so the username
            will always be 'rpc').

        header_fields: We copy header fields from the request that initiated the
            websocket connection.

        cached_queries and cached_fingerprints: When we receive a subscription
            update, Sideboard re-runs all of the subscription methods to see if
            new data needs to be pushed out.  We do this by storing all of the
            rpc methods and an MD5 hash of their return values.  We store a hash
            rather than the return values themselves to save on memory, since
            return values may be very large.

            The cached_queries dict has this structure:
                {
                    'client_id': {
                        'callback_id': (func, args, kwargs, client_data),
                        ...
                    },
                    ...
                }

            The cached_fingerprints dict has this structure:
                {
                    'client_id': {
                        'callback_id': 'md5_hash_of_return_value',
                        ...
                    },
                    ...
                }
        """
        WebSocket.__init__(self, *args, **kwargs)
        self.instances.add(self)
        self.send_lock = RLock()
        self.passthru_subscriptions = {}
        self.client_locks = defaultdict(RLock)
        self.cached_queries, self.cached_fingerprints = defaultdict(dict), defaultdict(dict)
        self.session_fields = self.check_authentication()
        self.header_fields = self.fetch_headers()
Ejemplo n.º 19
0
 def __init__(self, app_name, *args, **kw):
     self.app_name = app_name
     self.backend = get_backend()
     self.verbose = self.backend.verbose
     cherrypy.log.access_log.info(
         'Creating %s with args=%s and keywords=%s.' %
         (self.app_name, args, kw))
     WebSocket.__init__(self, *args, **kw)
     self.backend.register(self)
Ejemplo n.º 20
0
 def __init__(self,
              sock,
              protocols=None,
              extensions=None,
              environ=None,
              heartbeat_freq=None):
     WebSocket.__init__(self, sock, protocols, extensions, environ,
                        heartbeat_freq)
     self.json_rpc = cherrypy.engine.json_rpc
Ejemplo n.º 21
0
 def closed(self, code, reason=''):
     """
     This overrides the default closed handler to first clean up all of our
     subscriptions, remove this websocket from the registry of instances,
     and log a message before closing.
     """
     log.info('closing: code={!r} reason={!r}', code, reason)
     self.instances.discard(self)
     self.unsubscribe_all()
     WebSocket.closed(self, code, reason)
Ejemplo n.º 22
0
 def closed(self, code, reason=''):
     """
     This overrides the default closed handler to first clean up all of our
     subscriptions, remove this websocket from the registry of instances,
     and log a message before closing.
     """
     log.info('closing: code={!r} reason={!r}', code, reason)
     self.instances.discard(self)
     self.unsubscribe_all()
     WebSocket.closed(self, code, reason)
Ejemplo n.º 23
0
 def __init__(self,
              sock,
              protocols=None,
              extensions=None,
              environ=None,
              heartbeat_freq=None):
     WebSocket.__init__(self, sock)
     self.clients = []
     self.settings = cherrypy.engine.publish('get-settings', 'gui')[0]
     self.type = 'gui'
Ejemplo n.º 24
0
    def test_send_bytes_with_masking(self):
        tm = TextMessage(b'hello world').single(mask=True)

        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.stream = MagicMock()
        ws.stream.always_mask = True
        ws.stream.text_message.return_value.single.return_value = tm

        ws.send(b'hello world')
        m.sendall.assert_called_once_with(tm)
Ejemplo n.º 25
0
 def test_send_bytes_with_masking(self):
     tm = TextMessage(b'hello world').single(mask=True)
     
     m = MagicMock()
     ws = WebSocket(sock=m)
     ws.stream = MagicMock()
     ws.stream.always_mask = True
     ws.stream.text_message.return_value.single.return_value = tm
     
     ws.send(b'hello world')
     m.sendall.assert_called_once_with(tm)
Ejemplo n.º 26
0
 def test_closing_message_received(self):
     s = MagicMock()
     m = MagicMock()
     c = MagicMock()
     
     ws = WebSocket(sock=m)
     with patch.multiple(ws, close=c):
         ws.stream = s
         ws.stream.closing = CloseControlMessage(code=1000, reason='test closing')
         ws.process(b'unused for this test')
         c.assert_called_once_with(1000, b'test closing')
Ejemplo n.º 27
0
def join_queue(socket:WebSocket, data):
    # keep this order to avoid state conflict
    channel, pubsub = pub_sub_pool.join()
    r_queue.put(channel)
    # {'pattern': None, 'type': 'message', 'data': b'30ae154a-2397-4945-aeed-48dad6c603b6', 'channel': 'queue_channel:19'}
    msg = pub_sub_pool.next_message(channel, pubsub)
    uid = msg['data']
    if not uid in games:
        games[uid] = make_game_engine()

    games[uid].join_game(data["player"])
    socket.send(uid)
Ejemplo n.º 28
0
 def __init__(self, *args, **kargs):
     WebSocket.__init__(self, *args, **kargs)
     self._logger = logging.getLogger('python')
     self.comMessage = {
         "sender": "python",
         "opCode": "info",
         "data": {
             "param": 0,
             "discription": ''
         }
     }
     print("_________init_________")
Ejemplo n.º 29
0
    def test_closing_message_received(self):
        s = MagicMock()
        m = MagicMock()
        c = MagicMock()

        ws = WebSocket(sock=m)
        with patch.multiple(ws, close=c):
            ws.stream = s
            ws.stream.closing = CloseControlMessage(code=1000,
                                                    reason='test closing')
            ws.process(b'unused for this test')
            c.assert_called_once_with(1000, b'test closing')
Ejemplo n.º 30
0
    def __init__(self, *args, **kw):
        WebSocket.__init__(self, *args, **kw)

        # cherrypy.log("args type %s" % type(ws))
        #
        # for i in args:
        #     try:
        #         cherrypy.log("args  %s \n" % i)
        #     except Exception as error:
        #         cherrypy.log("Can't print args  because %s \n" % error)
        # cherrypy.log("args %s " % args)
        # cherrypy.log("kw %s " % kw)
        SUBSCRIBERS.add(self)
Ejemplo n.º 31
0
    def __init__(self, *args, **kwargs):
        WebSocket.__init__(self, *args, **kwargs)
        self.debugger_store().chrome_channel.setSocket(self)

        common_domain_args = {'debugger_store': self.debugger_store()}

        runtime_domain = RuntimeDomain(**common_domain_args)
        debugger_domain = DebuggerDomain(runtime_domain, **common_domain_args)
        self.handlers = HandlerDomainSet(
            ConsoleDomain(**common_domain_args),
            debugger_domain,
            PageDomain(**common_domain_args),
            runtime_domain,
        )
Ejemplo n.º 32
0
    def test_send_generator_without_masking(self):
        tm0 = b'hello'
        tm1 = b'world'
        
        def datasource():
            yield tm0
            yield tm1

        gen = datasource()
        
        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.send(gen)
        self.assertEqual(m.sendall.call_count, 2)
        self.assertRaises(StopIteration, next, gen)
Ejemplo n.º 33
0
Archivo: __init__.py Proyecto: 3GA/nush
    def __init__(self, url, protocols, extensions, heartbeat_freq=None):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        WebSocket.__init__(self, sock, protocols=protocols, extensions=extensions,
                           heartbeat_freq=heartbeat_freq)
        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))
        self.url = url

        self.host = None
        self.scheme = None
        self.port = None
        self.resource = None

        self._parse_url()
Ejemplo n.º 34
0
    def send(self, **message):
        message = {k: v for k, v in message.items() if v is not None}
        if "data" in message and "client" in message:
            fingerprint = _fingerprint(message["data"])
            client, callback = message["client"], message.get("callback")
            repeat_send = callback in self.cached_fingerprints[client]
            cached_fingerprint = self.cached_fingerprints[client].get(callback)
            self.cached_fingerprints[client][callback] = fingerprint
            if cached_fingerprint == fingerprint and repeat_send:
                return

        self.log.debug("sending {}", message)
        message = json.dumps(message, cls=sideboard.lib.serializer, separators=(",", ":"), sort_keys=True)
        with self.send_lock:
            WebSocket.send(self, message)
Ejemplo n.º 35
0
    def test_send_generator_without_masking(self):
        tm0 = b'hello'
        tm1 = b'world'

        def datasource():
            yield tm0
            yield tm1

        gen = datasource()

        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.send(gen)
        self.assertEqual(m.sendall.call_count, 2)
        self.assertRaises(StopIteration, next, gen)
Ejemplo n.º 36
0
    def send(self, **message):
        message = {k: v for k, v in message.items() if v is not None}
        if 'data' in message and 'client' in message:
            fingerprint = _fingerprint(message['data'])
            client, callback = message['client'], message.get('callback')
            repeat_send = callback in self.cached_fingerprints[client]
            cached_fingerprint = self.cached_fingerprints[client].get(callback)
            self.cached_fingerprints[client][callback] = fingerprint
            if cached_fingerprint == fingerprint and repeat_send:
                return

        log.debug('sending {}', message)
        message = json.dumps(message, cls=sideboard.lib.serializer,
                                      separators=(',', ':'), sort_keys=True)
        with self.send_lock:
            WebSocket.send(self, message)
Ejemplo n.º 37
0
 def test_get_ipv6_addresses(self):
     m = MagicMock()
     m.getsockname.return_value = ('127.0.0.1', 52300, None, None)
     m.getpeername.return_value = ('127.0.0.1', 4800, None, None)
     ws = WebSocket(sock=m)
     self.assertEqual(ws.local_address, ('127.0.0.1', 52300))
     self.assertEqual(ws.peer_address, ('127.0.0.1', 4800))
Ejemplo n.º 38
0
 def __init__(self, *args, **kargs):
     WebSocket.__init__(self, *args, **kargs)
     self.isAlive = True
     self._logger = logging.getLogger('python')
     self.comMessage = {
         "sender": "python",
         "opCode": "info",
         "data": {
             "param": 0,
             "discription": ''
         }
     }
     self._serialThread = threading.Thread(target=self.serialLoop,
                                           name="wait serial data")
     self._serialThread.start()
     print("_________init_________")
Ejemplo n.º 39
0
    def test_format_address(self):
        m = MagicMock()
        m.getsockname.return_value = ('127.0.0.1', 52300, None, None)
        m.getpeername.return_value = ('127.0.0.1', 4800, None, None)
        ws = WebSocket(sock=m)

        log = format_addresses(ws)
        self.assertEqual(
            log, "[Local => 127.0.0.1:52300 | Remote => 127.0.0.1:4800]")
Ejemplo n.º 40
0
    def send(self, **message):
        message = {k: v for k, v in message.items() if v is not None}
        if 'data' in message and 'client' in message:
            fingerprint = _fingerprint(message['data'])
            client, callback = message['client'], message.get('callback')
            repeat_send = callback in self.cached_fingerprints[client]
            cached_fingerprint = self.cached_fingerprints[client].get(callback)
            self.cached_fingerprints[client][callback] = fingerprint
            if cached_fingerprint == fingerprint and repeat_send:
                return

        log.debug('sending {}', message)
        message = json.dumps(message,
                             cls=sideboard.lib.serializer,
                             separators=(',', ':'),
                             sort_keys=True)
        with self.send_lock:
            WebSocket.send(self, message)
Ejemplo n.º 41
0
    def __init__(self, *args, **kargs):

        '''New websockets can be registered with the radio on creation.
        Channel names can be passed in the URL, for example:

            ws://localhost:1002/ws/chan0/chan1

        A socket may be created with no channels, and then register one
        or more later on. This is how client-side Radio actually works.
        '''

        WebSocket.__init__(self, *args, **kargs)

        # derive a list of zero or more channels from the url
        channels = str(self.environ['REQUEST_URI'])[2:-1].split('/')[2:]

        # if channels is empty, this does nothing
        radio.register(channels, self.send, True)
Ejemplo n.º 42
0
    def __init__(self, *args, **kwargs):
        WebSocket.__init__(self, *args, **kwargs)
        self.debugger_store().chrome_channel.setSocket(self)

        common_domain_args = {
            'debugger_store': self.debugger_store()
        }

        runtime_domain = RuntimeDomain(**common_domain_args)
        debugger_domain = DebuggerDomain(
            runtime_domain,
            **common_domain_args)
        self.handlers = HandlerDomainSet(
            ConsoleDomain(**common_domain_args),
            debugger_domain,
            PageDomain(**common_domain_args),
            runtime_domain,
        )
Ejemplo n.º 43
0
 def test_terminate_with_closing(self):
     m = MagicMock()
     s = MagicMock()
     c = MagicMock()
     cc = MagicMock()
     
     ws = WebSocket(sock=m)
     with patch.multiple(ws, closed=c, close_connection=cc):
         ws.stream = s
         ws.stream.closing = CloseControlMessage(code=1000, reason='test closing')
         ws.terminate()
         self.assertTrue(ws.client_terminated)
         self.assertTrue(ws.server_terminated)
         self.assertTrue(ws.terminated)
         c.assert_called_once_with(1000, b'test closing')
         cc.assert_called_once_with()
         self.assertIsNone(ws.stream)
         self.assertIsNone(ws.environ)
Ejemplo n.º 44
0
 def test_terminate_without_closing(self):
     m = MagicMock()
     s = MagicMock()
     c = MagicMock()
     cc = MagicMock()
     
     ws = WebSocket(sock=m)
     with patch.multiple(ws, closed=c, close_connection=cc):
         ws.stream = s
         ws.stream.closing = None
         ws.terminate()
         self.assertTrue(ws.client_terminated)
         self.assertTrue(ws.server_terminated)
         self.assertTrue(ws.terminated)
         c.assert_called_once_with(1006, "Going away")
         cc.assert_called_once_with()
         self.assertIsNone(ws.stream)
         self.assertIsNone(ws.environ)
Ejemplo n.º 45
0
    def test_terminate_without_closing(self):
        m = MagicMock()
        s = MagicMock()
        c = MagicMock()
        cc = MagicMock()

        ws = WebSocket(sock=m)
        with patch.multiple(ws, closed=c, close_connection=cc):
            ws.stream = s
            ws.stream.closing = None
            ws.terminate()
            self.assertTrue(ws.client_terminated)
            self.assertTrue(ws.server_terminated)
            self.assertTrue(ws.terminated)
            c.assert_called_once_with(1006, "Going away")
            cc.assert_called_once_with()
            self.assertIsNone(ws.stream)
            self.assertIsNone(ws.environ)
Ejemplo n.º 46
0
    def __init__(self,
                 url,
                 protocols=None,
                 extensions=None,
                 heartbeat_freq=None):
        """
        A websocket client that implements :rfc:`6455` and provides a simple
        interface to communicate with a websocket server.

        This class works on its own but will block if not run in
        its own thread.

        When an instance of this class is created, a :py:mod:`socket`
        is created with the nagle's algorithm disabled and with
        the capacity to reuse a port that was just used.

        The address of the server will be extracted from the given
        websocket url.

        The websocket key is randomly generated, reset the
        `key` attribute if you want to provide yours.

        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

        sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        WebSocket.__init__(self,
                           sock,
                           protocols=protocols,
                           extensions=extensions,
                           heartbeat_freq=heartbeat_freq)
        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))
        self.url = url

        self.host = None
        self.scheme = None
        self.port = None
        self.resource = None

        self._parse_url()
Ejemplo n.º 47
0
    def send(self, **message):
        """
        This overrides the ws4py-provided send to implement three new features:

        1) Instead of taking a string, this method treats its keyword arguments
           as the message, serializes them to JSON, and sends that.

        2) For subscription responses, we keep track of the most recent response
           we sent for the given subscription.  If neither the request or
           response have changed since the last time we pushed data back to the
           client for this subscription, we don't send anything.

        3) We lock when sending to ensure that our sends are thread-safe.
           Surprisingly, the "ws4py.threadedclient" class isn't thread-safe!

        4) Subscriptions firing will sometimes trigger a send on a websocket
           which has already been marked as closed.  When this happens we log a
           debug message and then exit without error.
        """
        if self.is_closed:
            log.debug('ignoring send on an already closed websocket: {}',
                      message)
            self.unsubscribe_all()
            return

        message = {k: v for k, v in message.items() if v is not None}
        if 'data' in message and 'client' in message:
            fingerprint = _fingerprint(message['data'])
            client, callback = message['client'], message.get('callback')
            repeat_send = callback in self.cached_fingerprints[client]
            cached_fingerprint = self.cached_fingerprints[client].get(callback)
            self.cached_fingerprints[client][callback] = fingerprint
            if cached_fingerprint == fingerprint and repeat_send:
                return

        log.debug('sending {}', message)
        message = json.dumps(message,
                             cls=sideboard.lib.serializer,
                             separators=(',', ':'),
                             sort_keys=True)
        with self.send_lock:
            if not self.is_closed:
                WebSocket.send(self, message)
Ejemplo n.º 48
0
    def test_terminate_with_closing(self):
        m = MagicMock()
        s = MagicMock()
        c = MagicMock()
        cc = MagicMock()

        ws = WebSocket(sock=m)
        with patch.multiple(ws, closed=c, close_connection=cc):
            ws.stream = s
            ws.stream.closing = CloseControlMessage(code=1000,
                                                    reason='test closing')
            ws.terminate()
            self.assertTrue(ws.client_terminated)
            self.assertTrue(ws.server_terminated)
            self.assertTrue(ws.terminated)
            c.assert_called_once_with(1000, b'test closing')
            cc.assert_called_once_with()
            self.assertIsNone(ws.stream)
            self.assertIsNone(ws.environ)
Ejemplo n.º 49
0
    def test_close_connection(self):
        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.close_connection()
        m.shutdown.assert_called_once_with(socket.SHUT_RDWR)
        m.close.assert_called_once_with()
        self.assertIsNone(ws.connection)

        m = MagicMock()
        m.close = MagicMock(side_effect=RuntimeError)
        ws = WebSocket(sock=m)
        ws.close_connection()
        self.assertIsNone(ws.connection)
    def __init__(self, proto):
        """
        A :pep:`3156` ready websocket handler that works
        well in a coroutine-aware loop such as the one provided
        by the asyncio module.

        The provided `proto` instance is a
        :class:`asyncio.Protocol` subclass instance that will
        be used internally to read and write from the
        underlying transport.

        Because the base :class:`ws4py.websocket.WebSocket`
        class is still coupled a bit to the socket interface,
        we have to override a little more than necessary
        to play nice with the :pep:`3156` interface. Hopefully,
        some day this will be cleaned out.
        """
        _WebSocket.__init__(self, None)
        self.started = False
        self.proto = proto
Ejemplo n.º 51
0
    def __init__(self, proto):
        """
        A :pep:`3156` ready websocket handler that works
        well in a coroutine-aware loop such as the one provided
        by the asyncio module.

        The provided `proto` instance is a
        :class:`asyncio.Protocol` subclass instance that will
        be used internally to read and write from the
        underlying transport.

        Because the base :class:`ws4py.websocket.WebSocket`
        class is still coupled a bit to the socket interface,
        we have to override a little more than necessary
        to play nice with the :pep:`3156` interface. Hopefully,
        some day this will be cleaned out.
        """
        _WebSocket.__init__(self, None)
        self.started = False
        self.proto = proto
Ejemplo n.º 52
0
    def send(self, **message):
        """
        This overrides the ws4py-provided send to implement three new features:

        1) Instead of taking a string, this method treats its keyword arguments
           as the message, serializes them to JSON, and sends that.

        2) For subscription responses, we keep track of the most recent response
           we sent for the given subscription.  If neither the request or
           response have changed since the last time we pushed data back to the
           client for this subscription, we don't send anything.

        3) We lock when sending to ensure that our sends are thread-safe.
           Surprisingly, the "ws4py.threadedclient" class isn't thread-safe!

        4) Subscriptions firing will sometimes trigger a send on a websocket
           which has already been marked as closed.  When this happens we log a
           debug message and then exit without error.
        """
        if self.is_closed:
            log.debug('ignoring send on an already closed websocket: {}', message)
            self.unsubscribe_all()
            return

        message = {k: v for k, v in message.items() if v is not None}
        if 'data' in message and 'client' in message:
            fingerprint = _fingerprint(message['data'])
            client, callback = message['client'], message.get('callback')
            repeat_send = callback in self.cached_fingerprints[client]
            cached_fingerprint = self.cached_fingerprints[client].get(callback)
            self.cached_fingerprints[client][callback] = fingerprint
            if cached_fingerprint == fingerprint and repeat_send:
                return

        log.debug('sending {}', message)
        message = json.dumps(message, cls=sideboard.lib.serializer,
                                      separators=(',', ':'), sort_keys=True)
        with self.send_lock:
            if not self.is_closed:
                WebSocket.send(self, message)
Ejemplo n.º 53
0
    def __init__(self, url, protocols=None, extensions=None, heartbeat_freq=None):
        """
        A websocket client that implements :rfc:`6455` and provides a simple
        interface to communicate with a websocket server.

        This class works on its own but will block if not run in
        its own thread.

        When an instance of this class is created, a :py:mod:`socket`
        is created with the nagle's algorithm disabled and with
        the capacity to reuse a port that was just used.

        The address of the server will be extracted from the given
        websocket url.

        The websocket key is randomly generated, reset the
        `key` attribute if you want to provide yours.

        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

        sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        WebSocket.__init__(self, sock, protocols=protocols,
                           extensions=extensions,
                           heartbeat_freq=heartbeat_freq)
        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))
        self.url = url

        self.host = None
        self.scheme = None
        self.port = None
        self.resource = None

        self._parse_url()
Ejemplo n.º 54
0
    def __init__(self, *args, **kwargs):
        WebSocket.__init__(self, *args, **kwargs)
        common_domain_args = {
            'debugger': self.debugger(),
            'socket': self,
        }
        file_manager = FileManager(self)
        remote_object_manager = RemoteObjectManager()

        runtime_domain = RuntimeDomain(
            remote_object_manager,
            **common_domain_args)
        self.handlers = HandlerDomainSet(
            ConsoleDomain(**common_domain_args),
            DebuggerDomain(
                runtime_domain,
                file_manager,
                remote_object_manager,
                basepath=self.basepath(),
                **common_domain_args),
            PageDomain(**common_domain_args),
            runtime_domain,
        )
Ejemplo n.º 55
0
    def test_close_connection(self):
        m = MagicMock()
        ws = WebSocket(sock=m)
        ws.close_connection()
        m.shutdown.assert_called_once_with(socket.SHUT_RDWR)
        m.close.assert_called_once_with()
        self.assertIsNone(ws.connection)

        m = MagicMock()
        m.close = MagicMock(side_effect=RuntimeError)
        ws = WebSocket(sock=m)
        ws.close_connection()
        self.assertIsNone(ws.connection)
Ejemplo n.º 56
0
 def __init__(self, *args, **kw):
     WebSocket.__init__(self, *args, **kw)
     SUBSCRIBERS.add(self)
Ejemplo n.º 57
0
 def test_socket_error_on_receiving_more_bytes(self):
     m = MagicMock()
     m.recv = MagicMock(side_effect=socket.error)
     ws = WebSocket(sock=m)
     self.assertFalse(ws.once())
Ejemplo n.º 58
0
    def __init__(self, url, protocols=None, extensions=None,
                 heartbeat_freq=None, ssl_options=None, headers=None):
        """
        A websocket client that implements :rfc:`6455` and provides a simple
        interface to communicate with a websocket server.

        This class works on its own but will block if not run in
        its own thread.

        When an instance of this class is created, a :py:mod:`socket`
        is created. If the connection is a TCP socket,
        the nagle's algorithm is disabled.

        The address of the server will be extracted from the given
        websocket url.

        The websocket key is randomly generated, reset the
        `key` attribute if you want to provide yours.

        For instance to create a TCP client:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws://localhost/ws')


        Here is an example for a TCP client over SSL:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('wss://localhost/ws')


        Finally an example of a Unix-domain connection:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')

        Note that in this case, the initial Upgrade request
        will be sent to ``/``. You may need to change this
        by setting the resource explicitely before connecting:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')
           >>> ws.resource = '/ws'
           >>> ws.connect()

        You may provide extra headers by passing a list of tuples
        which must be unicode objects.

        """
        self.url = url
        self.host = None
        self.scheme = None
        self.port = None
        self.unix_socket_path = None
        self.resource = None
        self.ssl_options = ssl_options or {}
        self.extra_headers = headers or []

        self._parse_url()

        if self.unix_socket_path:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
        else:
            # Let's handle IPv4 and IPv6 addresses
            # Simplified from CherryPy's code
            try:
                family, socktype, proto, canonname, sa = socket.getaddrinfo(self.host, self.port,
                                                                            socket.AF_UNSPEC,
                                                                            socket.SOCK_STREAM,
                                                                            0, socket.AI_PASSIVE)[0]
            except socket.gaierror:
                family = socket.AF_INET
                if self.host.startswith('::'):
                    family = socket.AF_INET6

                socktype = socket.SOCK_STREAM
                proto = 0
                canonname = ""
                sa = (self.host, self.port, 0, 0)

            sock = socket.socket(family, socktype, proto)
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            if hasattr(socket, 'AF_INET6') and family == socket.AF_INET6 and \
              self.host.startswith('::'):
                try:
                    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
                except (AttributeError, socket.error):
                    pass

        WebSocket.__init__(self, sock, protocols=protocols,
                           extensions=extensions,
                           heartbeat_freq=heartbeat_freq)

        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))
Ejemplo n.º 59
0
 def test_no_bytes_were_read(self):
     m = MagicMock()
     m.recv.return_value = b''
     ws = WebSocket(sock=m)
     self.assertFalse(ws.once())