diff --git a/doc/download.xml b/doc/download.xml index def4273..cf8548c 100644 --- a/doc/download.xml +++ b/doc/download.xml @@ -68,6 +68,8 @@ The following components are supported. that is a local filename, and the function writes the downloaded contents to this file; the returned record does not have a result component in this case. +

+ If the download fails then this file is not left behind. verifyCert diff --git a/lib/download.gi b/lib/download.gi index f3bf36c..4b9a6ce 100644 --- a/lib/download.gi +++ b/lib/download.gi @@ -273,6 +273,13 @@ InstallMethod( Download, if res.success = true then return res; fi; + # A failed method may have left a partial or bogus target file behind. + # Remove it here, so that the guarantee holds for every method, + # including ones added to 'Download_Methods' from outside. + if IsBound( opt.target ) and IsString( opt.target ) and + IsExistingFile( opt.target ) then + RemoveFile( opt.target ); + fi; Info( InfoUtils, 2, "Download method ", r.name, " failed with\n", "#I ", res.error ); Add( errors, Concatenation( r.name, ": ", res.error ) ); diff --git a/tst/download.tst b/tst/download.tst index 5f52849..02856d3 100644 --- a/tst/download.tst +++ b/tst/download.tst @@ -152,6 +152,18 @@ gap> RecNames( opt ); [ ] gap> SetUserPreference( "utils", "DownloadMaxTime", oldpref ); +## A failed download must not leave the target file behind, whichever +## method was tried. 'Download' is where that is guaranteed: an individual +## method may well leave a partial file, and one of them has to, since a +## resuming method needs what the previous attempt wrote. +gap> file:= Filename( DirectoryTemporary(), "target" );; +gap> res1:= Download( Concatenation( baseurl, "/missing" ), +> rec( target:= file ) );; +gap> res1.success = false; +true +gap> IsExistingFile( file ); +false + ## test errors and redirects gap> res1:= Download( Concatenation( baseurl, "/missing" ) );; gap> res1.success = false;