Skip to content

Commit

Permalink
Add shared config file
Browse files Browse the repository at this point in the history
  • Loading branch information
sansmoraxz committed Jun 12, 2024
1 parent a426b32 commit d38df27
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 31 deletions.
5 changes: 4 additions & 1 deletion cmd/godm/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ func downloadCmd() *cobra.Command {
os.Exit(1)
}

if err := godm.DownloadFile(fileName, largeFileUrl, true, compress); err != nil {
if err := godm.DownloadFile(fileName, largeFileUrl, &godm.DownloadConfig{
Compress: compress,
DisplayDownloadBar: true,
}); err != nil {
fmt.Printf("\n\nError downloading file: %v\n", err)
os.Exit(1)
}
Expand Down
62 changes: 35 additions & 27 deletions download.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ const (
chunkSize = 512 * 1024 // 1MB
)

func DownloadFile(filePath string, url string, displayDownloadBar bool, compress bool) error {
type DownloadConfig struct {
DisplayDownloadBar bool
Compress bool
}

type HeaderInfo struct {
IsAcceptRanges bool
Length int
ETag string
Encoding string
}

func DownloadFile(filePath string, url string, config *DownloadConfig) error {

// shared client
client := &http.Client{
// Timeout: time.Second * 10,
Expand All @@ -28,39 +41,34 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress
}
defer client.CloseIdleConnections()

headers, err := getHeaders(client, url, compress)
headerInfo, err := getHeaders(client, url, config)
if err != nil {
return err
}

isAcceptRanges := headers.Get("Accept-Ranges") == "bytes"
length, _ := strconv.Atoi(headers.Get("Content-Length")) // it will be 0 if not present
etag := headers.Get("ETag")
encoding := headers.Get("Content-Encoding")

if encoding == "" {
compress = false
} else if slices.Contains(supportedEncodings, encoding) {
compress = true
if headerInfo.Encoding == "" {
config.Compress = false
} else if slices.Contains(supportedEncodings, headerInfo.Encoding) {
config.Compress = true
} else {
return errors.New("Unknown encoding: " + encoding)
return errors.New("Unknown encoding: " + headerInfo.Encoding)
}

log.Info("Downloading: ", url)
log.Info("Content-Length: ", length)
log.Info("Content-Encoding: ", encoding)
log.Info("Accept-Ranges: ", isAcceptRanges)
log.Info("ETag: ", etag)
log.Info("Content-Length: ", headerInfo.Length)
log.Info("Content-Encoding: ", headerInfo.Encoding)
log.Info("Accept-Ranges: ", headerInfo.IsAcceptRanges)
log.Info("ETag: ", headerInfo.ETag)

toDownloadTracker := make(map[Chunk]bool)
downBar := make([]bool, length/chunkSize+1)
downBar := make([]bool, headerInfo.Length/chunkSize+1)

if displayDownloadBar {
if config.DisplayDownloadBar {
go func() {
for {
// print download bar
fmt.Printf("\r[")
for i := 0; i < length/chunkSize+1; i++ {
for i := 0; i < headerInfo.Length/chunkSize+1; i++ {
if downBar[i] {
fmt.Printf("#")
} else {
Expand All @@ -74,11 +82,11 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress
}

// download in parallel
for i := 0; i < length/chunkSize+1; i++ {
for i := 0; i < headerInfo.Length/chunkSize+1; i++ {
c := Chunk{
start: i * chunkSize,
end: min((i+1)*chunkSize-1, length-1),
etag: etag,
end: min((i+1)*chunkSize-1, headerInfo.Length-1),
etag: headerInfo.ETag,
url: url,
}
toDownloadTracker[c] = false
Expand All @@ -87,7 +95,7 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress

sem := make(chan bool, maxP)
defer close(sem)
wg.Add(length/chunkSize + 1)
wg.Add(headerInfo.Length/chunkSize + 1)

partFileNameFn := func(c Chunk) string {
return filePath + "." + strconv.Itoa(c.start) + "-" + strconv.Itoa(c.end) + ".part"
Expand All @@ -110,7 +118,7 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress
defer file.Close()
log.Info("Downloading: ", c.start, c.end)
for !downBar[c.start/chunkSize] {
err = c.doPartialDownload(client, file, compress)
err = c.doPartialDownload(client, file, config.Compress)
if err != nil {
log.Error("Error for chunk: ", c.start, c.end, err)
} else {
Expand All @@ -127,7 +135,7 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress

var reassembledFile *os.File

if compress {
if config.Compress {
// intermediate archive file if compress is true
archivePath := filePath + ".archive"
if reassembledFile, err = os.Create(archivePath); err != nil {
Expand Down Expand Up @@ -155,8 +163,8 @@ func DownloadFile(filePath string, url string, displayDownloadBar bool, compress

log.Info("Reassembled file")

if compress {
if err = decompressFile(reassembledFile, filePath, encoding); err != nil {
if config.Compress {
if err = decompressFile(reassembledFile, filePath, headerInfo.Encoding); err != nil {
return err
}
}
Expand Down
17 changes: 14 additions & 3 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package godm

import (
"net/http"
"strconv"
"strings"
)

func getHeaders(client *http.Client, url string, compress bool) (http.Header, error) {
func getHeaders(client *http.Client, url string, config *DownloadConfig) (*HeaderInfo, error) {
// head request to get metadata
// Note: the uncompressed payload is considered for Content-Length

Expand All @@ -14,7 +15,7 @@ func getHeaders(client *http.Client, url string, compress bool) (http.Header, er
return nil, err
}

if compress {
if config.Compress {
req.Header.Set("Accept-Encoding", strings.Join(supportedEncodings, ", "))
}
resp, err := client.Do(req)
Expand All @@ -23,5 +24,15 @@ func getHeaders(client *http.Client, url string, compress bool) (http.Header, er
}
defer resp.Body.Close()

return resp.Header, nil
l, err := strconv.Atoi(resp.Header.Get("Content-Length"))
if err != nil {
return nil, err
}

return &HeaderInfo{
IsAcceptRanges: resp.Header.Get("Accept-Ranges") == "bytes",
Length: l,
ETag: resp.Header.Get("ETag"),
Encoding: resp.Header.Get("Content-Encoding"),
}, nil
}

0 comments on commit d38df27

Please sign in to comment.