summaryrefslogtreecommitdiffstats
path: root/proxy/endpoints.py
diff options
context:
space:
mode:
Diffstat (limited to 'proxy/endpoints.py')
-rw-r--r--proxy/endpoints.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/proxy/endpoints.py b/proxy/endpoints.py
new file mode 100644
index 0000000..c287a88
--- /dev/null
+++ b/proxy/endpoints.py
@@ -0,0 +1,63 @@
1import logging
2from base64 import b64encode, b64decode
3from uuid import uuid4
4
5from starlette.endpoints import HTTPEndpoint
6from starlette.requests import Request
7from starlette.responses import Response
8
9from proxy.utils import get_path_with_query_string
10from ttun_server.proxy_queue import ProxyQueue
11from ttun_server.types import HttpMessage, HttpMessageType, HttpRequestData
12
13logger = logging.getLogger(__name__)
14
15
16class HeaderMapping:
17 def __init__(self, headers: list[tuple[str, str]]):
18 self._headers = headers
19
20 def items(self):
21 for header in self._headers:
22 yield header
23
24
25class Proxy(HTTPEndpoint):
26 async def dispatch(self) -> None:
27 request = Request(self.scope, self.receive)
28
29 subdomain = request.path_params['subdomain']
30 response = Response(content='Not Found', status_code=404)
31
32 identifier = str(uuid4())
33 response_queue = await ProxyQueue.create_for_identifier(identifier)
34
35 try:
36 request_queue = await ProxyQueue.get_for_identifier(subdomain)
37
38 logger.debug('PROXY %s%s ', subdomain, request.url)
39 await request_queue.enqueue(
40 HttpMessage(
41 type=HttpMessageType.request.value,
42 identifier=identifier,
43 payload=HttpRequestData(
44 method=request.method,
45 path=get_path_with_query_string(request),
46 headers=list(request.headers.items()),
47 body=b64encode(await request.body()).decode()
48 )
49 )
50 )
51
52 _response = await response_queue.dequeue()
53 payload = _response['payload']
54 response = Response(
55 status_code=payload['status'],
56 headers=HeaderMapping(payload['headers']),
57 content=b64decode(payload['body'].encode())
58 )
59 except AssertionError:
60 pass
61 finally:
62 await response(self.scope, self.receive, self.send)
63 await response_queue.delete()