Compare commits

...

13 Commits

21 changed files with 184 additions and 120 deletions

View File

@ -13,4 +13,5 @@ jobs:
with:
actions: 'check-inactive'
token: ${{ secrets.GITHUB_TOKEN }}
inactive-day: 30
inactive-day: 30
body: Hello, this issue has been inactive for more than 30 days and will be closed if inactive for another 30 days.

View File

@ -0,0 +1,20 @@
name: Close inactive
on:
schedule:
- cron: "0 0 */7 * *"
jobs:
close-inactive:
runs-on: ubuntu-latest
steps:
- name: close-issues
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issues'
token: ${{ secrets.GITHUB_TOKEN }}
labels: 'inactive'
inactive-day: 30
close-reason: 'not_planned'
body: |
Hello @${{ github.event.issue.user.login }}, this issue was closed due to inactive more than 60 days. You can reopen or recreate it if you think it should continue.

View File

@ -1,11 +1,11 @@
name: Check need info
name: Close need info
on:
schedule:
- cron: "0 0 */7 * *"
jobs:
check-need-info:
close-need-info:
runs-on: ubuntu-latest
steps:
- name: close-issues

View File

@ -15,4 +15,5 @@ jobs:
comment-title: '### See'
comment-body: '${index}. ${similarity} #${number}'
show-footer: false
show-mentioned: true
show-mentioned: true
since-days: 730

View File

@ -11,15 +11,16 @@ import (
// passwordCmd represents the password command
var passwordCmd = &cobra.Command{
Use: "password",
Short: "Show admin user's password",
Use: "admin",
Aliases: []string{"password"},
Short: "Show admin user's info",
Run: func(cmd *cobra.Command, args []string) {
Init()
admin, err := db.GetAdmin()
if err != nil {
utils.Log.Errorf("failed get admin user: %+v", err)
} else {
utils.Log.Infof("admin user's password is: %s", admin.Password)
utils.Log.Infof("admin user's info: \nusername: %s\npassword: %s", admin.Username, admin.Password)
}
},
}

View File

@ -9,10 +9,10 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
@ -22,6 +22,7 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
)
type Pan123 struct {
@ -68,9 +69,47 @@ func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) (
func (d *Pan123) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if f, ok := file.(File); ok {
return &model.Link{
URL: f.DownloadUrl,
}, nil
var resp DownResp
var headers map[string]string
if !utils.IsLocalIPAddr(args.IP) {
headers = map[string]string{
//"X-Real-IP": "1.1.1.1",
"X-Forwarded-For": args.IP,
}
}
data := base.Json{
"driveId": 0,
"etag": f.Etag,
"fileId": f.FileId,
"fileName": f.FileName,
"s3keyFlag": f.S3KeyFlag,
"size": f.Size,
"type": f.Type,
}
_, err := d.request("https://www.123pan.com/api/file/download_info", http.MethodPost, func(req *resty.Request) {
req.SetBody(data).SetHeaders(headers)
}, &resp)
if err != nil {
return nil, err
}
u, err := url.Parse(resp.Data.DownloadUrl)
if err != nil {
return nil, err
}
u_ := fmt.Sprintf("https://%s%s", u.Host, u.Path)
res, err := base.NoRedirectClient.R().SetQueryParamsFromValues(u.Query()).Head(u_)
if err != nil {
return nil, err
}
log.Debug(res.String())
link := model.Link{
URL: resp.Data.DownloadUrl,
}
log.Debugln("res code: ", res.StatusCode())
if res.StatusCode() == 302 {
link.URL = res.Header().Get("location")
}
return &link, nil
} else {
return nil, fmt.Errorf("can't convert obj")
}
@ -153,7 +192,7 @@ func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
uploadFile = io.MultiReader(buf, stream)
} else {
// 计算完整文件MD5
tempFile, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
@ -161,11 +200,9 @@ func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
if _, err = io.Copy(io.MultiWriter(tempFile, h), stream); err != nil {
if _, err = io.Copy(h, tempFile); err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err

View File

@ -506,14 +506,15 @@ func (y *Yun189PC) CommonUpload(ctx context.Context, dstDir model.Obj, file mode
// 快传
func (y *Yun189PC) FastUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (err error) {
// 需要获取完整文件md5,必须支持 io.Seek
if _, ok := file.GetReadCloser().(*os.File); !ok {
r, err := utils.CreateTempFile(file)
if err != nil {
return err
}
file.Close()
file.SetReadCloser(r)
tempFile, err := utils.CreateTempFile(file.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
file.SetReadCloser(tempFile)
const DEFAULT int64 = 10485760
count := int(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))

View File

@ -14,7 +14,6 @@ import (
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
@ -119,28 +118,14 @@ func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
}
func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
var tempFile *os.File
var err error
if f, ok := stream.GetReadCloser().(*os.File); ok {
tempFile = f
} else {
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
_, err = io.Copy(tempFile, stream)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
var Default int64 = 4 * 1024 * 1024
defaultByteData := make([]byte, Default)
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))

View File

@ -34,7 +34,7 @@ func fileToObj(f File) *model.ObjThumb {
Name: f.Name,
Size: size,
Modified: time.Time{},
IsFolder: false,
IsFolder: f.MimeType == "application/vnd.google-apps.folder",
},
Thumbnail: model.Thumbnail{},
}

View File

@ -12,7 +12,6 @@ import (
"strconv"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
@ -177,7 +176,7 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, stream model.Fil
if err != nil {
return err
}
tempFile, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
@ -185,14 +184,6 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, stream model.Fil
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
_, err = io.Copy(tempFile, stream)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
uploader := s3manager.NewUploader(s)
input := &s3manager.UploadInput{
Bucket: &resp.Data.Bucket,

View File

@ -11,7 +11,6 @@ import (
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
@ -134,28 +133,14 @@ func (d *PikPak) Remove(ctx context.Context, obj model.Obj) error {
}
func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
var tempFile *os.File
var err error
if f, ok := stream.GetReadCloser().(*os.File); ok {
tempFile = f
} else {
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
_, err = io.Copy(tempFile, stream)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
// cal sha1
s := sha1.New()
_, err = io.Copy(s, tempFile)
@ -182,6 +167,10 @@ func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
if err != nil {
return err
}
if stream.GetSize() == 0 {
log.Debugln(string(res))
return nil
}
params := jsoniter.Get(res, "resumable").Get("params")
endpoint := params.Get("endpoint").ToString()
endpointS := strings.Split(endpoint, ".")

View File

@ -10,7 +10,6 @@ import (
"os"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
@ -135,28 +134,14 @@ func (d *Quark) Remove(ctx context.Context, obj model.Obj) error {
}
func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
var tempFile *os.File
var err error
if f, ok := stream.GetReadCloser().(*os.File); ok {
tempFile = f
} else {
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
_, err = io.Copy(tempFile, stream)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
m := md5.New()
_, err = io.Copy(m, tempFile)
if err != nil {

View File

@ -13,8 +13,9 @@ type Addition struct {
}
var config = driver.Config{
Name: "Quark",
OnlyProxy: true,
Name: "Quark",
OnlyProxy: true,
DefaultRoot: "0",
}
func New() driver.Driver {

View File

@ -119,7 +119,7 @@ func (d *S3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
}
func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
err := d.copy(srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), srcObj.IsDir())
err := d.copy(ctx, srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), srcObj.IsDir())
if err != nil {
return err
}
@ -127,7 +127,7 @@ func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error
}
func (d *S3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return d.copy(srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir())
return d.copy(ctx, srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir())
}
func (d *S3) Remove(ctx context.Context, obj model.Obj) error {

View File

@ -1,12 +1,14 @@
package s3
import (
"context"
"errors"
"net/http"
"path"
"strings"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
@ -165,14 +167,41 @@ func (d *S3) listV2(prefix string) ([]model.Obj, error) {
return files, nil
}
func (d *S3) copy(src string, dst string, isDir bool) error {
srcKey := getKey(src, isDir)
dstKey := getKey(dst, isDir)
func (d *S3) copy(ctx context.Context, src string, dst string, isDir bool) error {
if isDir {
return d.copyDir(ctx, src, dst)
}
return d.copyFile(ctx, src, dst)
}
func (d *S3) copyFile(ctx context.Context, src string, dst string) error {
srcKey := getKey(src, false)
dstKey := getKey(dst, false)
input := &s3.CopyObjectInput{
Bucket: &d.Bucket,
CopySource: &srcKey,
CopySource: aws.String("/" + d.Bucket + "/" + srcKey),
Key: &dstKey,
}
_, err := d.client.CopyObject(input)
return err
}
func (d *S3) copyDir(ctx context.Context, src string, dst string) error {
objs, err := op.List(ctx, d, src, model.ListArgs{})
if err != nil {
return err
}
for _, obj := range objs {
cSrc := path.Join(src, obj.GetName())
cDst := path.Join(dst, obj.GetName())
if obj.IsDir() {
err = d.copyDir(ctx, cSrc, cDst)
} else {
err = d.copyFile(ctx, cSrc, cDst)
}
if err != nil {
return err
}
}
return nil
}

View File

@ -48,16 +48,14 @@ func InitConfig() {
confFromEnv()
}
// convert abs path
var absPath string
var err error
if !filepath.IsAbs(conf.Conf.TempDir) {
absPath, err = filepath.Abs(conf.Conf.TempDir)
absPath, err := filepath.Abs(conf.Conf.TempDir)
if err != nil {
log.Fatalf("get abs path error: %+v", err)
}
conf.Conf.TempDir = absPath
}
conf.Conf.TempDir = absPath
err = os.RemoveAll(filepath.Join(conf.Conf.TempDir))
err := os.RemoveAll(filepath.Join(conf.Conf.TempDir))
if err != nil {
log.Errorln("failed delete temp file:", err)
}

View File

@ -35,15 +35,12 @@ func initSettings() {
for i := range initialSettingItems {
v := initialSettingItems[i]
_, err := db.GetSettingItemByKey(v.Key)
if err == nil {
continue
}
if errors.Is(err, gorm.ErrRecordNotFound) {
if errors.Is(err, gorm.ErrRecordNotFound) || v.Key == conf.VERSION {
err = db.SaveSettingItem(v)
if err != nil {
log.Fatalf("failed create setting: %+v", err)
}
} else {
} else if err != nil {
log.Fatalf("failed get setting: %+v", err)
}
}

View File

@ -142,7 +142,7 @@ func Link(ctx context.Context, storage driver.Driver, path string, args model.Li
if file.IsDir() {
return nil, nil, errors.WithStack(errs.NotFile)
}
key := stdpath.Join(storage.GetStorage().MountPath, path)
key := stdpath.Join(storage.GetStorage().MountPath, path) + ":" + args.IP
if link, ok := linkCache.Get(key); ok {
return link, file, nil
}

View File

@ -34,16 +34,21 @@ func CreateNestedFile(path string) (*os.File, error) {
// CreateTempFile create temp file from io.ReadCloser, and seek to 0
func CreateTempFile(r io.ReadCloser) (*os.File, error) {
if f, ok := r.(*os.File); ok {
return f, nil
}
f, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
if err != nil {
return nil, err
}
_, err = io.Copy(f, r)
if err != nil {
_ = os.Remove(f.Name())
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
_ = os.Remove(f.Name())
return nil, err
}
return f, nil

View File

@ -24,3 +24,26 @@ func ClientIP(r *http.Request) string {
return ""
}
func IsLocalIPAddr(ip string) bool {
return IsLocalIP(net.ParseIP(ip))
}
func IsLocalIP(ip net.IP) bool {
if ip == nil {
return false
}
if ip.IsLoopback() {
return true
}
ip4 := ip.To4()
if ip4 == nil {
return false
}
return ip4[0] == 10 || // 10.0.0.0/8
(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || // 172.16.0.0/12
(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
}

View File

@ -52,7 +52,7 @@ func Proxy(c *gin.Context) {
downProxyUrl := storage.GetStorage().DownProxyUrl
if downProxyUrl != "" {
_, ok := c.GetQuery("d")
if ok {
if !ok {
URL := fmt.Sprintf("%s%s?sign=%s",
strings.Split(downProxyUrl, "\n")[0],
utils.EncodePath(rawPath, true),
@ -103,7 +103,7 @@ func shouldProxy(storage driver.Driver, filename string) bool {
// 4. proxy_types
// solution: text_file + shouldProxy()
func canProxy(storage driver.Driver, filename string) bool {
if storage.Config().MustProxy() || storage.GetStorage().WebProxy {
if storage.Config().MustProxy() || storage.GetStorage().WebProxy || storage.GetStorage().WebdavProxy() {
return true
}
if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) {