Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
44cb8aaafe | |||
51f5d1b3c4 | |||
36e0d6f787 | |||
3d0065bdcf | |||
7bf8071095 | |||
30d39f8e10 | |||
20d3ef7de6 | |||
86e5dae4d1 | |||
d89b1d4871 | |||
080e6fb22a | |||
e1cd71616d | |||
c92e11dad5 | |||
b52e8747fa | |||
14305748f0 | |||
44f8112e53 | |||
6a90b1d40a | |||
b42ec3e810 | |||
28875ce304 | |||
9b99e8ab70 | |||
98872a8fdb | |||
ce4a295008 | |||
bc1babb5b5 |
30
.github/workflows/build_docker.yml
vendored
30
.github/workflows/build_docker.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_docker:
|
build_docker:
|
||||||
name: Docker
|
name: Build docker
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -36,4 +36,30 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|
||||||
|
build_docker_with_aria2:
|
||||||
|
needs: build_docker
|
||||||
|
name: Build docker with aria2
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: alist-org/with_aria2
|
||||||
|
ref: main
|
||||||
|
persist-credentials: false
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Commit
|
||||||
|
run: |
|
||||||
|
git config --local user.email "i@nn.ci"
|
||||||
|
git config --local user.name "Noah Hsu"
|
||||||
|
git commit --allow-empty -m "Trigger build for ${{ github.sha }}"
|
||||||
|
|
||||||
|
- name: Push commit
|
||||||
|
uses: ad-m/github-push-action@master
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.MY_TOKEN }}
|
||||||
|
branch: main
|
||||||
|
repository: alist-org/with_aria2
|
30
.github/workflows/release_docker.yml
vendored
30
.github/workflows/release_docker.yml
vendored
@ -7,7 +7,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release_docker:
|
release_docker:
|
||||||
name: Docker
|
name: Release Docker
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -39,4 +39,30 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/386,linux/arm/v6,linux/s390x
|
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/386,linux/arm/v6,linux/s390x
|
||||||
|
|
||||||
|
release_docker_with_aria2:
|
||||||
|
needs: release_docker
|
||||||
|
name: Release docker with aria2
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: alist-org/with_aria2
|
||||||
|
ref: main
|
||||||
|
persist-credentials: false
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Add tag
|
||||||
|
run: |
|
||||||
|
git config --local user.email "i@nn.ci"
|
||||||
|
git config --local user.name "Noah Hsu"
|
||||||
|
git tag -a ${{ github.ref_name }} -m "release ${{ github.ref_name }}"
|
||||||
|
|
||||||
|
- name: Push tags
|
||||||
|
uses: ad-m/github-push-action@master
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.MY_TOKEN }}
|
||||||
|
branch: main
|
||||||
|
repository: alist-org/with_aria2
|
||||||
|
@ -83,8 +83,7 @@ func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dirName strin
|
|||||||
}
|
}
|
||||||
pathname = "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
|
pathname = "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
|
||||||
}
|
}
|
||||||
_, err := d.post(pathname,
|
_, err := d.post(pathname, data, nil)
|
||||||
data, nil)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +221,22 @@ func (d *Yun139) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ = iota //ignore first value by assigning to blank identifier
|
||||||
|
KB = 1 << (10 * iota)
|
||||||
|
MB
|
||||||
|
GB
|
||||||
|
TB
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPartSize(size int64) int64 {
|
||||||
|
// 网盘对于分片数量存在上限
|
||||||
|
if size/GB > 30 {
|
||||||
|
return 512 * MB
|
||||||
|
}
|
||||||
|
return 100 * MB
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
data := base.Json{
|
data := base.Json{
|
||||||
"manualRename": 2,
|
"manualRename": 2,
|
||||||
@ -267,17 +282,17 @@ func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
// Progress
|
// Progress
|
||||||
p := driver.NewProgress(stream.GetSize(), up)
|
p := driver.NewProgress(stream.GetSize(), up)
|
||||||
|
|
||||||
var Default int64 = 104857600
|
var partSize = getPartSize(stream.GetSize())
|
||||||
part := (stream.GetSize() + Default - 1) / Default
|
part := (stream.GetSize() + partSize - 1) / partSize
|
||||||
for i := int64(0); i < part; i++ {
|
for i := int64(0); i < part; i++ {
|
||||||
if utils.IsCanceled(ctx) {
|
if utils.IsCanceled(ctx) {
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
start := i * Default
|
start := i * partSize
|
||||||
byteSize := stream.GetSize() - start
|
byteSize := stream.GetSize() - start
|
||||||
if byteSize > Default {
|
if byteSize > partSize {
|
||||||
byteSize = Default
|
byteSize = partSize
|
||||||
}
|
}
|
||||||
|
|
||||||
limitReader := io.LimitReader(stream, byteSize)
|
limitReader := io.LimitReader(stream, byteSize)
|
||||||
@ -301,6 +316,11 @@ func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Debugf("%+v", res)
|
log.Debugf("%+v", res)
|
||||||
|
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|||||||
SetResult(&resp).
|
SetResult(&resp).
|
||||||
SetHeader("Authorization", d.AccessToken).
|
SetHeader("Authorization", d.AccessToken).
|
||||||
SetBody(MoveCopyReq{
|
SetBody(MoveCopyReq{
|
||||||
SrcDir: srcObj.GetPath(),
|
SrcDir: path.Dir(srcObj.GetPath()),
|
||||||
DstDir: dstDir.GetPath(),
|
DstDir: dstDir.GetPath(),
|
||||||
Names: []string{srcObj.GetName()},
|
Names: []string{srcObj.GetName()},
|
||||||
}).Post(url)
|
}).Post(url)
|
||||||
@ -135,7 +135,7 @@ func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|||||||
SetResult(&resp).
|
SetResult(&resp).
|
||||||
SetHeader("Authorization", d.AccessToken).
|
SetHeader("Authorization", d.AccessToken).
|
||||||
SetBody(MoveCopyReq{
|
SetBody(MoveCopyReq{
|
||||||
SrcDir: srcObj.GetPath(),
|
SrcDir: path.Dir(srcObj.GetPath()),
|
||||||
DstDir: dstDir.GetPath(),
|
DstDir: dstDir.GetPath(),
|
||||||
Names: []string{srcObj.GetName()},
|
Names: []string{srcObj.GetName()},
|
||||||
}).Post(url)
|
}).Post(url)
|
||||||
@ -149,7 +149,7 @@ func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
SetResult(&resp).
|
SetResult(&resp).
|
||||||
SetHeader("Authorization", d.AccessToken).
|
SetHeader("Authorization", d.AccessToken).
|
||||||
SetBody(RemoveReq{
|
SetBody(RemoveReq{
|
||||||
Dir: obj.GetPath(),
|
Dir: path.Dir(obj.GetPath()),
|
||||||
Names: []string{obj.GetName()},
|
Names: []string{obj.GetName()},
|
||||||
}).Post(url)
|
}).Post(url)
|
||||||
return checkResp(resp, err)
|
return checkResp(resp, err)
|
||||||
|
@ -251,7 +251,11 @@ func (d *AliDrive) Put(ctx context.Context, dstDir model.Obj, stream model.FileS
|
|||||||
if utils.IsCanceled(ctx) {
|
if utils.IsCanceled(ctx) {
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest("PUT", partInfo.UploadUrl, io.LimitReader(file, DEFAULT))
|
url := partInfo.UploadUrl
|
||||||
|
if d.InternalUpload {
|
||||||
|
url = partInfo.InternalUploadUrl
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("PUT", url, io.LimitReader(file, DEFAULT))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ type Addition struct {
|
|||||||
OrderBy string `json:"order_by" type:"select" options:"name,size,updated_at,created_at"`
|
OrderBy string `json:"order_by" type:"select" options:"name,size,updated_at,created_at"`
|
||||||
OrderDirection string `json:"order_direction" type:"select" options:"ASC,DESC"`
|
OrderDirection string `json:"order_direction" type:"select" options:"ASC,DESC"`
|
||||||
RapidUpload bool `json:"rapid_upload"`
|
RapidUpload bool `json:"rapid_upload"`
|
||||||
|
InternalUpload bool `json:"internal_upload"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
|
@ -48,7 +48,8 @@ type UploadResp struct {
|
|||||||
FileId string `json:"file_id"`
|
FileId string `json:"file_id"`
|
||||||
UploadId string `json:"upload_id"`
|
UploadId string `json:"upload_id"`
|
||||||
PartInfoList []struct {
|
PartInfoList []struct {
|
||||||
UploadUrl string `json:"upload_url"`
|
UploadUrl string `json:"upload_url"`
|
||||||
|
InternalUploadUrl string `json:"internal_upload_url"`
|
||||||
} `json:"part_info_list"`
|
} `json:"part_info_list"`
|
||||||
|
|
||||||
RapidUpload bool `json:"rapid_upload"`
|
RapidUpload bool `json:"rapid_upload"`
|
||||||
|
@ -54,6 +54,7 @@ func (d *AliyundriveShare) Drop(ctx context.Context) error {
|
|||||||
if d.cron != nil {
|
if d.cron != nil {
|
||||||
d.cron.Stop()
|
d.cron.Stop()
|
||||||
}
|
}
|
||||||
|
d.DriveId = ""
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ func (d *BaiduNetdisk) create(path string, size int64, isdir int, uploadid, bloc
|
|||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
"method": "create",
|
"method": "create",
|
||||||
}
|
}
|
||||||
data := fmt.Sprintf("path=%s&size=%d&isdir=%d", encodeURIComponent(path), size, isdir)
|
data := fmt.Sprintf("path=%s&size=%d&isdir=%d&rtype=3", encodeURIComponent(path), size, isdir)
|
||||||
if uploadid != "" {
|
if uploadid != "" {
|
||||||
data += fmt.Sprintf("&uploadid=%s&block_list=%s", uploadid, block_list)
|
data += fmt.Sprintf("&uploadid=%s&block_list=%s", uploadid, block_list)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func (d *GoogleDrive) Link(ctx context.Context, file model.Obj, args model.LinkA
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
link := model.Link{
|
link := model.Link{
|
||||||
URL: url + "&alt=media",
|
URL: url + "&alt=media&acknowledgeAbuse=true",
|
||||||
Header: http.Header{
|
Header: http.Header{
|
||||||
"Authorization": []string{"Bearer " + d.AccessToken},
|
"Authorization": []string{"Bearer " + d.AccessToken},
|
||||||
},
|
},
|
||||||
|
@ -210,9 +210,11 @@ func (d *LanZou) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
_, err := d._post(d.BaseUrl+"/fileup.php", func(req *resty.Request) {
|
_, err := d._post(d.BaseUrl+"/fileup.php", func(req *resty.Request) {
|
||||||
req.SetFormData(map[string]string{
|
req.SetFormData(map[string]string{
|
||||||
"task": "1",
|
"task": "1",
|
||||||
|
"vie": "2",
|
||||||
|
"ve": "2",
|
||||||
"id": "WU_FILE_0",
|
"id": "WU_FILE_0",
|
||||||
"name": stream.GetName(),
|
"name": stream.GetName(),
|
||||||
"folder_id": dstDir.GetID(),
|
"folder_id_bb_n": dstDir.GetID(),
|
||||||
}).SetFileReader("upload_file", stream.GetName(), stream).SetContext(ctx)
|
}).SetFileReader("upload_file", stream.GetName(), stream).SetContext(ctx)
|
||||||
}, &resp, true)
|
}, &resp, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -151,7 +151,7 @@ func (d *Local) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
|
|||||||
|
|
||||||
func (d *Local) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *Local) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
fullPath := filepath.Join(parentDir.GetPath(), dirName)
|
fullPath := filepath.Join(parentDir.GetPath(), dirName)
|
||||||
err := os.MkdirAll(fullPath, 0700)
|
err := os.MkdirAll(fullPath, 0777)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ func (d *Onedrive) Request(url string, method string, callback base.ReqCallback,
|
|||||||
|
|
||||||
func (d *Onedrive) getFiles(path string) ([]File, error) {
|
func (d *Onedrive) getFiles(path string) ([]File, error) {
|
||||||
var res []File
|
var res []File
|
||||||
nextLink := d.GetMetaUrl(false, path) + "/children?$expand=thumbnails"
|
nextLink := d.GetMetaUrl(false, path) + "/children?$top=5000&$expand=thumbnails($select=medium)&$select=id,name,size,lastModifiedDateTime,content.downloadUrl,file,parentReference"
|
||||||
for nextLink != "" {
|
for nextLink != "" {
|
||||||
var files Files
|
var files Files
|
||||||
_, err := d.Request(nextLink, http.MethodGet, nil, &files)
|
_, err := d.Request(nextLink, http.MethodGet, nil, &files)
|
||||||
|
@ -148,6 +148,9 @@ func (d *S3) listV2(prefix string) ([]model.Obj, error) {
|
|||||||
files = append(files, &file)
|
files = append(files, &file)
|
||||||
}
|
}
|
||||||
for _, object := range listObjectsResult.Contents {
|
for _, object := range listObjectsResult.Contents {
|
||||||
|
if strings.HasSuffix(*object.Key, "/") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
name := path.Base(*object.Key)
|
name := path.Base(*object.Key)
|
||||||
if name == getPlaceholderName(d.Placeholder) || name == d.Placeholder {
|
if name == getPlaceholderName(d.Placeholder) || name == d.Placeholder {
|
||||||
continue
|
continue
|
||||||
|
5
go.mod
5
go.mod
@ -5,9 +5,10 @@ go 1.19
|
|||||||
require (
|
require (
|
||||||
github.com/SheltonZhu/115driver v1.0.13
|
github.com/SheltonZhu/115driver v1.0.13
|
||||||
github.com/Xhofe/go-cache v0.0.0-20220723083548-714439c8af9a
|
github.com/Xhofe/go-cache v0.0.0-20220723083548-714439c8af9a
|
||||||
github.com/aws/aws-sdk-go v1.44.174
|
github.com/aws/aws-sdk-go v1.44.194
|
||||||
github.com/blevesearch/bleve/v2 v2.3.6
|
github.com/blevesearch/bleve/v2 v2.3.6
|
||||||
github.com/caarlos0/env/v6 v6.10.1
|
github.com/caarlos0/env/v6 v6.10.1
|
||||||
|
github.com/caarlos0/env/v7 v7.0.0
|
||||||
github.com/deckarep/golang-set/v2 v2.1.0
|
github.com/deckarep/golang-set/v2 v2.1.0
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/gin-contrib/cors v1.4.0
|
github.com/gin-contrib/cors v1.4.0
|
||||||
@ -35,7 +36,7 @@ require (
|
|||||||
gorm.io/driver/mysql v1.4.5
|
gorm.io/driver/mysql v1.4.5
|
||||||
gorm.io/driver/postgres v1.4.6
|
gorm.io/driver/postgres v1.4.6
|
||||||
gorm.io/driver/sqlite v1.4.4
|
gorm.io/driver/sqlite v1.4.4
|
||||||
gorm.io/gorm v1.24.3
|
gorm.io/gorm v1.24.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
5
go.sum
5
go.sum
@ -16,6 +16,8 @@ github.com/aws/aws-sdk-go v1.44.173 h1:8kXIxvQnBpGhmR3Eof6SnCKgR0q5/L/3Qbv9vAC5w
|
|||||||
github.com/aws/aws-sdk-go v1.44.173/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
github.com/aws/aws-sdk-go v1.44.173/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||||
github.com/aws/aws-sdk-go v1.44.174 h1:9lR4a6MKQW/t6YCG0ZKAt1GAkjdEPP8sWch/pfcuR0c=
|
github.com/aws/aws-sdk-go v1.44.174 h1:9lR4a6MKQW/t6YCG0ZKAt1GAkjdEPP8sWch/pfcuR0c=
|
||||||
github.com/aws/aws-sdk-go v1.44.174/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
github.com/aws/aws-sdk-go v1.44.174/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||||
|
github.com/aws/aws-sdk-go v1.44.194 h1:1ZDK+QDcc5oRbZGgRZSz561eR8XVizXCeGpoZKo33NU=
|
||||||
|
github.com/aws/aws-sdk-go v1.44.194/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
|
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.6 h1:NlntUHcV5CSWIhpugx4d/BRMGCiaoI8ZZXrXlahzNq4=
|
github.com/blevesearch/bleve/v2 v2.3.6 h1:NlntUHcV5CSWIhpugx4d/BRMGCiaoI8ZZXrXlahzNq4=
|
||||||
@ -56,6 +58,7 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8
|
|||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
|
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
|
||||||
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
|
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
|
||||||
|
github.com/caarlos0/env/v7 v7.0.0/go.mod h1:LPPWniDUq4JaO6Q41vtlyikhMknqymCLBw0eX4dcH1E=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -327,3 +330,5 @@ gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
|||||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg=
|
gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg=
|
||||||
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
|
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||||
|
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
|
@ -48,6 +48,7 @@ func initUser() {
|
|||||||
Role: model.GUEST,
|
Role: model.GUEST,
|
||||||
BasePath: "/",
|
BasePath: "/",
|
||||||
Permission: 0,
|
Permission: 0,
|
||||||
|
Disabled: true,
|
||||||
}
|
}
|
||||||
if err := db.CreateUser(guest); err != nil {
|
if err := db.CreateUser(guest); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -51,7 +51,7 @@ func InitDB() {
|
|||||||
if !(strings.HasSuffix(database.DBFile, ".db") && len(database.DBFile) > 3) {
|
if !(strings.HasSuffix(database.DBFile, ".db") && len(database.DBFile) > 3) {
|
||||||
log.Fatalf("db name error.")
|
log.Fatalf("db name error.")
|
||||||
}
|
}
|
||||||
dB, err = gorm.Open(sqlite.Open(fmt.Sprintf("%s?_journal=WAL&_locking=EXCLUSIVE&_vacuum=incremental",
|
dB, err = gorm.Open(sqlite.Open(fmt.Sprintf("%s?_journal=WAL&_vacuum=incremental",
|
||||||
database.DBFile)), gormConfig)
|
database.DBFile)), gormConfig)
|
||||||
}
|
}
|
||||||
case "mysql":
|
case "mysql":
|
||||||
|
@ -35,19 +35,22 @@ func setLog(l *logrus.Logger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Log() {
|
func Log() {
|
||||||
log.SetOutput(logrus.StandardLogger().Out)
|
|
||||||
setLog(logrus.StandardLogger())
|
setLog(logrus.StandardLogger())
|
||||||
setLog(utils.Log)
|
setLog(utils.Log)
|
||||||
logConfig := conf.Conf.Log
|
logConfig := conf.Conf.Log
|
||||||
if logConfig.Enable {
|
if logConfig.Enable {
|
||||||
mw := io.MultiWriter(os.Stdout, &lumberjack.Logger{
|
var w io.Writer = &lumberjack.Logger{
|
||||||
Filename: logConfig.Name,
|
Filename: logConfig.Name,
|
||||||
MaxSize: logConfig.MaxSize, // megabytes
|
MaxSize: logConfig.MaxSize, // megabytes
|
||||||
MaxBackups: logConfig.MaxBackups,
|
MaxBackups: logConfig.MaxBackups,
|
||||||
MaxAge: logConfig.MaxAge, //days
|
MaxAge: logConfig.MaxAge, //days
|
||||||
Compress: logConfig.Compress, // disabled by default
|
Compress: logConfig.Compress, // disabled by default
|
||||||
})
|
}
|
||||||
logrus.SetOutput(mw)
|
if flags.Debug || flags.Dev {
|
||||||
|
w = io.MultiWriter(os.Stdout, w)
|
||||||
|
}
|
||||||
|
logrus.SetOutput(w)
|
||||||
}
|
}
|
||||||
|
log.SetOutput(logrus.StandardLogger().Out)
|
||||||
utils.Log.Infof("init logrus...")
|
utils.Log.Infof("init logrus...")
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@ const (
|
|||||||
const (
|
const (
|
||||||
// site
|
// site
|
||||||
VERSION = "version"
|
VERSION = "version"
|
||||||
ApiUrl = "api_url"
|
|
||||||
BasePath = "base_path"
|
|
||||||
SiteTitle = "site_title"
|
SiteTitle = "site_title"
|
||||||
Announcement = "announcement"
|
Announcement = "announcement"
|
||||||
AllowIndexed = "allow_indexed"
|
AllowIndexed = "allow_indexed"
|
||||||
|
@ -18,6 +18,7 @@ type User struct {
|
|||||||
Password string `json:"password"` // password
|
Password string `json:"password"` // password
|
||||||
BasePath string `json:"base_path"` // base path
|
BasePath string `json:"base_path"` // base path
|
||||||
Role int `json:"role"` // user's role
|
Role int `json:"role"` // user's role
|
||||||
|
Disabled bool `json:"disabled"`
|
||||||
// Determine permissions by bit
|
// Determine permissions by bit
|
||||||
// 0: can see hidden files
|
// 0: can see hidden files
|
||||||
// 1: can access without password
|
// 1: can access without password
|
||||||
|
@ -31,6 +31,8 @@ func BuildIndex(ctx context.Context, indexPaths, ignorePaths []string, maxDepth
|
|||||||
objCount uint64 = 0
|
objCount uint64 = 0
|
||||||
fi model.Obj
|
fi model.Obj
|
||||||
)
|
)
|
||||||
|
log.Infof("build index for: %+v", indexPaths)
|
||||||
|
log.Infof("ignore paths: %+v", ignorePaths)
|
||||||
Running.Store(true)
|
Running.Store(true)
|
||||||
Quit = make(chan struct{}, 1)
|
Quit = make(chan struct{}, 1)
|
||||||
indexMQ := mq.NewInMemoryMQ[ObjWithParent]()
|
indexMQ := mq.NewInMemoryMQ[ObjWithParent]()
|
||||||
|
@ -53,9 +53,10 @@ func updateIgnorePaths() {
|
|||||||
res, err := base.RestyClient.R().Get(url)
|
res, err := base.RestyClient.R().Get(url)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
allowIndexed = utils.Json.Get(res.Body(), "data", conf.AllowIndexed).ToBool()
|
allowIndexed = utils.Json.Get(res.Body(), "data", conf.AllowIndexed).ToBool()
|
||||||
|
v3Visited[addition.Address] = allowIndexed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if allowIndexed {
|
if !allowIndexed {
|
||||||
ignorePaths = append(ignorePaths, storage.GetStorage().MountPath)
|
ignorePaths = append(ignorePaths, storage.GetStorage().MountPath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,7 +75,17 @@ func EncodePath(path string, all ...bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func JoinBasePath(basePath, reqPath string) (string, error) {
|
func JoinBasePath(basePath, reqPath string) (string, error) {
|
||||||
if strings.HasSuffix(reqPath, "..") || strings.Contains(reqPath, "../") {
|
/** relative path:
|
||||||
|
* 1. ..
|
||||||
|
* 2. ../
|
||||||
|
* 3. /..
|
||||||
|
* 4. /../
|
||||||
|
* 5. /a/b/..
|
||||||
|
*/
|
||||||
|
if reqPath == ".." ||
|
||||||
|
strings.HasSuffix(reqPath, "/..") ||
|
||||||
|
strings.HasPrefix(reqPath, "../") ||
|
||||||
|
strings.Contains(reqPath, "/../") {
|
||||||
return "", errs.RelativePath
|
return "", errs.RelativePath
|
||||||
}
|
}
|
||||||
return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)), nil
|
return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)), nil
|
||||||
|
@ -3,24 +3,27 @@ package common
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
stdpath "path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/setting"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetApiUrl(r *http.Request) string {
|
func GetApiUrl(r *http.Request) string {
|
||||||
api := conf.Conf.SiteURL
|
api := conf.Conf.SiteURL
|
||||||
if api == "" {
|
if strings.HasPrefix(api, "http") {
|
||||||
api = setting.GetStr(conf.ApiUrl)
|
return api
|
||||||
}
|
}
|
||||||
if r != nil && api == "" {
|
if r != nil && api == "" {
|
||||||
protocol := "http"
|
protocol := "http"
|
||||||
if r.TLS != nil {
|
if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
|
||||||
protocol = "https"
|
protocol = "https"
|
||||||
}
|
}
|
||||||
api = fmt.Sprintf("%s://%s", protocol, r.Host)
|
host := r.Host
|
||||||
|
if r.Header.Get("X-Forwarded-Host") != "" {
|
||||||
|
host = r.Header.Get("X-Forwarded-Host")
|
||||||
|
}
|
||||||
|
api = fmt.Sprintf("%s://%s", protocol, stdpath.Join(host, api))
|
||||||
}
|
}
|
||||||
strings.TrimSuffix(api, "/")
|
strings.TrimSuffix(api, "/")
|
||||||
return api
|
return api
|
||||||
|
@ -67,6 +67,10 @@ func UpdateUser(c *gin.Context) {
|
|||||||
if req.OtpSecret == "" {
|
if req.OtpSecret == "" {
|
||||||
req.OtpSecret = user.OtpSecret
|
req.OtpSecret = user.OtpSecret
|
||||||
}
|
}
|
||||||
|
if req.Disabled && req.IsAdmin() {
|
||||||
|
common.ErrorStrResp(c, "admin user can not be disabled", 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := op.UpdateUser(&req); err != nil {
|
if err := op.UpdateUser(&req); err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,6 +33,11 @@ func Auth(c *gin.Context) {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if guest.Disabled {
|
||||||
|
common.ErrorStrResp(c, "Guest user is disabled, login please", 401)
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
c.Set("user", guest)
|
c.Set("user", guest)
|
||||||
log.Debugf("use empty token: %+v", guest)
|
log.Debugf("use empty token: %+v", guest)
|
||||||
c.Next()
|
c.Next()
|
||||||
@ -50,6 +55,11 @@ func Auth(c *gin.Context) {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if user.Disabled {
|
||||||
|
common.ErrorStrResp(c, "Current user is disabled, replace please", 401)
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
c.Set("user", user)
|
c.Set("user", user)
|
||||||
log.Debugf("use login token: %+v", user)
|
log.Debugf("use login token: %+v", user)
|
||||||
c.Next()
|
c.Next()
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/setting"
|
|
||||||
"github.com/alist-org/alist/v3/pkg/utils"
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,11 +24,6 @@ func getSiteConfig() SiteConfig {
|
|||||||
BasePath: u.Path,
|
BasePath: u.Path,
|
||||||
Cdn: strings.ReplaceAll(strings.TrimSuffix(conf.Conf.Cdn, "/"), "$version", conf.WebVersion),
|
Cdn: strings.ReplaceAll(strings.TrimSuffix(conf.Conf.Cdn, "/"), "$version", conf.WebVersion),
|
||||||
}
|
}
|
||||||
// try to get old config
|
|
||||||
if siteConfig.ApiURL == "" {
|
|
||||||
siteConfig.ApiURL = setting.GetStr(conf.ApiUrl)
|
|
||||||
siteConfig.BasePath = setting.GetStr(conf.BasePath)
|
|
||||||
}
|
|
||||||
if siteConfig.BasePath != "" {
|
if siteConfig.BasePath != "" {
|
||||||
siteConfig.BasePath = utils.FixAndCleanPath(siteConfig.BasePath)
|
siteConfig.BasePath = utils.FixAndCleanPath(siteConfig.BasePath)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user