@@ -609,9 +609,10 @@ class Updater(object):
609
609
targets that have changed are returns in a list. From this list, they
610
610
can request a download by calling 'download_target()'.
611
611
612
- download_target(target, destination_directory):
612
+ download_target(target, destination_directory, custom_download_handler ):
613
613
This method performs the actual download of the specified target. The
614
- file is saved to the 'destination_directory' argument.
614
+ file is saved to the 'destination_directory' argument. A custom
615
+ file download function can be used if provided by the user.
615
616
616
617
remove_obsolete_targets(destination_directory):
617
618
Any files located in 'destination_directory' that were previously
@@ -1313,7 +1314,7 @@ def _soft_check_file_length(self, file_object, trusted_file_length):
1313
1314
1314
1315
1315
1316
def _get_target_file (self , target_filepath , file_length , file_hashes ,
1316
- prefix_filename_with_hash ):
1317
+ prefix_filename_with_hash , custom_download_handler = None ):
1317
1318
"""
1318
1319
<Purpose>
1319
1320
Non-public method that safely (i.e., the file length and hash are
@@ -1339,6 +1340,10 @@ def _get_target_file(self, target_filepath, file_length, file_hashes,
1339
1340
prefixed with hashes (in this case the server uses other means
1340
1341
to ensure snapshot consistency).
1341
1342
1343
+ custom_download_handler:
1344
+ A user provided function performing the actual target file download.
1345
+ If None, tuf.download.safe_download is used.
1346
+
1342
1347
<Exceptions>
1343
1348
tuf.exceptions.NoWorkingMirrorError:
1344
1349
The target could not be fetched. This is raised only when all known
@@ -1370,7 +1375,7 @@ def verify_target_file(target_file_object):
1370
1375
target_filepath = os .path .join (dirname , target_digest + '.' + basename )
1371
1376
1372
1377
return self ._get_file (target_filepath , verify_target_file ,
1373
- 'target' , file_length )
1378
+ 'target' , file_length , custom_download_handler )
1374
1379
1375
1380
1376
1381
@@ -1654,7 +1659,8 @@ def _get_metadata_file(self, metadata_role, remote_filename,
1654
1659
1655
1660
1656
1661
1657
- def _get_file (self , filepath , verify_file_function , file_type , file_length ):
1662
+ def _get_file (self , filepath , verify_file_function , file_type , file_length ,
1663
+ custom_download_handler = None ):
1658
1664
"""
1659
1665
<Purpose>
1660
1666
Non-public method that tries downloading, up to a certain length, a
@@ -1681,6 +1687,10 @@ def _get_file(self, filepath, verify_file_function, file_type, file_length):
1681
1687
The expected length, or upper bound, of the target or metadata file to
1682
1688
be downloaded.
1683
1689
1690
+ custom_download_handler:
1691
+ A user provided function performing the actual target file download.
1692
+ If None, tuf.download.safe_download is used.
1693
+
1684
1694
<Exceptions>
1685
1695
tuf.exceptions.NoWorkingMirrorError:
1686
1696
The metadata could not be fetched. This is raised only when all known
@@ -1702,11 +1712,17 @@ def _get_file(self, filepath, verify_file_function, file_type, file_length):
1702
1712
file_mirror_errors = {}
1703
1713
file_object = None
1704
1714
1715
+ if custom_download_handler is not None :
1716
+ safe_download = custom_download_handler
1717
+
1718
+ else :
1719
+ safe_download = tuf .download .safe_download
1720
+
1705
1721
for file_mirror in file_mirrors :
1706
1722
try :
1707
1723
# Eensure the length of the downloaded file matches 'file_length'
1708
1724
# exactly.
1709
- file_object = tuf . download . safe_download (file_mirror , file_length )
1725
+ file_object = safe_download (file_mirror , file_length )
1710
1726
1711
1727
# Verify 'file_object' according to the callable function.
1712
1728
# 'file_object' is also verified if decompressed above (i.e., the
@@ -3212,7 +3228,7 @@ def updated_targets(self, targets, destination_directory):
3212
3228
3213
3229
3214
3230
def download_target (self , target , destination_directory ,
3215
- prefix_filename_with_hash = True ):
3231
+ prefix_filename_with_hash = True , custom_download_handler = None ):
3216
3232
"""
3217
3233
<Purpose>
3218
3234
Download 'target' and verify it is trusted.
@@ -3237,6 +3253,22 @@ def download_target(self, target, destination_directory,
3237
3253
to ensure snapshot consistency).
3238
3254
Default is True.
3239
3255
3256
+ custom_download_handler:
3257
+ A user provided function performing the actual target file download.
3258
+ In order to comply with the TUF specification, the function signature
3259
+ should have the form:
3260
+
3261
+ 'def download_handler_func(url, required_length)'
3262
+
3263
+ The function implementation should provide the following functionality:
3264
+
3265
+ 'Given the 'url' and 'required_length' of the desired file, open a
3266
+ connection to 'url', download it, and return the contents of the file.
3267
+ Also ensure the length of the downloaded file matches 'required_length'
3268
+ exactly'
3269
+
3270
+ If None, tuf.download.safe_download is used.
3271
+
3240
3272
<Exceptions>
3241
3273
securesystemslib.exceptions.FormatError:
3242
3274
If 'target' is not properly formatted.
@@ -3294,6 +3326,6 @@ def download_target(self, target, destination_directory,
3294
3326
# '_get_target_file()' checks every mirror and returns the first target
3295
3327
# that passes verification.
3296
3328
target_file_object = self ._get_target_file (target_filepath , trusted_length ,
3297
- trusted_hashes , prefix_filename_with_hash )
3329
+ trusted_hashes , prefix_filename_with_hash , custom_download_handler )
3298
3330
3299
3331
securesystemslib .util .persist_temp_file (target_file_object , destination )
0 commit comments