Skip to content

Commit

Permalink
Move download.py functions to FetcherInterface
Browse files Browse the repository at this point in the history
Make download_file and download_bytes functions part of
the FetcherInterface class. Remove download.py module.

Signed-off-by: Teodora Sechkova <[email protected]>
  • Loading branch information
sechkova committed Jul 5, 2021
1 parent 9fef7c9 commit 5b3a4de
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 79 deletions.
69 changes: 0 additions & 69 deletions tuf/ngclient/_internal/download.py

This file was deleted.

58 changes: 57 additions & 1 deletion tuf/ngclient/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

# Imports
import abc
from typing import Iterator
import logging
import tempfile
from contextlib import contextmanager
from typing import IO, Iterator
from urllib import parse

from tuf import exceptions

logger = logging.getLogger(__name__)


# Classes
Expand Down Expand Up @@ -40,3 +48,51 @@ def fetch(self, url: str, required_length: int) -> Iterator[bytes]:
A bytes iterator
"""
raise NotImplementedError # pragma: no cover

@contextmanager
def download_file(self, url: str, required_length: int) -> Iterator[IO]:
"""Opens a connection to 'url' and downloads the content
up to 'required_length'.
Args:
url: a URL string that represents the location of the file.
required_length: an integer value representing the length of
the file or an upper boundary.
Raises:
DownloadLengthMismatchError: a mismatch of observed vs expected
lengths while downloading the file.
Yields:
A file object that points to the contents of 'url'.
"""
# 'url.replace('\\', '/')' is needed for compatibility with
# Windows-based systems, because they might use back-slashes in place
# of forward-slashes. This converts it to the common format.
# unquote() replaces %xx escapes in a url with their single-character
# equivalent. A back-slash may beencoded as %5c in the url, which
# should also be replaced with a forward slash.
url = parse.unquote(url).replace("\\", "/")
logger.debug("Downloading: %s", url)

number_of_bytes_received = 0

with tempfile.TemporaryFile() as temp_file:
chunks = self.fetch(url, required_length)
for chunk in chunks:
temp_file.write(chunk)
number_of_bytes_received += len(chunk)
if number_of_bytes_received > required_length:
raise exceptions.DownloadLengthMismatchError(
required_length, number_of_bytes_received
)
temp_file.seek(0)
yield temp_file

def download_bytes(self, url: str, required_length: int) -> bytes:
"""Download bytes from given url
Returns the downloaded bytes, otherwise like download_file()
"""
with self.download_file(url, required_length) as dl_file:
return dl_file.read()
14 changes: 5 additions & 9 deletions tuf/ngclient/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@
from securesystemslib import util as sslib_util

from tuf import exceptions
from tuf.ngclient._internal import (
download,
requests_fetcher,
trusted_metadata_set,
)
from tuf.ngclient._internal import requests_fetcher, trusted_metadata_set
from tuf.ngclient.fetcher import FetcherInterface

# Globals
Expand All @@ -35,7 +31,7 @@

class Updater:
"""
An implemetation of the TUF client workflow.
An implementation of the TUF client workflow.
Provides a public API for integration in client applications.
"""

Expand Down Expand Up @@ -207,8 +203,8 @@ def download_target(

full_url = parse.urljoin(target_base_url, targetinfo["filepath"])

with download.download_file(
full_url, targetinfo["fileinfo"].length, self._fetcher
with self._fetcher.download_file(
full_url, targetinfo["fileinfo"].length
) as target_file:
_check_file_length(target_file, targetinfo["fileinfo"].length)
_check_hashes_obj(target_file, targetinfo["fileinfo"].hashes)
Expand All @@ -227,7 +223,7 @@ def _download_metadata(
else:
filename = f"{version}.{rolename}.json"
url = parse.urljoin(self._metadata_base_url, filename)
return download.download_bytes(url, length, self._fetcher)
return self._fetcher.download_bytes(url, length)

def _load_local_metadata(self, rolename: str) -> bytes:
with open(os.path.join(self._dir, f"{rolename}.json"), "rb") as f:
Expand Down

0 comments on commit 5b3a4de

Please sign in to comment.