-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcore.py
More file actions
59 lines (44 loc) · 2.1 KB
/
core.py
File metadata and controls
59 lines (44 loc) · 2.1 KB
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
import asyncio
import collections
from typing import Sequence
import tornado.httputil
import tornado.routing
from abstractions import AppDelegate, Middleware
from middleware.exception import convert_exception_to_response
class PipelineRouter(tornado.routing.ReversibleRuleRouter):
def __init__(self, rules=None, middleware: Sequence[Middleware] = None):
super().__init__(rules)
self.middleware = middleware if isinstance(middleware, collections.Sequence) else []
def get_target_delegate(self, target, request, **target_params):
target_kwargs = target_params.get('target_kwargs')
return PipelineDelegate(request, middleware=self.middleware, **target_kwargs)
class PipelineDelegate(tornado.httputil.HTTPMessageDelegate):
request_handler: AppDelegate
def __init__(self, request: tornado.httputil.HTTPServerRequest, delegate: AppDelegate,
middleware: Sequence[Middleware], *args, **kwargs):
self.request = request
self.delegate = delegate
self.middleware = middleware
self._chunks = []
self.load_middleware()
def load_middleware(self):
self.request_handler = convert_exception_to_response(self.delegate)
for middleware in reversed(self.middleware):
handler = middleware(self.request_handler)
self.request_handler = convert_exception_to_response(handler)
def data_received(self, chunk):
self._chunks.append(chunk)
def finish(self):
self.request.body = b''.join(self._chunks)
self.request._parse_body()
asyncio.create_task(self.handle_request())
def on_connection_close(self):
self._chunks = None
async def handle_request(self):
response = await self.request_handler(self.request)
reason = tornado.httputil.responses.get(response.status_code, 'Unknown')
await self.request.connection.write_headers(
tornado.httputil.ResponseStartLine('', response.status_code, reason),
tornado.httputil.HTTPHeaders(response.headers),
response.body)
self.request.connection.finish()