#!/usr/bin/env python3 import asyncio from functools import wraps import os from secrets import compare_digest import sys from urllib.parse import urlparse from quart import ( request, make_response, Quart, ) app = Quart(__name__) timer_handle = None loop = None def set_timeout(): global timer_handle # ASAN is very slow, just don't have a timer. if 'ASAN_OPTIONS' in os.environ: return if timer_handle: timer_handle.cancel() # This timeout just prevents a zombie process from # running even if a test crashes. timer_handle = loop.call_later(20, lambda: sys.exit(0)) @app.route('/') async def index(): set_timeout() return 'Hello world' @app.route('/slow') async def slow(): set_timeout() await asyncio.sleep(1) return 'Hello world' @app.route('/timeout') async def timeout(): set_timeout() await asyncio.sleep(4) return 'Hello world' @app.route('/no-content') async def no_content(): set_timeout() return await make_response('', 204) @app.route('/large') async def large(): set_timeout() async def generate_data(): # Send increasing letters just to aid debugging letter = ord('A') bytes_pending = 1024 * 24 while bytes_pending: await asyncio.sleep(0.1) bytes_pending -= 1024 string = chr(letter) * 1024 letter += 1 yield bytes(string, 'UTF-8') yield b'\0' return generate_data() @app.route('/echo_query') async def echo_query(): set_timeout() url = urlparse(request.url) return url.query @app.route('/echo_post', methods=['POST']) async def echo_post(): set_timeout() data = await request.get_data() return data @app.route('/auth') async def auth(): set_timeout() auth = request.authorization if ( auth is not None and auth.type == "basic" and auth.username == 'username' and compare_digest(auth.password, 'password') ): return 'Authenticated' response = await make_response('Authentication Required') response.status_code = 401 response.headers['WWW-Authenticate'] = 'Basic' return response has_been_misdirected = False @app.route('/misdirected_request') async def misdirected_request(): set_timeout() global has_been_misdirected if not has_been_misdirected: has_been_misdirected = True response = await make_response('', 421) return response return 'Success!' if __name__ == '__main__': loop = asyncio.get_event_loop() set_timeout() app.run(use_reloader=False, loop=loop, certfile='test-cert.pem', keyfile='test-key.pem')