tor-browser

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

helpers.py (3620B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 """ Helpers to build scenarii
      5 """
      6 from condprof.util import logger
      7 
      8 _SUPPORTED_MOBILE_BROWSERS = "fenix", "gecko", "firefox"
      9 
     10 
     11 def is_mobile(platform):
     12    return any(mobile in platform for mobile in _SUPPORTED_MOBILE_BROWSERS)
     13 
     14 
     15 class TabSwitcher:
     16    """Helper used to create tabs and circulate in them."""
     17 
     18    def __init__(self, session, options):
     19        self.handles = None
     20        self.current = 0
     21        self.session = session
     22        self._max = options.get("max_urls", 10)
     23        self.platform = options.get("platform", "")
     24        self.num_tabs = self._max >= 100 and 100 or self._max
     25        self._mobile = is_mobile(self.platform)
     26 
     27    async def create_windows(self):
     28        # on mobile we don't use tabs for now
     29        # see https://bugzil.la/1559120
     30        if self._mobile:
     31            return
     32        # creating tabs
     33        for i in range(self.num_tabs):
     34            # see https://github.com/HDE/arsenic/issues/71
     35            await self.session._request(
     36                url="/window/new", method="POST", data={"type": "tab"}
     37            )
     38 
     39    async def switch(self):
     40        if self._mobile:
     41            return
     42        try:
     43            if self.handles is None:
     44                self.handles = await self.session.get_window_handles()
     45                self.current = 0
     46        except Exception:
     47            logger.error("Could not get window handles")
     48            return
     49 
     50        handle = self.handles[self.current]
     51        if self.current == len(self.handles) - 1:
     52            self.current = 0
     53        else:
     54            self.current += 1
     55        try:
     56            await self.session.switch_to_window(handle)
     57        except Exception:
     58            logger.error("Could not switch to handle %s" % str(handle))
     59 
     60 
     61 # 10 minutes
     62 _SCRIPT_TIMEOUT = 10 * 60 * 1000
     63 
     64 
     65 async def execute_async_script(session, script, *args):
     66    # switch to the right context if needed
     67    current_context = await session._request(url="/moz/context", method="GET")
     68    if current_context != "chrome":
     69        await session._request(
     70            url="/moz/context", method="POST", data={"context": "chrome"}
     71        )
     72        switch_back = True
     73    else:
     74        switch_back = False
     75    await session._request(
     76        url="/timeouts", method="POST", data={"script": _SCRIPT_TIMEOUT}
     77    )
     78    try:
     79        attempts = 0
     80        while True:
     81            try:
     82                return await session._request(
     83                    url="/execute/async",
     84                    method="POST",
     85                    data={"script": script, "args": list(args)},
     86                )
     87            except Exception as e:
     88                attempts += 1
     89                logger.error("The script failed.", exc_info=True)
     90                if attempts > 2:
     91                    return {
     92                        "result": 1,
     93                        "result_message": str(e),
     94                        "result_exc": e,
     95                        "logs": {},
     96                    }
     97    finally:
     98        if switch_back:
     99            await session._request(
    100                url="/moz/context", method="POST", data={"context": current_context}
    101            )
    102 
    103 
    104 async def close_extra_windows(session):
    105    logger.info("Closing all tabs")
    106    handles = await session.get_window_handles()
    107    # we're closing all tabs except the last one
    108    for handle in handles[:-1]:
    109        await session.switch_to_window(handle)
    110        await session._request(url="/window", method="DELETE")