async def handleHandshake(state: ConnectionState, ws, app: Dict, pdu: JsonDict, serializedPdu: str): authMethod = pdu.get('body', {}).get('method') if authMethod != 'role_secret': errMsg = f'invalid auth method: {authMethod}' logging.warning(errMsg) response = { "action": f"auth/handshake/error", "id": pdu.get('id', 1), "body": { "error": errMsg }, } await state.respond(ws, response) return role = pdu.get('body', {}).get('data', {}).get('role') state.role = role state.nonce = generateNonce() response = { "action": "auth/handshake/ok", "id": pdu.get('id', 1), "body": { "data": { "nonce": state.nonce, "version": getVersion(), "connection_id": state.connection_id, "node": platform.uname().node, } }, } await state.respond(ws, response)
async def process_request(self, path, request_headers): if path == '/health/': return http.HTTPStatus.OK, [], b'OK\n' if path == '/version/': return http.HTTPStatus.OK, [], bytes(getVersion(), 'utf8') + b'\n' if path == '/': return http.HTTPStatus.OK, [], bytes(getBanner(), 'utf8') + b'\n' appkey = parseAppKey(path) if appkey is None or not ServerProtocol.appsConfig.isAppKeyValid( appkey): logging.warning( f'Rejecting request with invalid appkey for {path}') logging.warning(f'Request headers: {request_headers}') return http.HTTPStatus.FORBIDDEN, [], b'KO\n' self.requestHeaders = request_headers
async def setup(self, stop=None, block=False): '''It would be good to unify better unittest mode versus command mode, and get rid of block ''' await self.init_app() handler = functools.partial(cobraHandlerWrapper, app=self.app, redisUrls=self.redisUrls) ServerProtocol.appsConfig = self.app['apps_config'] extraHeaders = { "X-Cobra-Node": platform.uname().node, "X-Cobra-Version": getVersion(), } if block: async with websockets.serve( handler, self.host, self.port, create_protocol=ServerProtocol, subprotocols=['json'], ping_timeout=None, ping_interval=None, max_size=self.messageMaxSize, extra_headers=extraHeaders, ) as self.server: await stop await self.cleanup() else: self.server = await websockets.serve( handler, self.host, self.port, create_protocol=ServerProtocol, subprotocols=['json'], ping_timeout=None, ping_interval=None, max_size=self.messageMaxSize, extra_headers=extraHeaders, )
def getBanner(): p = psutil.Process(os.getpid()) createTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p.create_time())) banner = r''' ___ _ / __\___ | |__ _ __ __ _ / / / _ \| '_ \| '__/ _` | / /__| (_) | |_) | | | (_| | \____/\___/|_.__/|_| \__,_| Cobra is a realtime messaging server using Python3, WebSockets and Redis. Version {} Running on {} Start time {} '''.format(getVersion(), platform.uname().node, createTime) return banner
def run( host, port, redis_urls, redis_password, redis_cluster, apps_config_path, apps_config_path_content, debug_memory, debug_memory_no_tracemalloc, debug_memory_print_all_tasks, sentry, sentry_url, prod, no_stats, max_subscriptions, idle_timeout, disable_redis_startup_probing, redis_startup_probing_timeout, environment, message_max_size, pidfile, ): '''Run the cobra server \b cobra run --redis_urls 'redis://localhost:7001;redis://localhost:7002' \b env COBRA_REDIS_PASSWORD=foobared cobra run ''' if prod: os.environ['COBRA_PROD'] = '1' if sentry and sentry_url: sentry_sdk.init( sentry_url, release=getVersion(), environment=environment, attach_stacktrace=True, ) if pidfile: pid = str(os.getpid()) with open(pidfile, 'w') as f: f.write(pid) if apps_config_path_content: apps_config_path = generateAppsConfig(apps_config_path_content) if not apps_config_path: logging.error( f'Invalid apps config path content: {apps_config_path_content}' ) logging.error( f'(usually configured with $COBRA_APPS_CONFIG_CONTENT)') logging.error(f'Generate it with `gzip -c ~/.cobra.yaml | base64`') sys.exit(1) apps_config_path_content = '<cleared>' os.environ['COBRA_APPS_CONFIG'] = apps_config_path print('runServer', locals()) runner = AppRunner( host, port, redis_urls, redis_password, redis_cluster, apps_config_path, debug_memory, debug_memory_no_tracemalloc, debug_memory_print_all_tasks, not no_stats, max_subscriptions, idle_timeout, probeRedisOnStartup=not disable_redis_startup_probing, redisStartupProbingTimeout=redis_startup_probing_timeout, messageMaxSize=message_max_size, ) loop = asyncio.get_event_loop() stop = loop.create_future() asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, stop.set_result, None) try: runner.run(stop) except Exception as e: logging.fatal(f'Cannot start cobra server: {e}') sys.exit(1)