github.com/vektra/tachyon@v0.0.0-20150921164542-0da4f3861aef/download.go (about) 1 package tachyon 2 3 import ( 4 "crypto/sha256" 5 "encoding/hex" 6 "fmt" 7 "io" 8 "net/http" 9 "os" 10 ) 11 12 type DownloadCmd struct { 13 Url string `tachyon:"url,required"` 14 Dest string `tachyon:"dest"` 15 Sha256sum string `tachyon:"sha256sum"` 16 Once bool `tachyon:"once"` 17 } 18 19 func (d *DownloadCmd) Run(env *CommandEnv) (*Result, error) { 20 destPath := d.Dest 21 22 var out *os.File 23 var err error 24 25 if destPath == "" { 26 out, err = env.Env.TempFile("download") 27 destPath = out.Name() 28 29 if err != nil { 30 return nil, err 31 } 32 } else { 33 if d.Once { 34 fi, err := os.Stat(destPath) 35 if err == nil { 36 r := NewResult(false) 37 r.Data.Set("size", fi.Size()) 38 r.Data.Set("path", destPath) 39 40 return r, nil 41 } 42 } 43 44 out, err = os.OpenFile(destPath, os.O_CREATE|os.O_WRONLY, 0644) 45 if err != nil { 46 return nil, err 47 } 48 } 49 50 defer out.Close() 51 52 resp, err := http.Get(d.Url) 53 if err != nil { 54 return nil, err 55 } 56 57 if resp.StatusCode/100 != 2 { 58 return nil, fmt.Errorf("Unable to download '%s', code: %d", d.Url, resp.StatusCode) 59 } 60 61 s := sha256.New() 62 63 tee := io.MultiWriter(out, s) 64 65 n, err := io.Copy(tee, resp.Body) 66 if err != nil { 67 return nil, err 68 } 69 70 r := NewResult(true) 71 r.Data.Set("size", n) 72 r.Data.Set("path", destPath) 73 r.Data.Set("sha256sum", hex.EncodeToString(s.Sum(nil))) 74 75 return r, nil 76 } 77 78 func init() { 79 RegisterCommand("download", &DownloadCmd{}) 80 }