async def cors_middleware(ctx: Context, nxt: typing.Callable): # settings LEMON_CORS_ORIGIN_WHITELIST = settings.LEMON_CORS_ORIGIN_WHITELIST LEMON_CORS_ORIGIN_REGEX_WHITELIST = settings.LEMON_CORS_ORIGIN_REGEX_WHITELIST LEMON_CORS_ALLOW_METHODS = settings.LEMON_CORS_ALLOW_METHODS LEMON_CORS_ALLOW_HEADERS = settings.LEMON_CORS_ALLOW_HEADERS LEMON_CORS_EXPOSE_HEADERS = settings.LEMON_CORS_EXPOSE_HEADERS LEMON_CORS_ALLOW_CREDENTIALS = settings.LEMON_CORS_ALLOW_CREDENTIALS LEMON_CORS_MAX_AGE = settings.LEMON_CORS_MAX_AGE headers = ctx.req.headers origin = headers.get('origin', None) # pass request if origin is None: return await nxt() # preflight request if ctx.req.method == 'OPTIONS': acrm = headers.get('access-control-request-method', None) acrh = headers.get('access-control-request-headers', None) if acrm is None: return await nxt() matched = False for domain in LEMON_CORS_ORIGIN_WHITELIST: if domain == origin: matched = True for domain_pattern in LEMON_CORS_ORIGIN_REGEX_WHITELIST: if re.match(domain_pattern, origin): matched = True if matched is False: ctx.status = 200 return ctx.res.headers['access-control-allow-origin'] = origin if LEMON_CORS_ALLOW_CREDENTIALS: ctx.res.headers['access-control-allow-credentials'] = 'true' ctx.res.headers['access-control-max-age'] = LEMON_CORS_MAX_AGE ctx.res.headers['access-control-allow-methods'] = ','.join(LEMON_CORS_ALLOW_METHODS) ctx.res.headers['access-control-allow-headers'] = ','.join(LEMON_CORS_ALLOW_HEADERS) or acrh # stop request ctx.status = 204 return # cross origin request ctx.res.headers['access-control-allow-origin'] = origin if LEMON_CORS_ALLOW_CREDENTIALS: ctx.res.headers['access-control-allow-credentials'] = 'true' if LEMON_CORS_EXPOSE_HEADERS: ctx.res.headers['access-control-expose-headers'] = ','.join(LEMON_CORS_EXPOSE_HEADERS) return await nxt()
async def lemon_error_middleware(ctx: Context, nxt): """Catch the final exception""" try: await nxt() except HttpError as e: ctx.body = e.body ctx.status = e.status except Exception as e: error_logger.error(e) ctx.status = 500 ctx.body = ctx.body or 'INTERNAL ERROR'
async def exception_middleware(ctx: Context, nxt: typing.Callable) -> typing.Any: """Catch the final exception""" try: return await nxt() except GeneralException as e: ctx.body = e.body ctx.status = e.status except Exception as e: traceback.print_exc() ctx.status = 500 ctx.body = ctx.body or { 'lemon': 'INTERNAL ERROR', }
async def err_middleware(ctx: Context, nxt): ctx.body = {'msg': 'err_middleware'} try: await nxt() except Exception: ctx.body = {'msg': 'error handled'} ctx.status = 400