tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

http_handler.py (3915B)


      1 # mypy: allow-untyped-defs
      2 
      3 import http.client as httplib
      4 import sys
      5 import logging
      6 import traceback
      7 
      8 
      9 global logger
     10 logger = logging.getLogger("wave-api-handler")
     11 
     12 class HttpHandler:
     13    def __init__(
     14        self,
     15        static_handler,
     16        sessions_api_handler,
     17        tests_api_handler,
     18        results_api_handler,
     19        devices_api_handler,
     20        general_api_handler,
     21        http_port,
     22        web_root
     23    ):
     24        self.static_handler = static_handler
     25        self.sessions_api_handler = sessions_api_handler
     26        self.tests_api_handler = tests_api_handler
     27        self.results_api_handler = results_api_handler
     28        self.general_api_handler = general_api_handler
     29        self.devices_api_handler = devices_api_handler
     30        self._http_port = http_port
     31        self._web_root = web_root
     32 
     33    def handle_request(self, request, response):
     34        response.headers = [
     35            ("Access-Control-Allow-Origin", "*"),
     36            ("Access-Control-Allow-Headers", "*"),
     37            ("Access-Control-Allow-Methods", "*")
     38        ]
     39        if request.method == "OPTIONS":
     40            return
     41 
     42        path = self._remove_web_root(request.request_path)
     43 
     44        is_api_call = False
     45        for index, part in enumerate(path.split("/")):
     46            if index > 2:
     47                break
     48            if part != "api":
     49                continue
     50 
     51            is_api_call = True
     52 
     53        if (is_api_call):
     54            if request.url_parts.scheme == "https":
     55                self._proxy(request, response)
     56                return
     57            self.handle_api(request, response)
     58        else:
     59            self.handle_static_file(request, response)
     60 
     61    def handle_api(self, request, response):
     62        path = self._remove_web_root(request.request_path)
     63        path = path.split("?")[0]
     64        api_name = path.split("/")[1]
     65 
     66        if api_name is None:
     67            return
     68 
     69        if api_name == "sessions":
     70            self.sessions_api_handler.handle_request(request, response)
     71            return
     72        if api_name == "tests":
     73            self.tests_api_handler.handle_request(request, response)
     74            return
     75        if api_name == "results":
     76            self.results_api_handler.handle_request(request, response)
     77            return
     78        if api_name == "devices":
     79            self.devices_api_handler.handle_request(request, response)
     80            return
     81 
     82        self.general_api_handler.handle_request(request, response)
     83 
     84    def handle_static_file(self, request, response):
     85        self.static_handler.handle_request(request, response)
     86 
     87    def _remove_web_root(self, path):
     88        if self._web_root is not None:
     89            path = path[len(self._web_root):]
     90        return path
     91 
     92 
     93    def _proxy(self, request, response):
     94        host = 'localhost'
     95        port = int(self._http_port)
     96        uri = request.url_parts.path
     97        uri = uri + "?" + request.url_parts.query
     98        content_length = request.headers.get('Content-Length')
     99        data = ""
    100        if content_length is not None:
    101            data = request.raw_input.read(int(content_length))
    102        method = request.method
    103 
    104        headers = {}
    105        for key in request.headers:
    106            value = request.headers[key]
    107            headers[key.decode("utf-8")] = value.decode("utf-8")
    108 
    109        try:
    110            proxy_connection = httplib.HTTPConnection(host, port)
    111            proxy_connection.request(method, uri, data, headers)
    112            proxy_response = proxy_connection.getresponse()
    113            response.content = proxy_response.read()
    114            response.headers = proxy_response.getheaders()
    115            response.status = proxy_response.status
    116 
    117        except OSError:
    118            message = "Failed to perform proxy request"
    119            info = sys.exc_info()
    120            traceback.print_tb(info[2])
    121            logger.error(f"{message}: {info[0].__name__}: {info[1].args[0]}")
    122            response.status = 500