@@ -1217,7 +1217,7 @@ def _check_hashes(self, file_object, trusted_hashes):
12171217
12181218
12191219
1220- def _hard_check_file_length (self , file_object , trusted_file_length ):
1220+ def _check_file_length (self , file_object , trusted_file_length ):
12211221 """
12221222 <Purpose>
12231223 Non-public method that ensures the length of 'file_object' is strictly
@@ -1304,24 +1304,44 @@ def _get_target_file(self, target_filepath, file_length, file_hashes,
13041304 A file object containing the target.
13051305 """
13061306
1307- # Define a callable function that is passed as an argument to _get_file()
1308- # and called. The 'verify_target_file' function ensures the file length
1309- # and hashes of 'target_filepath' are strictly equal to the trusted values.
1310- def verify_target_file (target_file_object ):
1311-
1312- # Every target file must have its length and hashes inspected.
1313- self ._hard_check_file_length (target_file_object , file_length )
1314- self ._check_hashes (target_file_object , file_hashes )
1315-
13161307 if self .consistent_snapshot and prefix_filename_with_hash :
13171308 # Note: values() does not return a list in Python 3. Use list()
13181309 # on values() for Python 2+3 compatibility.
13191310 target_digest = list (file_hashes .values ()).pop ()
13201311 dirname , basename = os .path .split (target_filepath )
13211312 target_filepath = os .path .join (dirname , target_digest + '.' + basename )
13221313
1323- return self ._get_file (target_filepath , verify_target_file ,
1324- 'target' , file_length , download_safely = True )
1314+ file_mirrors = tuf .mirrors .get_list_of_mirrors ('target' , target_filepath ,
1315+ self .mirrors )
1316+
1317+ # file_mirror (URL): error (Exception)
1318+ file_mirror_errors = {}
1319+ file_object = None
1320+
1321+ for file_mirror in file_mirrors :
1322+ try :
1323+ file_object = tuf .download .safe_download (file_mirror , file_length )
1324+
1325+ # Verify 'file_object' against the expected length and hashes.
1326+ self ._check_file_length (file_object , file_length )
1327+ self ._check_hashes (file_object , file_hashes )
1328+
1329+ except Exception as exception :
1330+ # Remember the error from this mirror, and "reset" the target file.
1331+ logger .debug ('Update failed from ' + file_mirror + '.' )
1332+ file_mirror_errors [file_mirror ] = exception
1333+ file_object = None
1334+
1335+ else :
1336+ break
1337+
1338+ if file_object :
1339+ return file_object
1340+
1341+ else :
1342+ logger .debug ('Failed to update ' + repr (target_filepath ) + ' from'
1343+ ' all mirrors: ' + repr (file_mirror_errors ))
1344+ raise tuf .exceptions .NoWorkingMirrorError (file_mirror_errors )
13251345
13261346
13271347
@@ -1605,96 +1625,6 @@ def _get_metadata_file(self, metadata_role, remote_filename,
16051625
16061626
16071627
1608- def _get_file (self , filepath , verify_file_function , file_type , file_length ,
1609- download_safely = True ):
1610- """
1611- <Purpose>
1612- Non-public method that tries downloading, up to a certain length, a
1613- metadata or target file from a list of known mirrors. As soon as the first
1614- valid copy of the file is found, the rest of the mirrors will be skipped.
1615-
1616- <Arguments>
1617- filepath:
1618- The relative metadata or target filepath.
1619-
1620- verify_file_function:
1621- A callable function that expects a file object and raises an exception
1622- if the file is invalid.
1623- Target files and uncompressed versions of metadata may be verified with
1624- 'verify_file_function'.
1625-
1626- file_type:
1627- Type of data needed for download, must correspond to one of the strings
1628- in the list ['meta', 'target']. 'meta' for metadata file type or
1629- 'target' for target file type. It should correspond to the
1630- 'securesystemslib.formats.NAME_SCHEMA' format.
1631-
1632- file_length:
1633- The expected length, or upper bound, of the target or metadata file to
1634- be downloaded.
1635-
1636- download_safely:
1637- A boolean switch to toggle safe or unsafe download of the file.
1638-
1639- <Exceptions>
1640- tuf.exceptions.NoWorkingMirrorError:
1641- The metadata could not be fetched. This is raised only when all known
1642- mirrors failed to provide a valid copy of the desired metadata file.
1643-
1644- <Side Effects>
1645- The file is downloaded from all known repository mirrors in the worst
1646- case. If a valid copy of the file is found, it is stored in a temporary
1647- file and returned.
1648-
1649- <Returns>
1650- A file object containing the metadata or target.
1651- """
1652-
1653- file_mirrors = tuf .mirrors .get_list_of_mirrors (file_type , filepath ,
1654- self .mirrors )
1655-
1656- # file_mirror (URL): error (Exception)
1657- file_mirror_errors = {}
1658- file_object = None
1659-
1660- for file_mirror in file_mirrors :
1661- try :
1662- # TODO: Instead of the more fragile 'download_safely' switch, unroll
1663- # the function into two separate ones: one for "safe" download, and the
1664- # other one for "unsafe" download? This should induce safer and more
1665- # readable code.
1666- if download_safely :
1667- file_object = tuf .download .safe_download (file_mirror , file_length )
1668-
1669- else :
1670- file_object = tuf .download .unsafe_download (file_mirror , file_length )
1671-
1672- # Verify 'file_object' according to the callable function.
1673- # 'file_object' is also verified if decompressed above (i.e., the
1674- # uncompressed version).
1675- verify_file_function (file_object )
1676-
1677- except Exception as exception :
1678- # Remember the error from this mirror, and "reset" the target file.
1679- logger .debug ('Update failed from ' + file_mirror + '.' )
1680- file_mirror_errors [file_mirror ] = exception
1681- file_object = None
1682-
1683- else :
1684- break
1685-
1686- if file_object :
1687- return file_object
1688-
1689- else :
1690- logger .debug ('Failed to update ' + repr (filepath ) + ' from'
1691- ' all mirrors: ' + repr (file_mirror_errors ))
1692- raise tuf .exceptions .NoWorkingMirrorError (file_mirror_errors )
1693-
1694-
1695-
1696-
1697-
16981628 def _update_metadata (self , metadata_role , upperbound_filelength , version = None ):
16991629 """
17001630 <Purpose>
0 commit comments