MCPcopy Create free account
hub / github.com/pallets/quart / ASGIHTTPConnection

Class ASGIHTTPConnection

src/quart/asgi.py:45–176  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

43
44
45class ASGIHTTPConnection:
46 def __init__(self, app: Quart, scope: HTTPScope) -> None:
47 self.app = app
48 self.scope = scope
49
50 async def __call__(
51 self, receive: ASGIReceiveCallable, send: ASGISendCallable
52 ) -> None:
53 request = self._create_request_from_scope(send)
54 receiver_task = asyncio.ensure_future(self.handle_messages(request, receive))
55 handler_task = asyncio.ensure_future(self.handle_request(request, send))
56 done, pending = await asyncio.wait(
57 [handler_task, receiver_task], return_when=asyncio.FIRST_COMPLETED
58 )
59 await cancel_tasks(pending)
60 raise_task_exceptions(done)
61
62 async def handle_messages(
63 self, request: Request, receive: ASGIReceiveCallable
64 ) -> None:
65 while True:
66 message = await receive()
67 if message["type"] == "http.request":
68 request.body.append(message.get("body", b""))
69 if not message.get("more_body", False):
70 request.body.set_complete()
71 elif message["type"] == "http.disconnect":
72 return
73
74 def _create_request_from_scope(self, send: ASGISendCallable) -> Request:
75 headers = Headers()
76 headers["Remote-Addr"] = (self.scope.get("client") or ["<local>"])[0]
77 for name, value in self.scope["headers"]:
78 headers.add(name.decode("latin1").title(), value.decode("latin1"))
79 if self.scope["http_version"] < "1.1":
80 headers.setdefault("Host", self.app.config["SERVER_NAME"] or "")
81
82 path = self.scope["path"]
83 path = path if path[0] == "/" else urlparse(path).path
84 root_path = self.scope.get("root_path", "")
85 if root_path != "":
86 try:
87 path = path.split(root_path, 1)[1]
88 path = " " if path == "" else path
89 except IndexError:
90 path = " " # Invalid in paths, hence will result in 404
91
92 return self.app.request_class(
93 self.scope["method"],
94 self.scope["scheme"],
95 path,
96 self.scope["query_string"],
97 headers,
98 self.scope.get("root_path", ""),
99 self.scope["http_version"],
100 max_content_length=self.app.config["MAX_CONTENT_LENGTH"],
101 body_timeout=self.app.config["BODY_TIMEOUT"],
102 send_push_promise=partial(self._send_push_promise, send),

Calls

no outgoing calls

Used in the wild real call sites across dependent graphs

searching dependent graphs…