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')
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
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: 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
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
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') 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: 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
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') except UpgradeRequiredError, excpt: 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: 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())