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  }