github.com/getgauge/gauge@v1.6.9/util/httpUtils.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package util 8 9 import ( 10 "fmt" 11 "io" 12 "net/http" 13 "os" 14 "path/filepath" 15 16 "github.com/getgauge/gauge/logger" 17 18 "github.com/getgauge/common" 19 ) 20 21 // progressReader is for indicating the download / upload progress on the console 22 type progressReader struct { 23 io.Reader 24 bytesTransfered int64 25 totalBytes int64 26 progress float64 27 progressDisplayed bool 28 } 29 30 // Read overrides the underlying io.Reader's Read method. 31 // io.Copy() will be calling this method. 32 func (w *progressReader) Read(p []byte) (int, error) { 33 n, err := w.Reader.Read(p) 34 if n > 0 { 35 w.bytesTransfered += int64(n) 36 percent := float64(w.bytesTransfered) * float64(100) / float64(w.totalBytes) 37 if percent-w.progress > 4 { 38 fmt.Print(".") 39 w.progress = percent 40 w.progressDisplayed = true 41 } 42 } 43 return n, err 44 } 45 46 // Download fires a HTTP GET request to download a resource to target directory 47 func Download(url, targetDir, fileName string, silent bool) (string, error) { 48 if !common.DirExists(targetDir) { 49 return "", fmt.Errorf("Error downloading file: %s\nTarget dir %s doesn't exists.", url, targetDir) 50 } 51 52 if fileName == "" { 53 fileName = filepath.Base(url) 54 } 55 targetFile := filepath.Join(targetDir, fileName) 56 57 logger.Debugf(true, "Downloading %s", url) 58 resp, err := http.Get(url) 59 if err != nil { 60 return "", err 61 } 62 if resp.StatusCode != 200 { 63 return "", fmt.Errorf("Error downloading file: %s.\n%s", url, resp.Status) 64 } 65 66 defer resp.Body.Close() 67 68 out, err := os.Create(targetFile) 69 if err != nil { 70 return "", err 71 } 72 defer out.Close() 73 if silent { 74 _, err = io.Copy(out, resp.Body) 75 } else { 76 progressReader := &progressReader{Reader: resp.Body, totalBytes: resp.ContentLength} 77 _, err = io.Copy(out, progressReader) 78 if progressReader.progressDisplayed { 79 fmt.Println() 80 } 81 } 82 return targetFile, err 83 }