Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/offline_download/http/client.go
1562 views
1
package http
2
3
import (
4
"fmt"
5
"net/http"
6
"net/url"
7
"os"
8
"path"
9
"path/filepath"
10
"strings"
11
12
"github.com/alist-org/alist/v3/internal/model"
13
"github.com/alist-org/alist/v3/internal/offline_download/tool"
14
"github.com/alist-org/alist/v3/pkg/utils"
15
)
16
17
type SimpleHttp struct {
18
client http.Client
19
}
20
21
func (s SimpleHttp) Name() string {
22
return "SimpleHttp"
23
}
24
25
func (s SimpleHttp) Items() []model.SettingItem {
26
return nil
27
}
28
29
func (s SimpleHttp) Init() (string, error) {
30
return "ok", nil
31
}
32
33
func (s SimpleHttp) IsReady() bool {
34
return true
35
}
36
37
func (s SimpleHttp) AddURL(args *tool.AddUrlArgs) (string, error) {
38
panic("should not be called")
39
}
40
41
func (s SimpleHttp) Remove(task *tool.DownloadTask) error {
42
panic("should not be called")
43
}
44
45
func (s SimpleHttp) Status(task *tool.DownloadTask) (*tool.Status, error) {
46
panic("should not be called")
47
}
48
49
func (s SimpleHttp) Run(task *tool.DownloadTask) error {
50
u := task.Url
51
// parse url
52
_u, err := url.Parse(u)
53
if err != nil {
54
return err
55
}
56
req, err := http.NewRequestWithContext(task.Ctx(), http.MethodGet, u, nil)
57
if err != nil {
58
return err
59
}
60
resp, err := s.client.Do(req)
61
if err != nil {
62
return err
63
}
64
defer resp.Body.Close()
65
if resp.StatusCode >= 400 {
66
return fmt.Errorf("http status code %d", resp.StatusCode)
67
}
68
// If Path is empty, use Hostname; otherwise, filePath euqals TempDir which causes os.Create to fail
69
urlPath := _u.Path
70
if urlPath == "" {
71
urlPath = strings.ReplaceAll(_u.Host, ".", "_")
72
}
73
filename := path.Base(urlPath)
74
if n, err := parseFilenameFromContentDisposition(resp.Header.Get("Content-Disposition")); err == nil {
75
filename = n
76
}
77
// save to temp dir
78
_ = os.MkdirAll(task.TempDir, os.ModePerm)
79
filePath := filepath.Join(task.TempDir, filename)
80
file, err := os.Create(filePath)
81
if err != nil {
82
return err
83
}
84
defer file.Close()
85
fileSize := resp.ContentLength
86
task.SetTotalBytes(fileSize)
87
err = utils.CopyWithCtx(task.Ctx(), file, resp.Body, fileSize, task.SetProgress)
88
return err
89
}
90
91
func init() {
92
tool.Tools.Add(&SimpleHttp{})
93
}
94
95