diff options
Diffstat (limited to 'proxy/endpoints.py')
| -rw-r--r-- | proxy/endpoints.py | 63 |
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 @@ | |||
| 1 | import logging | ||
| 2 | from base64 import b64encode, b64decode | ||
| 3 | from uuid import uuid4 | ||
| 4 | |||
| 5 | from starlette.endpoints import HTTPEndpoint | ||
| 6 | from starlette.requests import Request | ||
| 7 | from starlette.responses import Response | ||
| 8 | |||
| 9 | from proxy.utils import get_path_with_query_string | ||
| 10 | from ttun_server.proxy_queue import ProxyQueue | ||
| 11 | from ttun_server.types import HttpMessage, HttpMessageType, HttpRequestData | ||
| 12 | |||
| 13 | logger = logging.getLogger(__name__) | ||
| 14 | |||
| 15 | |||
| 16 | class 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 | |||
| 25 | class 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() | ||
