anderfv21.dev/ason@v0.0.3/dl/downloader.go (about)

     1  package dl
     2  
     3  import (
     4  	"io"
     5  	"net/http"
     6  	"net/url"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  )
    11  
    12  // Info contains information about download.
    13  type Info struct {
    14  	URL        string
    15  	Outputfile string
    16  }
    17  
    18  // Download download file given neede info to download.
    19  func Download(info Info) error {
    20  	res, err := http.Get(info.URL)
    21  	if err != nil {
    22  		return err
    23  	}
    24  	defer res.Body.Close()
    25  
    26  	// guess the outputfile from http header
    27  	if info.Outputfile == "" {
    28  		ss := res.Header["Content-Disposition"]
    29  		if len(ss) == 1 {
    30  			sss := strings.Split(ss[0], ";")
    31  			for _, s := range sss {
    32  				s = strings.Trim(s, " ")
    33  				if strings.HasPrefix(s, "filename=") {
    34  					s = strings.TrimPrefix(s, "filename=")
    35  					s = strings.Trim(s, `"`)
    36  					if s != " " {
    37  						info.Outputfile = s
    38  						break
    39  					}
    40  				}
    41  			}
    42  		}
    43  	}
    44  
    45  	if info.Outputfile == "" {
    46  		u, err := url.Parse(info.URL)
    47  		if err == nil {
    48  			s := filepath.Base(u.Path)
    49  			if s != "" {
    50  				info.Outputfile = s
    51  			}
    52  		}
    53  	}
    54  
    55  	f, err := os.OpenFile(info.Outputfile, os.O_CREATE|os.O_WRONLY, 0666)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	defer f.Close()
    60  
    61  	_, err = io.Copy(f, res.Body)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	return nil
    67  }