Ejemplo n.º 1
0
    async def websocket_handshake(self, request):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue)
        self.websocket.connection_made(request.transport)
        return self.websocket
Ejemplo n.º 2
0
class WebSocketProtocol(HttpProtocol):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.websocket = None

    def connection_timeout(self):
        # timeouts make no sense for websocket routes
        if self.websocket is None:
            super().connection_timeout()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            # pass the data to the websocket protocol
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except HttpParserUpgrade:
                # this is okay, it just indicates we've got an upgrade request
                pass

    def write_response(self, response):
        if self.websocket is not None:
            # websocket requests do not write a response
            self.transport.close()
        else:
            super().write_response(response)

    async def websocket_handshake(self, request):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol()
        self.websocket.connection_made(request.transport)
        return self.websocket
async def socket_coroutine(socket: websockets.WebSocketCommonProtocol, path,
                           network_queue: asyncio.Queue):
    print(f'Accepted TCP connection from {socket.remote_address}')
    while True:
        try:
            data = await network_queue.get()
            await socket.send(f"{json.dumps(data)}")
        finally:
            socket.close()
        def switch_protocols():
            ws_protocol = WebSocketCommonProtocol()
            transport._protocol = ws_protocol
            ws_protocol.connection_made(transport)

            # Ensure aiohttp doesn't interfere.
            http_protocol.transport = None

            asyncio. async (run_ws_handler(ws_protocol))
Ejemplo n.º 5
0
    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            raise InvalidUsage("Invalid websocket request")

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            close_timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit,
            ping_interval=self.websocket_ping_interval,
            ping_timeout=self.websocket_ping_timeout,
        )
        # we use WebSocketCommonProtocol because we don't want the handshake
        # logic from WebSocketServerProtocol; however, we must tell it that
        # we're running on the server side
        self.websocket.is_client = False
        self.websocket.side = "server"
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 6
0
    async def websocket_handshake(self, request):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue
        )
        self.websocket.connection_made(request.transport)
        return self.websocket
Ejemplo n.º 7
0
async def chat(request, ws: WebSocketCommonProtocol):
    print('Connected to WS Server!')
    print(request)
    print(ws)
    user_id = request.args.get('user_id')
    nickname = request.args.get('nickname')
    # 1. Authenticate User (create_or_update)
    db = app.db
    await db.users.update_one({'user_id': user_id},
                              {'$set': {
                                  'nickname': nickname
                              }}, True)
    await ws.send(
        ujson.dumps({
            'type': 'LOGIN',
            'user_id': user_id,
            'nickname': nickname,
            'profile_url':
            'https://sendbird.com/main/img/profiles/profile_11_512px.png',
            'ping_interval': 15,
            'pong_timeout': 5,
            'reconnect_interval': 3
        }))
    # 2. PING/PONG
    while True:
        try:
            msg = await asyncio.wait_for(ws.recv(), timeout=90.0)
            loaded_msg = ujson.loads(msg)
            await message_handler(loaded_msg, ws)
        except Exception as e:
            # TODO: leave user from channel
            logging.error('WS RECV Error: ' + repr(e))
            break
Ejemplo n.º 8
0
    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        subprotocol = None
        if subprotocols and 'Sec-Websocket-Protocol' in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers['Sec-Websocket-Protocol'].split(',')
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    set_header('Sec-Websocket-Protocol', subprotocol)
                    break

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit)
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 9
0
    async def _ws(self, sanic_request: SanicRequest, ws: WebSocket):
        recv = None
        pending = set()

        def sender(notification: Notification) -> Future:
            return ensure_future(
                self._ws_notification(sender_ctx(notification)))

        notifier = Notifier(ws, sender, self._finalise_future)
        root_ctx = Context(self.app, sanic_request, ws, notifier)
        sender_ctx = root_ctx(Directions.outgoing)

        while ws.open:
            if recv not in pending:
                recv = ensure_future(ws.recv())
                pending.add(recv)

            try:
                done, pending = await wait(pending,
                                           return_when=FIRST_COMPLETED)
            except CancelledError:
                for fut in pending:
                    self._finalise_future(fut)

                break

            for fut in done:
                result = self._finalise_future(fut)

                if not result:
                    continue

                if isinstance(result, Response):
                    pending.add(self._ws_outgoing(root_ctx(result)))
                    continue

                obj = self._parse_json(result)

                if isinstance(obj, Response):
                    pending.add(self._ws_outgoing(root_ctx(obj)))
                    continue

                incoming = self._parse_message(obj)

                if isinstance(incoming, Response):
                    pending.add(self._ws_outgoing(root_ctx(incoming)))
                    continue

                ctx = root_ctx(incoming)

                if not self._handle_incoming(
                        ctx, lambda x: pending.add(self._ws_outgoing(ctx(x))),
                        pending.add):
                    continue

        notifier.cancel()

        for fut in pending:
            fut.cancel()
Ejemplo n.º 10
0
    async def websocket_handshake(self, request, subprotocols=None):
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            msg = "Invalid websocket request received."
            if self.debug:
                msg += "\n" + traceback.format_exc()
            self.logger.error(msg)
            self.on_response(msg)
            raise RuntimeError(msg)

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.config.ws_timeout,
            max_size=self.config.ws_max_size,
            max_queue=self.config.ws_max_queue,
            read_limit=self.config.ws_read_limit,
            write_limit=self.config.ws_write_limit,
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 11
0
    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            raise InvalidUsage("Invalid websocket request")

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit,
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 12
0
  def data_received(self, data):
    try:
      if self.enabled:
        self.websocket.data_received(data)
      else:
        self.parser.feed_data(data)

    except HttpParserError as err:
      logger.debug(err)
      import ipdb; ipdb.set_trace()
      exception = panic_exceptions.InvalidUsage('Bad Request')
      self.write_error(exception)

    except HttpParserUpgrade as err:
      logger.debug(err)
      self.enabled = True

      response = panic_response.Response(b'')
      try:
        key = handshake.check_request(lambda x: self.headers.get(x).value)
        handshake.build_response(response.assimilate, key)
      except InvalidHandshake:
        exception = panic_exceptions.InvalidUsage('Invalid websocket request')
        self.write_error(exception)

      else:
        self.transport.write(response.channel('1.1'))
        self.websocket = WebSocketCommonProtocol(
            timeout=self.timeout,
            max_size=self.max_size,
            max_queue=self.max_queue,
            read_limit=self.read_limit,
            write_limit=self.write_limit)

        self.websocket.subprotocol = None
        #subprotocol
        self.websocket.connection_made(self.transport)
        self.websocket.connection_open()

        self._request_handler_task = self.params.loop.create_task(
            self.params.request_handler(self.request, self.websocket, self.transport))
 async def _consumer_handler(self,
                             websocket: websockets.WebSocketCommonProtocol):
     # the connection object to receive messages from and add them ito the queue.
     try:
         while True:
             # conn_list : Create a list of connected clients
             msg = await asyncio.wait_for(websocket.recv(), timeout=10.0)
             # register websocket
             await websocket.send(msg)
             self.USERS.add(websocket)
             self.first_conn_count += 1
             print("connected websocket!")
     except asyncio.TimeoutError:
         print("finished! connected client!", str(self.first_conn_count))
Ejemplo n.º 14
0
 async def accept_connection(self, websocket: WebSocketCommonProtocol):
     while True:
         try:
             request = await asyncio.wait_for(websocket.recv(), timeout=0.01)
         except TimeoutError:
             pass
         except ConnectionClosedOK:
             return
         else:
             parsed_request = json.loads(request)
             if 'type' in parsed_request and parsed_request['type'] == RequestType.SUBSCRIBE.value:
                 Logger.success('[Websocket Server]: new connection was added, {}'.format(websocket.local_address))
                 self.connections.append(websocket)
         finally:
             await asyncio.sleep(1)
Ejemplo n.º 15
0
    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        subprotocol = None
        if subprotocols and 'Sec-Websocket-Protocol' in request.headers:
            # select a subprotocol
            client_subprotocols = [p.strip() for p in request.headers[
                'Sec-Websocket-Protocol'].split(',')]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    set_header('Sec-Websocket-Protocol', subprotocol)
                    break

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 16
0
    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            raise InvalidUsage("Invalid websocket request")

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit,
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 17
0
class WebSocketProtocol(HttpProtocol):
    def __init__(self,
                 *args,
                 websocket_max_size=None,
                 websocket_max_queue=None,
                 **kwargs):
        super().__init__(*args, **kwargs)
        self.websocket = None
        self.websocket_max_size = websocket_max_size
        self.websocket_max_queue = websocket_max_queue

    # timeouts make no sense for websocket routes
    def request_timeout_callback(self):
        if self.websocket is None:
            super().request_timeout_callback()

    def response_timeout_callback(self):
        if self.websocket is None:
            super().response_timeout_callback()

    def keep_alive_timeout_callback(self):
        if self.websocket is None:
            super().keep_alive_timeout_callback()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            # pass the data to the websocket protocol
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except HttpParserUpgrade:
                # this is okay, it just indicates we've got an upgrade request
                pass

    def write_response(self, response):
        if self.websocket is not None:
            # websocket requests do not write a response
            self.transport.close()
        else:
            super().write_response(response)

    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        subprotocol = None
        if subprotocols and 'Sec-Websocket-Protocol' in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers['Sec-Websocket-Protocol'].split(',')
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    set_header('Sec-Websocket-Protocol', subprotocol)
                    break

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue)
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 18
0
class WebSocketProtocol(HttpProtocol):
    def request_timeout_callback(self):
        if self.websocket is None:
            super().request_timeout_callback()

    def response_timeout_callback(self):
        if self.websocket is None:
            super().response_timeout_callback()

    def timeout_keep_alive_handler(self):
        if self.websocket is None:
            super().timeout_keep_alive_handler()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except httptools.HttpParserUpgrade:
                pass

    def write_response(self, response):
        if self.websocket is not None:
            self.transport.close()
        else:
            super().on_response(response)

    async def websocket_handshake(self, request, subprotocols=None):
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            msg = "Invalid websocket request received."
            if self.debug:
                msg += "\n" + traceback.format_exc()
            self.logger.error(msg)
            self.on_response(msg)
            raise RuntimeError(msg)

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.config.ws_timeout,
            max_size=self.config.ws_max_size,
            max_queue=self.config.ws_max_queue,
            read_limit=self.config.ws_read_limit,
            write_limit=self.config.ws_write_limit,
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
 async def receive_message(self, app, ws: WebSocketCommonProtocol):
     return ws.recv()
Ejemplo n.º 20
0
class WebSocketProtocol(asyncio.Protocol):
  def __init__(self, params: panic_datatypes.ServerParams):
    self.enabled = False
    self.params = params
    self.websocket = None
    self.transport = None
    self.timeout = params.request_timeout or 10
    self.max_size = 2 ** 20
    self.max_queue = 2 ** 5
    self.read_limit =  2 ** 16
    self.write_limit = 2 ** 16

    self.url = None
    self.connections = params.connections

    self.request = None
    self.headers = panic_datatypes.HTTPHeaders()
    self.parser = HttpRequestParser(self)

    self._last_request_time = None

    self._identity = uuid.uuid4()


  def connection_made(self, transport):
    self.connections.add(self)
    self._timeout_handler = self.params.loop.call_later(self.timeout, self.connection_timeout)
    self.transport = transport
    self._last_request_time = datetime.datetime.utcnow()

  def connection_lost(self, exc):
    self.connections.discard(self)
    self._timeout_handler.cancel()
    self.cleanup()

  def cleanup(self):
    self.websocket = None
    self.transport = None
    self.timeout = 10
    self.max_size = 1
    self.max_queue = 1
    self.read_limit = 2 ** 16
    self.write_limit = 2 ** 16
    self.enabled = False
    self.url = None
    logger.warn('handle connections')
    self.connections = None
    self.request = None
    self.headers = None
    self.parser = None
    self._last_request_time = None
    self._request_handler_task = None

  def connection_timeout(self):
    time_elapsed = datetime.datetime.utcnow() - self._last_request_time
    seconds_elapsed = round(time_elapsed.seconds + float('0.%d' % time_elapsed.microseconds))
    if seconds_elapsed <= self.timeout:
      logger.info('Handler Timed out for WebSocket/Channel')

      #import ipdb; ipdb.set_trace()
      pass
      #if self._request_handler_task:
      #  self._request_handler_task.cancel()

      #exception = panic_exceptions.RequestTimeout('Request Timeout')
      #self.write_error(exception)

    else:
      time_left = self.timeout - seconds_elapsed
      self._timeout_handler = self.params.loop.call_later(time_left, self.connection_timeout)


  def data_received(self, data):
    try:
      if self.enabled:
        self.websocket.data_received(data)
      else:
        self.parser.feed_data(data)

    except HttpParserError as err:
      logger.debug(err)
      import ipdb; ipdb.set_trace()
      exception = panic_exceptions.InvalidUsage('Bad Request')
      self.write_error(exception)

    except HttpParserUpgrade as err:
      logger.debug(err)
      self.enabled = True

      response = panic_response.Response(b'')
      try:
        key = handshake.check_request(lambda x: self.headers.get(x).value)
        handshake.build_response(response.assimilate, key)
      except InvalidHandshake:
        exception = panic_exceptions.InvalidUsage('Invalid websocket request')
        self.write_error(exception)

      else:
        self.transport.write(response.channel('1.1'))
        self.websocket = WebSocketCommonProtocol(
            timeout=self.timeout,
            max_size=self.max_size,
            max_queue=self.max_queue,
            read_limit=self.read_limit,
            write_limit=self.write_limit)

        self.websocket.subprotocol = None
        #subprotocol
        self.websocket.connection_made(self.transport)
        self.websocket.connection_open()

        self._request_handler_task = self.params.loop.create_task(
            self.params.request_handler(self.request, self.websocket, self.transport))

  def on_url(self, url):
    self.url = url

  def on_message_complete(self):
    pass
    #self._request_handler = self.paramsself.params
    #self._request_handler_task = self.params.loop.create_task(
    #    self.params.request_handler(self.request, self.write_response))

  def on_header(self, name, value):
    self.headers.append(name.decode(), value.decode('utf-8'))

  def on_headers_complete(self):
    remote_addr = self.transport.get_extra_info('peername')
    if remote_addr:
      self.headers.append(remote_addr[0], str(remote_addr[1]))

    self.request = panic_request.Request(
      url = self.url,
      headers = self.headers,
      version = self.parser.get_http_version(),
      method = panic_datatypes.HTTPMethod.channel
    )

  def write_response(self, response):
    self.transport.close()

  def request_timeout_callback(self):
    if self.websocket is None:
      return super(WebSocketProtocol, self).request_timeout_callback()

  def write_error(self, exception):
    try:
      response = self.params.error_handler(self.request, exception)
      version = self.request.version if self.request else '1.1'
      self.transport.write(response.output(float(version)))
      self.transport.close()
    except Exception as err:
      # logger.exception(err)
      import traceback
      traceback.print_stack()
      import ipdb;ipdb.set_trace()
      self.signal.stopped 
      import sys; sys.exit(1)
      self.bail_out("Writing error failed, connection closed {}".format(e))
Ejemplo n.º 21
0
class WebSocketProtocol(HttpProtocol):
    def __init__(
        self,
        *args,
        websocket_timeout=10,
        websocket_max_size=None,
        websocket_max_queue=None,
        websocket_read_limit=2 ** 16,
        websocket_write_limit=2 ** 16,
        **kwargs
    ):
        super().__init__(*args, **kwargs)
        self.websocket = None
        self.websocket_timeout = websocket_timeout
        self.websocket_max_size = websocket_max_size
        self.websocket_max_queue = websocket_max_queue
        self.websocket_read_limit = websocket_read_limit
        self.websocket_write_limit = websocket_write_limit

    # timeouts make no sense for websocket routes
    def request_timeout_callback(self):
        if self.websocket is None:
            super().request_timeout_callback()

    def response_timeout_callback(self):
        if self.websocket is None:
            super().response_timeout_callback()

    def keep_alive_timeout_callback(self):
        if self.websocket is None:
            super().keep_alive_timeout_callback()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            # pass the data to the websocket protocol
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except HttpParserUpgrade:
                # this is okay, it just indicates we've got an upgrade request
                pass

    def write_response(self, response):
        if self.websocket is not None:
            # websocket requests do not write a response
            self.transport.close()
        else:
            super().write_response(response)

    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            raise InvalidUsage("Invalid websocket request")

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit,
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket
Ejemplo n.º 22
0
class WebSocketProtocol(HttpProtocol):
    def __init__(self, *args, websocket_max_size=None,
                 websocket_max_queue=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.websocket = None
        self.websocket_max_size = websocket_max_size
        self.websocket_max_queue = websocket_max_queue

    def connection_timeout(self):
        # timeouts make no sense for websocket routes
        if self.websocket is None:
            super().connection_timeout()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            # pass the data to the websocket protocol
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except HttpParserUpgrade:
                # this is okay, it just indicates we've got an upgrade request
                pass

    def write_response(self, response):
        if self.websocket is not None:
            # websocket requests do not write a response
            self.transport.close()
        else:
            super().write_response(response)

    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        subprotocol = None
        if subprotocols and 'Sec-Websocket-Protocol' in request.headers:
            # select a subprotocol
            client_subprotocols = [p.strip() for p in request.headers[
                'Sec-Websocket-Protocol'].split(',')]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    set_header('Sec-Websocket-Protocol', subprotocol)
                    break

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue
        )
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        return self.websocket
Ejemplo n.º 23
0
class WebSocketProtocol(HttpProtocol):
    def __init__(
        self,
        *args,
        websocket_timeout=10,
        websocket_max_size=None,
        websocket_max_queue=None,
        websocket_read_limit=2 ** 16,
        websocket_write_limit=2 ** 16,
        **kwargs
    ):
        super().__init__(*args, **kwargs)
        self.websocket = None
        # self.app = None
        self.websocket_timeout = websocket_timeout
        self.websocket_max_size = websocket_max_size
        self.websocket_max_queue = websocket_max_queue
        self.websocket_read_limit = websocket_read_limit
        self.websocket_write_limit = websocket_write_limit

    # timeouts make no sense for websocket routes
    def request_timeout_callback(self):
        if self.websocket is None:
            super().request_timeout_callback()

    def response_timeout_callback(self):
        if self.websocket is None:
            super().response_timeout_callback()

    def keep_alive_timeout_callback(self):
        if self.websocket is None:
            super().keep_alive_timeout_callback()

    def connection_lost(self, exc):
        if self.websocket is not None:
            self.websocket.connection_lost(exc)
        super().connection_lost(exc)

    def data_received(self, data):
        if self.websocket is not None:
            # pass the data to the websocket protocol
            self.websocket.data_received(data)
        else:
            try:
                super().data_received(data)
            except HttpParserUpgrade:
                # this is okay, it just indicates we've got an upgrade request
                pass

    def write_response(self, response):
        if self.websocket is not None:
            # websocket requests do not write a response
            self.transport.close()
        else:
            super().write_response(response)

    async def websocket_handshake(self, request, subprotocols=None):
        # let the websockets package do the handshake with the client
        headers = {}

        try:
            key = handshake.check_request(request.headers)
            handshake.build_response(headers, key)
        except InvalidHandshake:
            raise InvalidUsage("Invalid websocket request")

        subprotocol = None
        if subprotocols and "Sec-Websocket-Protocol" in request.headers:
            # select a subprotocol
            client_subprotocols = [
                p.strip()
                for p in request.headers["Sec-Websocket-Protocol"].split(",")
            ]
            for p in client_subprotocols:
                if p in subprotocols:
                    subprotocol = p
                    headers["Sec-Websocket-Protocol"] = subprotocol
                    break

        # write the 101 response back to the client
        rv = b"HTTP/1.1 101 Switching Protocols\r\n"
        for k, v in headers.items():
            rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n"
        rv += b"\r\n"
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            timeout=self.websocket_timeout,
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue,
            read_limit=self.websocket_read_limit,
            write_limit=self.websocket_write_limit,
        )
        # Following two lines are required for websockets 8.x
        self.websocket.is_client = False
        self.websocket.side = "server"
        self.websocket.subprotocol = subprotocol
        self.websocket.connection_made(request.transport)
        self.websocket.connection_open()
        return self.websocket