def __call__(self, environ, start_response):
     """ Hijack the main loop from the original thread and listen on events on Redis and Websockets"""
     websocket = None
     redis_context = self.redis_context()
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         self.process_request(request)
         channels = self.process_subscriptions(request)
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         redis_context.subscribe_channels(request, channels)
         websocket_fd = websocket.get_file_descriptor()
         redis_fd = redis_context.get_file_descriptor()
         while websocket and not websocket.closed:
             ready = self.select([websocket_fd, redis_fd], [], [])[0]
             for fd in ready:
                 if fd == websocket_fd:
                     message = websocket.receive()
                     redis_context.publish_message(message)
                 elif fd == redis_fd:
                     response = redis_context.parse_response()
                     if response[0] == 'message':
                         message = response[2]
                         websocket.send(message)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
     except WebSocketError, excpt:
         logger.warning('WebSocketError: ', exc_info=sys.exc_info())
         response = HttpResponse(status=1001, content='Websocket Closed')
 def __call__(self, environ, start_response):
     """ Hijack the main loop from the original thread and listen on events on Redis and Websockets"""
     websocket = None
     subscriber = self.Subscriber(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         self.process_request(request)
         channels = self.process_subscriptions(request)
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(
             ', '.join(channels)))
         subscriber.set_pubsub_channels(request, channels)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = subscriber.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         subscriber.send_persited_messages(websocket)
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     message = websocket.receive()
                     if message != redis_settings.WS4REDIS_HEARTBEAT:
                         subscriber.publish_message(message)
                 elif fd == redis_fd:
                     response = subscriber.parse_response()
                     if response[0] == 'message':
                         message = response[2]
                         websocket.send(message)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
             if redis_settings.WS4REDIS_HEARTBEAT:
                 websocket.send(redis_settings.WS4REDIS_HEARTBEAT)
     except WebSocketError, excpt:
         logger.warning('WebSocketError: ', exc_info=sys.exc_info())
         response = HttpResponse(status=1001, content='Websocket Closed')
Example #3
0
 def __call__(self, environ, start_response):
     """ Hijack the main loop from the original thread and listen on events on Redis and Websockets"""
     websocket = None
     redis_store = self.RedisStore(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         self.process_request(request)
         # Return access token
         access_key = self.authenticate(request)
         if not access_key:
             raise Exception("No access token found.")
         websocket = self.upgrade_websocket(environ, start_response)
         # logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         redis_store.subscribe(request, access_key)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = redis_store.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         redis_store.send_persited_messages(websocket)
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     message = websocket.receive()
                     redis_store.publish_message(message)
                 elif fd == redis_fd:
                     response = redis_store.parse_response()
                     if response[0] == 'message':
                         message = response[2]
                         websocket.send(message)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
     except WebSocketError, excpt:
         logger.warning('WebSocketError: ', exc_info=sys.exc_info())
         response = HttpResponse(status=1001, content='Websocket Closed')
 def __call__(self, environ, start_response):
     """ Hijack the main loop from the original thread and listen on events on Redis and Websockets"""
     websocket = None
     subscriber = self.Subscriber(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         self.process_request(request)
         channels = self.process_subscriptions(request)
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         subscriber.set_pubsub_channels(request, channels)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = subscriber.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         subscriber.send_persited_messages(websocket)
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     message = websocket.receive()
                     if message != redis_settings.WS4REDIS_HEARTBEAT:
                         subscriber.publish_message(message)
                 elif fd == redis_fd:
                     response = subscriber.parse_response()
                     if response[0] == 'message':
                         message = response[2]
                         websocket.send(message)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
             if redis_settings.WS4REDIS_HEARTBEAT:
                 websocket.send(redis_settings.WS4REDIS_HEARTBEAT)
     except WebSocketError, excpt:
         logger.warning('WebSocketError: ', exc_info=sys.exc_info())
         response = HttpResponse(status=1001, content='Websocket Closed')
 def __call__(self, environ, start_response):
     """ Hijack the main loop from the original thread and listen on events on Redis and Websockets"""
     websocket = None
     request = None
     subscriber = self.Subscriber(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         self.process_request(request)
         channels, echo_message = self.process_subscriptions(request)
         if callable(private_settings.WS4REDIS_ALLOWED_CHANNELS):
             channels = list(private_settings.WS4REDIS_ALLOWED_CHANNELS(request, channels))
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         subscriber.set_pubsub_channels(request, channels)
         subscriber.user_connect(request)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = subscriber.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         subscriber.send_persited_messages(websocket)
         recvmsg = None
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     recvmsg = RedisMessage(websocket.receive())
                     if recvmsg:
                         subscriber.publish_message(recvmsg)
                 elif fd == redis_fd:
                     sendmsg = RedisMessage(subscriber.parse_response())
                     if sendmsg and (echo_message or sendmsg != recvmsg):
                         websocket.send(sendmsg)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
             if private_settings.WS4REDIS_HEARTBEAT:
                 websocket.send(private_settings.WS4REDIS_HEARTBEAT)
     except WebSocketError as excpt:
         logger.warning('WebSocketError: ', exc_info=sys.exc_info())
         response = http.HttpResponse(status=1001, content='Websocket Closed')
     except UpgradeRequiredError as excpt:
         logger.info('Websocket upgrade required')
         response = http.HttpResponseBadRequest(status=426, content=excpt)
     except HandshakeError as excpt:
         logger.warning('HandshakeError: ', exc_info=sys.exc_info())
         response = http.HttpResponseBadRequest(content=excpt)
     except PermissionDenied as excpt:
         logger.warning('PermissionDenied: ', exc_info=sys.exc_info())
         response = http.HttpResponseForbidden(content=excpt)
     except Exception as excpt:
         logger.error('Other Exception: ', exc_info=sys.exc_info())
         response = http.HttpResponseServerError(content=excpt)
     else:
         response = http.HttpResponse()
     if websocket:
         subscriber.user_disconnect(request)
         websocket.close(code=1001, message='Websocket Closed')
     if hasattr(start_response, 'im_self') and not start_response.im_self.headers_sent:
         logger.warning('Staring late response on websocket')
         status_text = STATUS_CODE_TEXT.get(response.status_code, 'UNKNOWN STATUS CODE')
         status = '{0} {1}'.format(response.status_code, status_text)
         start_response(force_str(status), response._headers.values())
     logger.info('Finish long living response with status code: '.format(response.status_code))
     return response
 def __call__(self, environ, start_response):
     """
     Hijack the main loop from the original thread and listen on events on the Redis
     and the Websocket filedescriptors.
     """
     websocket = None
     subscriber = self.Subscriber(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         if callable(private_settings.WS4REDIS_PROCESS_REQUEST):
             private_settings.WS4REDIS_PROCESS_REQUEST(request)
         else:
             self.process_request(request)
         channels, echo_message = self.process_subscriptions(request)
         if callable(private_settings.WS4REDIS_ALLOWED_CHANNELS):
             channels = list(private_settings.WS4REDIS_ALLOWED_CHANNELS(request, channels))
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         subscriber.set_pubsub_channels(request, channels)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = subscriber.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         subscriber.send_persited_messages(websocket)
         recvmsg = None
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     recvmsg = RedisMessage(websocket.receive())
                     if recvmsg:
                         subscriber.publish_message(recvmsg)
                 elif fd == redis_fd:
                     sendmsg = RedisMessage(subscriber.parse_response())
                     if sendmsg and (echo_message or sendmsg != recvmsg):
                         websocket.send(sendmsg)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
             # Check again that the websocket is closed before sending the heartbeat,
             # because the websocket can closed previously in the loop.
             if private_settings.WS4REDIS_HEARTBEAT and not websocket.closed:
                 websocket.send(private_settings.WS4REDIS_HEARTBEAT)
     except WebSocketError as excpt:
         logger.warning('WebSocketError: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponse(status=1001, content='Websocket Closed')
     except UpgradeRequiredError as excpt:
         logger.info('Websocket upgrade required')
         response = http.HttpResponseBadRequest(status=426, content=excpt)
     except HandshakeError as excpt:
         logger.warning('HandshakeError: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseBadRequest(content=excpt)
     except PermissionDenied as excpt:
         logger.warning('PermissionDenied: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseForbidden(content=excpt)
     except Exception as excpt:
         logger.error('Other Exception: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseServerError(content=excpt)
     else:
         response = http.HttpResponse()
     finally:
         subscriber.release()
         if websocket:
             websocket.close(code=1001, message='Websocket Closed')
         else:
             logger.warning('Starting late response on websocket')
             status_text = http_client.responses.get(response.status_code, 'UNKNOWN STATUS CODE')
             status = '{0} {1}'.format(response.status_code, status_text)
             headers = response._headers.values()
             if six.PY3:
                 headers = list(headers)
             start_response(force_str(status), headers)
             logger.info('Finish non-websocket response with status code: {}'.format(response.status_code))
     return response
 def __call__(self, environ, start_response):
     """
     Hijack the main loop from the original thread and listen on events on the Redis
     and the Websocket filedescriptors.
     """
     websocket = None
     subscriber = self.Subscriber(self._redis_connection)
     try:
         self.assure_protocol_requirements(environ)
         request = WSGIRequest(environ)
         if callable(private_settings.WS4REDIS_PROCESS_REQUEST):
             private_settings.WS4REDIS_PROCESS_REQUEST(request)
         else:
             self.process_request(request)
         channels, echo_message = self.process_subscriptions(request)
         if callable(private_settings.WS4REDIS_ALLOWED_CHANNELS):
             channels = list(private_settings.WS4REDIS_ALLOWED_CHANNELS(request, channels))
         websocket = self.upgrade_websocket(environ, start_response)
         logger.debug('Subscribed to channels: {0}'.format(', '.join(channels)))
         subscriber.set_pubsub_channels(request, channels)
         websocket_fd = websocket.get_file_descriptor()
         listening_fds = [websocket_fd]
         redis_fd = subscriber.get_file_descriptor()
         if redis_fd:
             listening_fds.append(redis_fd)
         subscriber.send_persited_messages(websocket)
         recvmsg = None
         while websocket and not websocket.closed:
             ready = self.select(listening_fds, [], [], 4.0)[0]
             if not ready:
                 # flush empty socket
                 websocket.flush()
             for fd in ready:
                 if fd == websocket_fd:
                     recvmsg = RedisMessage(websocket.receive())
                     if recvmsg:
                         subscriber.publish_message(recvmsg)
                 elif fd == redis_fd:
                     sendmsg = RedisMessage(subscriber.parse_response())
                     if sendmsg and (echo_message or sendmsg != recvmsg):
                         websocket.send(sendmsg)
                 else:
                     logger.error('Invalid file descriptor: {0}'.format(fd))
             if private_settings.WS4REDIS_HEARTBEAT:
                 websocket.send(private_settings.WS4REDIS_HEARTBEAT)
     except WebSocketError as excpt:
         logger.warning('WebSocketError: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponse(status=1001, content='Websocket Closed')
     except UpgradeRequiredError as excpt:
         logger.info('Websocket upgrade required')
         response = http.HttpResponseBadRequest(status=426, content=excpt)
     except HandshakeError as excpt:
         logger.warning('HandshakeError: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseBadRequest(content=excpt)
     except PermissionDenied as excpt:
         logger.warning('PermissionDenied: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseForbidden(content=excpt)
     except Exception as excpt:
         logger.error('Other Exception: {}'.format(excpt), exc_info=sys.exc_info())
         response = http.HttpResponseServerError(content=excpt)
     else:
         response = http.HttpResponse()
     finally:
         subscriber.release()
         if websocket:
             websocket.close(code=1001, message='Websocket Closed')
         else:
             logger.warning('Starting late response on websocket')
             status_text = STATUS_CODE_TEXT.get(response.status_code, 'UNKNOWN STATUS CODE')
             status = '{0} {1}'.format(response.status_code, status_text)
             start_response(force_str(status), response._headers.values())
             logger.info('Finish non-websocket response with status code: {}'.format(response.status_code))
     return response
Example #8
0
                    elif fd == redis_fd:
                        response = redis_store.parse_response()
                        if response[0] == 'message':
                            message = response[2]
                            websocket.send(message)
                    else:
                        logger.error('Invalid file descriptor: {0}'.format(fd))
        except WebSocketError, excpt:
            logger.warning('WebSocketError: ', exc_info=sys.exc_info())
            response = HttpResponse(status=1001, content='Websocket Closed')
        except UpgradeRequiredError:
            logger.info('Websocket upgrade required')
            response = HttpResponseBadRequest(status=426, content=excpt)
        except HandshakeError, excpt:
            logger.warning('HandshakeError: ', exc_info=sys.exc_info())
            response = HttpResponseBadRequest(content=excpt)
        except Exception, excpt:
            logger.error('Other Exception: ', exc_info=sys.exc_info())
            response = HttpResponseServerError(content=excpt)
        else:
            response = HttpResponse()
        if websocket:
            websocket.close(code=1001, message='Websocket Closed')
        if hasattr(start_response,
                   'im_self') and not start_response.im_self.headers_sent:
            status_text = STATUS_CODE_TEXT.get(response.status_code,
                                               'UNKNOWN STATUS CODE')
            status = '{0} {1}'.format(response.status_code, status_text)
            start_response(force_str(status), response._headers.values())
        return response
Example #9
0
                        redis_store.publish_message(message)
                    elif fd == redis_fd:
                        response = redis_store.parse_response()
                        if response[0] == 'message':
                            message = response[2]
                            websocket.send(message)
                    else:
                        logger.error('Invalid file descriptor: {0}'.format(fd))
        except WebSocketError, excpt:
            logger.warning('WebSocketError: ', exc_info=sys.exc_info())
            response = HttpResponse(status=1001, content='Websocket Closed')
        except UpgradeRequiredError:
            logger.info('Websocket upgrade required')
            response = HttpResponseBadRequest(status=426, content=excpt)
        except HandshakeError, excpt:
            logger.warning('HandshakeError: ', exc_info=sys.exc_info())
            response = HttpResponseBadRequest(content=excpt)
        except Exception, excpt:
            logger.error('Other Exception: ', exc_info=sys.exc_info())
            response = HttpResponseServerError(content=excpt)
        else:
            response = HttpResponse()
        if websocket:
            redis_store.unsubscribe(request, access_key)
            websocket.close(code=1001, message='Websocket Closed')
        if hasattr(start_response, 'im_self') and not start_response.im_self.headers_sent:
            status_text = STATUS_CODE_TEXT.get(response.status_code, 'UNKNOWN STATUS CODE')
            status = '{0} {1}'.format(response.status_code, status_text)
            start_response(force_str(status), response._headers.values())
        return response