@@ -2,97 +2,66 @@ package download
2
2
3
3
import (
4
4
"context"
5
- "crypto/sha256"
6
5
"encoding/hex"
7
6
"fmt"
8
7
"io"
8
+ "mime"
9
9
"net/http"
10
10
"net/url"
11
11
"os"
12
12
"path/filepath"
13
- "time"
14
13
14
+ "github.com/cavaliergopher/grab/v3"
15
15
"github.com/crc-org/crc/v2/pkg/crc/logging"
16
16
"github.com/crc-org/crc/v2/pkg/crc/network/httpproxy"
17
17
"github.com/crc-org/crc/v2/pkg/crc/version"
18
- "github.com/crc-org/crc/v2/pkg/os/terminal"
19
-
20
- "github.com/cavaliergopher/grab/v3"
21
- "github.com/cheggaaa/pb/v3"
22
18
"github.com/pkg/errors"
23
19
)
24
20
25
- func doRequest (client * grab.Client , req * grab.Request ) (string , error ) {
26
- const minSizeForProgressBar = 100_000_000
27
-
28
- resp := client .Do (req )
29
- if resp .Size () < minSizeForProgressBar {
30
- <- resp .Done
31
- return resp .Filename , resp .Err ()
32
- }
33
-
34
- t := time .NewTicker (500 * time .Millisecond )
35
- defer t .Stop ()
36
- var bar * pb.ProgressBar
37
- if terminal .IsShowTerminalOutput () {
38
- bar = pb .Start64 (resp .Size ())
39
- bar .Set (pb .Bytes , true )
40
- // This is the same as the 'Default' template https://github.com/cheggaaa/pb/blob/224e0746e1e7b9c5309d6e2637264bfeb746d043/v3/preset.go#L8-L10
41
- // except that the 'per second' suffix is changed to '/s' (by default it is ' p/s' which is unexpected)
42
- progressBarTemplate := `{{with string . "prefix"}}{{.}} {{end}}{{counters . }} {{bar . }} {{percent . }} {{speed . "%s/s" "??/s"}}{{with string . "suffix"}} {{.}}{{end}}`
43
- bar .SetTemplateString (progressBarTemplate )
44
- defer bar .Finish ()
45
- }
46
-
47
- loop:
48
- for {
49
- select {
50
- case <- t .C :
51
- if terminal .IsShowTerminalOutput () {
52
- bar .SetCurrent (resp .BytesComplete ())
53
- }
54
- case <- resp .Done :
55
- break loop
56
- }
57
- }
58
-
59
- return resp .Filename , resp .Err ()
60
- }
61
-
62
21
// Download function takes sha256sum as hex decoded byte
63
22
// something like hex.DecodeString("33daf4c03f86120fdfdc66bddf6bfff4661c7ca11c5d")
64
- func Download (ctx context.Context , uri , destination string , mode os.FileMode , sha256sum []byte ) (string , error ) {
23
+ func Download (ctx context.Context , uri , destination string , mode os.FileMode , _ []byte ) (io. Reader , string , error ) {
65
24
logging .Debugf ("Downloading %s to %s" , uri , destination )
66
25
67
- client := grab .NewClient ()
68
- client .UserAgent = version .UserAgent ()
69
- client .HTTPClient = & http.Client {Transport : httpproxy .HTTPTransport ()}
70
- req , err := grab .NewRequest (destination , uri )
26
+ req , err := http .NewRequestWithContext (ctx , "GET" , uri , nil )
27
+
71
28
if err != nil {
72
- return "" , errors .Wrapf (err , "unable to get request from %s" , uri )
29
+ return nil , "" , errors .Wrapf (err , "unable to get request from %s" , uri )
73
30
}
31
+ client := http.Client {Transport : & http.Transport {}}
74
32
75
33
if ctx == nil {
76
34
panic ("ctx is nil, this should not happen" )
77
35
}
78
36
req = req .WithContext (ctx )
79
37
80
- if sha256sum != nil {
81
- req .SetChecksum (sha256 .New (), sha256sum , true )
38
+ resp , err := client .Do (req )
39
+ if err != nil {
40
+ return nil , "" , err
82
41
}
83
42
84
- filename , err := doRequest (client , req )
43
+ var filename , dir string
44
+ if filepath .Ext (destination ) == "crcbundle" {
45
+ dir = filepath .Dir (destination )
46
+ } else {
47
+ dir = destination
48
+ }
49
+ if disposition , params , _ := mime .ParseMediaType (resp .Header .Get ("Content-Disposition" )); disposition == "attachment" {
50
+ filename = filepath .Join (dir , params ["filename" ])
51
+ } else {
52
+ filename = filepath .Join (dir , filepath .Base (resp .Request .URL .Path ))
53
+ }
54
+ file , err := os .OpenFile (filename , os .O_CREATE | os .O_WRONLY | os .O_TRUNC , mode )
85
55
if err != nil {
86
- return "" , err
56
+ return nil , "" , err
87
57
}
88
58
89
59
if err := os .Chmod (filename , mode ); err != nil {
90
60
_ = os .Remove (filename )
91
- return "" , err
61
+ return nil , "" , err
92
62
}
93
63
94
- logging .Debugf ("Download saved to %v" , filename )
95
- return filename , nil
64
+ return io .TeeReader (resp .Body , file ), filename , nil
96
65
}
97
66
98
67
// InMemory takes a URL and returns a ReadCloser object to the downloaded file
@@ -138,10 +107,10 @@ func NewRemoteFile(uri, sha256sum string) *RemoteFile {
138
107
139
108
}
140
109
141
- func (r * RemoteFile ) Download (ctx context.Context , bundlePath string , mode os.FileMode ) (string , error ) {
110
+ func (r * RemoteFile ) Download (ctx context.Context , bundlePath string , mode os.FileMode ) (io. Reader , string , error ) {
142
111
sha256bytes , err := hex .DecodeString (r .sha256sum )
143
112
if err != nil {
144
- return "" , err
113
+ return nil , "" , err
145
114
}
146
115
return Download (ctx , r .URI , bundlePath , mode , sha256bytes )
147
116
}
0 commit comments