mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-09-19 20:26:26 +08:00
106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
package http
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand/v2"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/offline_download/tool"
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
|
)
|
|
|
|
type SimpleHttp struct {
|
|
client http.Client
|
|
}
|
|
|
|
func (s SimpleHttp) Name() string {
|
|
return "SimpleHttp"
|
|
}
|
|
|
|
func (s SimpleHttp) Items() []model.SettingItem {
|
|
return nil
|
|
}
|
|
|
|
func (s SimpleHttp) Init() (string, error) {
|
|
return "ok", nil
|
|
}
|
|
|
|
func (s SimpleHttp) IsReady() bool {
|
|
return true
|
|
}
|
|
|
|
func (s SimpleHttp) AddURL(args *tool.AddUrlArgs) (string, error) {
|
|
panic("should not be called")
|
|
}
|
|
|
|
func (s SimpleHttp) Remove(task *tool.DownloadTask) error {
|
|
panic("should not be called")
|
|
}
|
|
|
|
func (s SimpleHttp) Status(task *tool.DownloadTask) (*tool.Status, error) {
|
|
panic("should not be called")
|
|
}
|
|
|
|
func (s SimpleHttp) Run(task *tool.DownloadTask) error {
|
|
streamPut := task.DeletePolicy == tool.UploadDownloadStream
|
|
method := http.MethodGet
|
|
if streamPut {
|
|
method = http.MethodHead
|
|
}
|
|
req, err := http.NewRequestWithContext(task.Ctx(), method, task.Url, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if streamPut {
|
|
req.Header.Set("Range", "bytes=0-")
|
|
}
|
|
resp, err := s.client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode >= 400 {
|
|
return fmt.Errorf("http status code %d", resp.StatusCode)
|
|
}
|
|
filename, err := parseFilenameFromContentDisposition(resp.Header.Get("Content-Disposition"))
|
|
if err != nil {
|
|
filename = path.Base(resp.Request.URL.Path)
|
|
}
|
|
filename = strings.Trim(filename, "/")
|
|
if len(filename) == 0 {
|
|
filename = fmt.Sprintf("%s-%d-%x", strings.ReplaceAll(req.URL.Host, ".", "_"), time.Now().UnixMilli(), rand.Uint32())
|
|
}
|
|
fileSize := resp.ContentLength
|
|
if streamPut {
|
|
if fileSize == 0 {
|
|
start, end, _ := http_range.ParseContentRange(resp.Header.Get("Content-Range"))
|
|
fileSize = start + end
|
|
}
|
|
task.SetTotalBytes(fileSize)
|
|
task.TempDir = filename
|
|
return nil
|
|
}
|
|
task.SetTotalBytes(fileSize)
|
|
// save to temp dir
|
|
_ = os.MkdirAll(task.TempDir, os.ModePerm)
|
|
filePath := filepath.Join(task.TempDir, filename)
|
|
file, err := os.Create(filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
err = utils.CopyWithCtx(task.Ctx(), file, resp.Body, fileSize, task.SetProgress)
|
|
return err
|
|
}
|
|
|
|
func init() {
|
|
tool.Tools.Add(&SimpleHttp{})
|
|
}
|