Download to temporary filename, then move to final name.

This commit is contained in:
Andrey Smirnov
2013-12-17 20:30:48 +04:00
parent 20524a839d
commit 151a4acfa7
+33 -8
View File
@@ -9,6 +9,7 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"path/filepath"
) )
// Downloader is parallel HTTP fetcher // Downloader is parallel HTTP fetcher
@@ -91,14 +92,34 @@ func (downloader *downloaderImpl) handleTask(task *downloadTask) {
return return
} }
outfile, err := os.Create(task.destination) err = os.MkdirAll(filepath.Base(task.destination), 0755)
if err != nil {
task.result <- err
return
}
temppath := task.destination + ".down"
outfile, err := os.Create(temppath)
if err != nil { if err != nil {
task.result <- err task.result <- err
return return
} }
defer outfile.Close() defer outfile.Close()
io.Copy(outfile, resp.Body) _, err = io.Copy(outfile, resp.Body)
if err != nil {
os.Remove(temppath)
task.result <- err
return
}
err = os.Rename(temppath, task.destination)
if err != nil {
os.Remove(temppath)
task.result <- err
return
}
task.result <- nil task.result <- nil
} }
@@ -120,23 +141,27 @@ func (downloader *downloaderImpl) process() {
// //
// Temporary file would be already removed, so no need to cleanup // Temporary file would be already removed, so no need to cleanup
func DownloadTemp(downloader Downloader, url string) (*os.File, error) { func DownloadTemp(downloader Downloader, url string) (*os.File, error) {
tempdir, err := ioutil.TempDir(os.TempDir(), "aptly")
tempfile, err := ioutil.TempFile(os.TempDir(), "aptly")
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer os.RemoveAll(tempdir)
defer os.Remove(tempfile.Name()) tempfile := filepath.Join(tempdir, "buffer")
ch := downloader.Download(url, tempfile.Name()) ch := downloader.Download(url, tempfile)
err = <-ch err = <-ch
if err != nil { if err != nil {
tempfile.Close()
return nil, err return nil, err
} }
return tempfile, nil file, err := os.Open(tempfile)
if err != nil {
return nil, err
}
return file, nil
} }
// List of extensions + corresponding uncompression support // List of extensions + corresponding uncompression support