예제 #1
0
 async def test_nested_timeouts_concurrent(self):
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.002):
             with self.assertRaises(TimeoutError):
                 async with asyncio.timeout(0.1):
                     # Pretend we crunch some numbers.
                     time.sleep(0.01)
                     await asyncio.sleep(1)
예제 #2
0
 async def test_nested_timeout_in_finally(self):
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.01):
             try:
                 await asyncio.sleep(1)
             finally:
                 with self.assertRaises(TimeoutError):
                     async with asyncio.timeout(0.01):
                         await asyncio.sleep(10)
예제 #3
0
async def stream_torrent(loop, torrent, stream_func, filter_func):
    """
        Stream torrent.
        This will launch:
            - A logger to log torrent alerts (while torrent is downloading)
            - Torrent download
            - Once torrent.started, will try to find a playable file, and
              fill a ``PERCENT_CACHE`` cache to start playing

    """
    async def alert_watcher(torrent):
        """ Watch and log torrent alerts from LT """
        while not torrent.finished:
            alert = torrent.session.pop_alert()
            if alert:
                LOG.info(alert)
            await asyncio.sleep(1)

    # Force sequential mode
    torrent.sequential(True)

    # Start alert watcher task
    loop.create_task(alert_watcher(torrent))

    # If we're actually re-asking for a torrent, just relaunch streaming
    if torrent.finished:
        return [
            wait_for_completion(torrent),
            stream_func(loop, filter_func(torrent.files))
        ]

    # Otherwise, wait for torrent to start or finish in TIMEOUT_START+
    # seconds
    with asyncio.timeout(TIMEOUT_START):
        while not torrent.started and not torrent.finished:
            await asyncio.sleep(5)

    # Only download filtered file
    playable_tfile = torrent.download_only(await filter_func(torrent.files))

    # If filter matches nothing, stop
    if not playable_tfile:
        raise Exception("Could not find a playable source that matches"
                        " filter function")

    # Try to fill the cache, if it's not filled within the first
    # ``TIMEOUT_CACHE_FILL`` seconds, exit
    with asyncio.timeout(TIMEOUT_CACHE_FILL):
        while playable_tfile.completed_percent < PERCENT_CACHE:
            await asyncio.sleep(5)

    return await asyncio.gather(
        [wait_for_completion(torrent),
         stream_func(loop, playable_tfile)])
예제 #4
0
async def stream_torrent(loop, torrent, stream_func, filter_func):
    """
        Stream torrent.
        This will launch:
            - A logger to log torrent alerts (while torrent is downloading)
            - Torrent download
            - Once torrent.started, will try to find a playable file, and
              fill a ``PERCENT_CACHE`` cache to start playing

    """

    async def alert_watcher(torrent):
        """ Watch and log torrent alerts from LT """
        while not torrent.finished:
            alert = torrent.session.pop_alert()
            if alert:
                LOG.info(alert)
            await asyncio.sleep(1)

    # Force sequential mode
    torrent.sequential(True)

    # Start alert watcher task
    loop.create_task(alert_watcher(torrent))

    # If we're actually re-asking for a torrent, just relaunch streaming
    if torrent.finished:
        return [wait_for_completion(torrent),
                stream_func(loop, filter_func(torrent.files))]

    # Otherwise, wait for torrent to start or finish in TIMEOUT_START+
    # seconds
    with asyncio.timeout(TIMEOUT_START):
        while not torrent.started and not torrent.finished:
            await asyncio.sleep(5)

    # Only download filtered file
    playable_tfile = torrent.download_only(await filter_func(torrent.files))

    # If filter matches nothing, stop
    if not playable_tfile:
        raise Exception("Could not find a playable source that matches"
                        " filter function")

    # Try to fill the cache, if it's not filled within the first
    # ``TIMEOUT_CACHE_FILL`` seconds, exit
    with asyncio.timeout(TIMEOUT_CACHE_FILL):
        while playable_tfile.completed_percent < PERCENT_CACHE:
            await asyncio.sleep(5)

    return await asyncio.gather([wait_for_completion(torrent),
                                 stream_func(loop, playable_tfile)])
예제 #5
0
    async def trakt_auth_device(self, advise_callback):
        """
            returns the full authorization data,
            as a dict, from wich we'll get "access_token"
        """
        with aiohttp.ClientSession() as session:
            async with session.post(
                self.code_url, data={"client_id": self.cid}
            ) as resp:
                assert resp.status == 200
                auth_data = await resp.json()

        await advise_callback(auth_data)

        with suppress(TimeoutError):
            data = {"client_id": self.cid, "client_secret": self.csecret,
                    "code": auth_data['device_code']}
            with asyncio.timeout(auth_data['expires_in']):
                with aiohttp.ClientSession() as session:
                    while True:
                        async with session.post(self.token_url, data=data) as resp:
                            if resp.status == 200:
                                return await resp.json()
                            else:
                                await asyncio.sleep(auth_data["interval"])
        return False
예제 #6
0
    async def trakt_auth_device(self, advise_callback):
        """
            returns the full authorization data,
            as a dict, from wich we'll get "access_token"
        """
        with aiohttp.ClientSession() as session:
            async with session.post(self.code_url,
                                    data={"client_id": self.cid}) as resp:
                assert resp.status == 200
                auth_data = await resp.json()

        await advise_callback(auth_data)

        with suppress(TimeoutError):
            data = {
                "client_id": self.cid,
                "client_secret": self.csecret,
                "code": auth_data['device_code']
            }
            with asyncio.timeout(auth_data['expires_in']):
                with aiohttp.ClientSession() as session:
                    while True:
                        async with session.post(self.token_url,
                                                data=data) as resp:
                            if resp.status == 200:
                                return await resp.json()
                            else:
                                await asyncio.sleep(auth_data["interval"])
        return False
예제 #7
0
 def dispatch(self, event, time=10):
     for action in (a for a, f in self.bindings if f.check(event)):
         LOG.debug("Dispatching {}".format(str(action)))
         try:
             self.queue.put_nowait(
                 (functools.partial(action, event), timeout(time)))
         except QueueFull:
             LOG.error("The unbounded queue is full! Pretty weird, eh?")
예제 #8
0
 async def test_nested_timeouts_loop_busy(self):
     # After the inner timeout is an expensive operation which should
     # be stopped by the outer timeout.
     loop = asyncio.get_running_loop()
     # Disable a message about long running task
     loop.slow_callback_duration = 10
     t0 = loop.time()
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.1):  # (1)
             with self.assertRaises(TimeoutError):
                 async with asyncio.timeout(0.01):  # (2)
                     # Pretend the loop is busy for a while.
                     time.sleep(0.1)
                     await asyncio.sleep(1)
             # TimeoutError was cought by (2)
             await asyncio.sleep(
                 10)  # This sleep should be interrupted by (1)
     t1 = loop.time()
     self.assertTrue(t0 <= t1 <= t0 + 1)
예제 #9
0
    async def test_foreign_exception_on_timeout(self):
        async def crash():
            try:
                await asyncio.sleep(1)
            finally:
                1 / 0

        with self.assertRaises(ZeroDivisionError):
            async with asyncio.timeout(0.01):
                await crash()
예제 #10
0
 async def test_timeout_zero(self):
     loop = asyncio.get_running_loop()
     t0 = loop.time()
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0) as cm:
             await asyncio.sleep(10)
     t1 = loop.time()
     self.assertTrue(cm.expired())
     # 2 sec for slow CI boxes
     self.assertLess(t1 - t0, 2)
     self.assertTrue(t0 <= cm.when() <= t1)
예제 #11
0
    async def test_timeout_disabled(self):
        loop = asyncio.get_running_loop()
        t0 = loop.time()
        async with asyncio.timeout(None) as cm:
            await asyncio.sleep(0.01)
        t1 = loop.time()

        self.assertFalse(cm.expired())
        self.assertIsNone(cm.when())
        # 2 sec for slow CI boxes
        self.assertLess(t1 - t0, 2)
예제 #12
0
    async def test_timeout_not_called(self):
        loop = asyncio.get_running_loop()
        t0 = loop.time()
        async with asyncio.timeout(10) as cm:
            await asyncio.sleep(0.01)
        t1 = loop.time()

        self.assertFalse(cm.expired())
        # 2 sec for slow CI boxes
        self.assertLess(t1 - t0, 2)
        self.assertGreater(cm.when(), t1)
예제 #13
0
 async def test_waiter_cancelled(self):
     loop = asyncio.get_running_loop()
     cancelled = False
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.01):
             try:
                 await asyncio.sleep(10)
             except asyncio.CancelledError:
                 cancelled = True
                 raise
     self.assertTrue(cancelled)
예제 #14
0
async def _stream_torrent(loop, torrent, stream_func, filter_func):
    loop.create_task(alert_watcher(torrent))

    if torrent.finished:
        #: Parallel launch stream function and wait for completion from now on
        #: We'll forget the torrent itself and relie
        #: In case we already got it
        return [
            wait_for_completion(torrent),
            stream_func(loop, filter_func(torrent.files))
        ]

    with asyncio.timeout(10 * 60):  #: TODO Make this timeout configurable
        while not torrent.started and not torrent.finished:
            await asyncio.sleep(5)

    #: Secuential download.
    torrent.handle.set_sequential_download(True)

    #: Filter function must make sure to be precise...
    #: It gets a list of torrent.file
    playable_tfile = torrent.download_only(await filter_func(torrent.files))
    LOG.info("Found playable file: %s", playable_tfile)

    if not playable_tfile:
        raise Exception("Could not find a playable source that matches"
                        " filter function")

    try:
        with asyncio.timeout(5 * 60):
            while True:
                if playable_tfile.completed_percent >= 5:
                    break
                await asyncio.sleep(5)
    except asyncio.TimeoutError:
        raise Exception('Could not get playable source in time')

    #: Parallel launch stream function and wait for completion from now on
    #: We'll forget the torrent itself and relie
    return [wait_for_completion(torrent), stream_func(loop, playable_tfile)]
예제 #15
0
async def _stream_torrent(loop, torrent, stream_func, filter_func):
    loop.create_task(alert_watcher(torrent))

    if torrent.finished:
        #: Parallel launch stream function and wait for completion from now on
        #: We'll forget the torrent itself and relie
        #: In case we already got it
        return [wait_for_completion(torrent),
                stream_func(loop, filter_func(torrent.files))]

    with asyncio.timeout(10 * 60):  #: TODO Make this timeout configurable
        while not torrent.started and not torrent.finished:
            await asyncio.sleep(5)

    #: Secuential download.
    torrent.handle.set_sequential_download(True)

    #: Filter function must make sure to be precise...
    #: It gets a list of torrent.file
    playable_tfile = torrent.download_only(await filter_func(torrent.files))
    LOG.info("Found playable file: %s", playable_tfile)

    if not playable_tfile:
        raise Exception("Could not find a playable source that matches"
                        " filter function")

    try:
        with asyncio.timeout(5 * 60):
            while True:
                if playable_tfile.completed_percent >= 5:
                    break
                await asyncio.sleep(5)
    except asyncio.TimeoutError:
        raise Exception('Could not get playable source in time')

    #: Parallel launch stream function and wait for completion from now on
    #: We'll forget the torrent itself and relie
    return [wait_for_completion(torrent),
            stream_func(loop, playable_tfile)]
예제 #16
0
async def client_handler(websocket, path):
    # print(websocket)

    async def send_string(msg):
        try:
            await websocket.send(msg)
        except Exception as e:
            print(e)
            return False
        return True

    # Client should provide a proof of work
    answ = random.randint(0, 2**ANSWER_SIZE - 1)
    answ = hex(answ)[2:]
    answ = answ.zfill(ANSWER_SIZE // 4)

    chal = hashlib.md5(answ.encode("utf8")).hexdigest()
    chal = bin(int(chal, 16))[2:]
    chal = chal[:CHALLENGE_SIZE].zfill(CHALLENGE_SIZE)

    if not await send_string(CHALLENGE + chal): return

    try:
        with asyncio.timeout(TIMEOUT):
            answer = await websocket.recv()
        if len(answer) != ANSWER_SIZE // 4:
            print("Invalid response length.")
            # await send_string(UNACCEPTABLE)
            return

        _chal = hashlib.md5(answer.encode("utf8")).hexdigest()
        _chal = bin(int(_chal, 16))[2:]
        _chal = _chal[:CHALLENGE_SIZE].zfill(CHALLENGE_SIZE)
        if _chal != chal:
            print("Invalid response to challenge.")
            # await send_string(UNACCEPTABLE)
            return
    except Exception as e:
        print(e)
        return

    # Initial permutation, persists during a session
    phi = np.random.permutation(N)

    i = 0
    while i < N:
        found = False

        # Current permutation and its inverse
        # Persists until a right guess, or until N/2 wrong guesses
        rho = np.random.permutation(N)
        rho_inv = np.argsort(rho)

        result = rho[phi[rho_inv]]

        if not await send_string(RE_ARRANGED + str(i).zfill(ALIGN)): return

        for j in range(0, MAX_GUESSES):
            try:
                if not await send_string(GIVE_GUESS + str(j).zfill(ALIGN)):
                    return
                with asyncio.timeout(TIMEOUT):
                    answer = await websocket.recv()
                if len(answer) > 3:
                    raise Exception("Input too long")
                guess = int(answer)
                actual = result[guess]
            except Exception as e:
                print(e)
                return
            if actual == i:
                if not await send_string(GREATE_GUESS + PAD): return
                found = True
                # print('---> GREAT!')
                break
            # print('--->' + str(actual))
            if not await send_string(WRONG_GUESS + str(actual).zfill(ALIGN)):
                return

        if found:
            i += 1
        else:
            await send_string(BYE + PAD)
            return

    await send_string(FLAG_IS + 'SharifCTF{flagfalgflag}')
예제 #17
0
 async def test_foreign_cancel_doesnt_timeout_if_not_expired(self):
     with self.assertRaises(asyncio.CancelledError):
         async with asyncio.timeout(10) as cm:
             asyncio.current_task().cancel()
             await asyncio.sleep(10)
     self.assertFalse(cm.expired())
예제 #18
0
    async def test_repr_finished(self):
        async with asyncio.timeout(10) as cm:
            await asyncio.sleep(0)

        self.assertEqual(repr(cm), "<Timeout [finished]>")
예제 #19
0
 async def test_foreign_exception_passed(self):
     with self.assertRaises(KeyError):
         async with asyncio.timeout(0.01) as cm:
             raise KeyError
     self.assertFalse(cm.expired())
예제 #20
0
 async def outer() -> None:
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.001):
             await asyncio.sleep(10)
예제 #21
0
 async def test_timeout_basic(self):
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.01) as cm:
             await asyncio.sleep(10)
     self.assertTrue(cm.expired())
예제 #22
0
 async def test_repr_active(self):
     async with asyncio.timeout(10) as cm:
         self.assertRegex(repr(cm), r"<Timeout \[active\] when=\d+\.\d*>")
예제 #23
0
 async def test_repr_disabled(self):
     async with asyncio.timeout(None) as cm:
         self.assertEqual(repr(cm), r"<Timeout [active] when=None>")
예제 #24
0
async def client_handler(websocket, path):
	# print(websocket)

	async def send_string(msg):
		try:
			await websocket.send(msg)
		except Exception as e:
			print(e)
			return False
		return True
	
	# Client should provide a proof of work
	answ = random.randint(0, 2**ANSWER_SIZE - 1)
	answ = hex(answ)[2:]
	answ = answ.zfill(ANSWER_SIZE//4)

	chal = hashlib.md5(answ.encode("utf8")).hexdigest()
	chal = bin(int(chal, 16))[2:]
	chal = chal[:CHALLENGE_SIZE].zfill(CHALLENGE_SIZE)

	if not await send_string(CHALLENGE + chal): return

	try:
		with asyncio.timeout(TIMEOUT):
			answer = await websocket.recv()
		if len(answer) != ANSWER_SIZE//4:
			print("Invalid response length.")
			# await send_string(UNACCEPTABLE)
			return

		_chal = hashlib.md5(answer.encode("utf8")).hexdigest()
		_chal = bin(int(_chal, 16))[2:]
		_chal = _chal[:CHALLENGE_SIZE].zfill(CHALLENGE_SIZE)
		if _chal != chal:
			print("Invalid response to challenge.")
			# await send_string(UNACCEPTABLE)
			return
	except Exception as e:
		print(e)
		return

	# Initial permutation, persists during a session
	phi = np.random.permutation(N)

	i = 0
	while i < N:
		found = False

		# Current permutation and its inverse
		# Persists until a right guess, or until N/2 wrong guesses
		rho = np.random.permutation(N)
		rho_inv = np.argsort(rho)

		result = rho[phi[rho_inv]]

		if not await send_string(RE_ARRANGED + str(i).zfill(ALIGN)): return

		for j in range(0, MAX_GUESSES):
			try:
				if not await send_string(GIVE_GUESS + str(j).zfill(ALIGN)): return
				with asyncio.timeout(TIMEOUT):
					answer = await websocket.recv()
				if len(answer) > 3:
					raise Exception("Input too long")
				guess = int(answer)
				actual = result[guess]			
			except Exception as e:
				print(e)
				return
			if actual == i:
				if not await send_string(GREATE_GUESS + PAD): return
				found = True
				# print('---> GREAT!')
				break
			# print('--->' + str(actual))
			if not await send_string(WRONG_GUESS + str(actual).zfill(ALIGN)): return

		if found:
			i += 1
		else:
			await send_string(BYE + PAD)
			return

	await send_string(FLAG_IS + 'SharifCTF{flagfalgflag}')
예제 #25
0
 async def test_repr_expired(self):
     with self.assertRaises(TimeoutError):
         async with asyncio.timeout(0.01) as cm:
             await asyncio.sleep(10)
     self.assertEqual(repr(cm), "<Timeout [expired]>")