From a1abb7c8fbafa7f8b537dd37f7b47e528d525923 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Mon, 15 Apr 2019 18:17:43 -0400 Subject: [PATCH] test range requests --- lbrynet/extras/daemon/Daemon.py | 3 +- lbrynet/stream/managed_stream.py | 1 - tests/integration/test_range_requests.py | 68 ++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/integration/test_range_requests.py diff --git a/lbrynet/extras/daemon/Daemon.py b/lbrynet/extras/daemon/Daemon.py index 1cb00cf09..68b37faad 100644 --- a/lbrynet/extras/daemon/Daemon.py +++ b/lbrynet/extras/daemon/Daemon.py @@ -473,7 +473,7 @@ class Daemon(metaclass=JSONRPCServerType): name, claim_id = name_and_claim_id.split("/") uri = f"lbry://{name}#{claim_id}" stream = await self.jsonrpc_get(uri) - return web.HTTPFound(f"/stream/{stream.sd_hash}") + raise web.HTTPFound(f"/stream/{stream.sd_hash}") async def handle_stream_range_request(self, request: web.Request): sd_hash = request.path.split("/stream/")[1] @@ -515,6 +515,7 @@ class Daemon(metaclass=JSONRPCServerType): async for blob_info, decrypted in stream.aiter_read_stream(skip_blobs): await response.write(decrypted) log.info("sent browser blob %i/%i", blob_info.blob_num + 1, len(stream.descriptor.blobs) - 1) + await response.write_eof() return response async def _process_rpc_call(self, data): diff --git a/lbrynet/stream/managed_stream.py b/lbrynet/stream/managed_stream.py index e70052b3b..19f4f1857 100644 --- a/lbrynet/stream/managed_stream.py +++ b/lbrynet/stream/managed_stream.py @@ -9,7 +9,6 @@ from lbrynet.stream.downloader import StreamDownloader from lbrynet.stream.descriptor import StreamDescriptor from lbrynet.stream.reflector.client import StreamReflectorClient from lbrynet.extras.daemon.storage import StoredStreamClaim -from lbrynet.blob.blob_file import BlobFile if typing.TYPE_CHECKING: from lbrynet.conf import Config from lbrynet.schema.claim import Claim diff --git a/tests/integration/test_range_requests.py b/tests/integration/test_range_requests.py new file mode 100644 index 000000000..9e0b7ecc1 --- /dev/null +++ b/tests/integration/test_range_requests.py @@ -0,0 +1,68 @@ +import asyncio +import aiohttp +import aiohttp.web +import os +import hashlib +import logging +from lbrynet.utils import aiohttp_request +from lbrynet.testcase import CommandTestCase + +log = logging.getLogger(__name__) + + +class RangeRequests(CommandTestCase): + + VERBOSITY = logging.WARN + + async def _test_range_requests(self, data: bytes, save_blobs: bool = True, streaming_only: bool = True): + self.daemon.conf.save_blobs = save_blobs + self.daemon.conf.streaming_only = streaming_only + self.data = data + await self.stream_create('foo', '0.01', data=self.data) + await self.daemon.jsonrpc_file_delete(delete_from_download_dir=True, claim_name='foo') + + self.daemon.stream_manager.stop() + await self.daemon.stream_manager.start() + + await self.daemon.runner.setup() + site = aiohttp.web.TCPSite(self.daemon.runner, self.daemon.conf.api_host, self.daemon.conf.api_port) + await site.start() + self.assertListEqual(self.daemon.jsonrpc_file_list(), []) + name = 'foo' + url = f'http://{self.daemon.conf.api_host}:{self.daemon.conf.api_port}/get/{name}' + + streamed_bytes = b'' + async with aiohttp_request('get', url) as req: + self.assertEqual(req.headers.get('Content-Type'), 'application/octet-stream') + content_range = req.headers.get('Content-Range') + while True: + try: + data, eof = await asyncio.wait_for(req.content.readchunk(), 3, loop=self.loop) + except asyncio.TimeoutError: + data = b'' + eof = True + if data: + streamed_bytes += data + if not data or eof: + break + self.assertTrue((len(streamed_bytes) + 16 >= len(self.data)) + and (len(streamed_bytes) <= len(self.data))) + return streamed_bytes, content_range + + async def test_range_requests_0_padded_bytes(self): + self.data = b''.join(hashlib.sha256(os.urandom(16)).digest() for _ in range(250000)) + b'0000000000000' + streamed, content_range = await self._test_range_requests(self.data) + self.assertEqual(streamed, self.data) + self.assertEqual(content_range, 'bytes 0-8000013/8000014') + + async def test_range_requests_1_padded_bytes(self): + self.data = b''.join(hashlib.sha256(os.urandom(16)).digest() for _ in range(250000)) + b'00000000000001x' + streamed, content_range = await self._test_range_requests(self.data) + self.assertEqual(streamed, self.data[:-1]) + self.assertEqual(content_range, 'bytes 0-8000013/8000014') + + async def test_range_requests_2_padded_bytes(self): + self.data = b''.join(hashlib.sha256(os.urandom(16)).digest() for _ in range(250000)) + streamed, content_range = await self._test_range_requests(self.data) + self.assertEqual(streamed, self.data[:-2]) + self.assertEqual(content_range, 'bytes 0-7999997/7999998')