-
Notifications
You must be signed in to change notification settings - Fork 2
/
demo.py
127 lines (104 loc) · 3.42 KB
/
demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#
# demo application for http3_server.py
#
import datetime
import os
import json
from urllib.parse import urlencode
import httpbin
from asgiref.wsgi import WsgiToAsgi
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse, Response, JSONResponse
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from starlette.websockets import WebSocketDisconnect
import config
ROOT = os.path.dirname(__file__)
STATIC_ROOT = os.environ.get("STATIC_ROOT", os.path.join(ROOT, "htdocs"))
STATIC_URL = "/"
LOGS_PATH = os.path.join(STATIC_ROOT, "logs")
QVIS_URL = "https://qvis.edm.uhasselt.be/"
templates = Jinja2Templates(directory=os.path.join(STATIC_ROOT, "templates"))
app = Starlette(debug=True)
@app.route("/")
async def homepage(request):
"""
Simple homepage.
"""
await request.send_push_promise("/style.css")
return templates.TemplateResponse("index.html", {"request": request})
@app.route("/manifest/{filename:str}")
async def manifest(request):
server_pushed = 0
filename = request.path_params['filename']
manifest = json.load(open(STATIC_ROOT + "/" + filename))
segment = manifest['segment_size_bytes'][0][2]
if config.NUM_SERVER_PUSHED_FRAMES is not None:
while server_pushed < config.NUM_SERVER_PUSHED_FRAMES:
await request.send_push_promise(str(segment))
server_pushed += 1
return JSONResponse(manifest)
@app.route("/echo", methods=["POST"])
async def echo(request):
"""
HTTP echo endpoint.
"""
content = await request.body()
media_type = request.headers.get("content-type")
return Response(content, media_type=media_type)
@app.route("/logs/?")
async def logs(request):
"""
Browsable list of QLOG files.
"""
logs = []
for name in os.listdir(LOGS_PATH):
if name.endswith(".qlog"):
s = os.stat(os.path.join(LOGS_PATH, name))
file_url = "https://" + request.headers["host"] + "/logs/" + name
logs.append(
{
"date": datetime.datetime.utcfromtimestamp(s.st_mtime).strftime(
"%Y-%m-%d %H:%M:%S"
),
"file_url": file_url,
"name": name[:-5],
"qvis_url": QVIS_URL
+ "?"
+ urlencode({"file": file_url})
+ "#/sequence",
"size": s.st_size,
}
)
return templates.TemplateResponse(
"logs.html",
{
"logs": sorted(logs, key=lambda x: x["date"], reverse=True),
"request": request,
},
)
@app.route("/{size:int}")
def padding(request):
"""
Dynamically generated data, maximum 50MB.
"""
size = min(50000000, request.path_params["size"])
return PlainTextResponse("Z" * size)
@app.websocket_route("/ws")
async def ws(websocket):
"""
WebSocket echo endpoint.
"""
if "chat" in websocket.scope["subprotocols"]:
subprotocol = "chat"
else:
subprotocol = None
await websocket.accept(subprotocol=subprotocol)
try:
while True:
message = await websocket.receive_text()
await websocket.send_text(message)
except WebSocketDisconnect:
pass
app.mount("/httpbin", WsgiToAsgi(httpbin.app))
app.mount(STATIC_URL, StaticFiles(directory=STATIC_ROOT, html=True))