Compare commits
9 Commits
cffa82226d
...
symbol_lin
Author | SHA1 | Date | |
---|---|---|---|
4687aa64ec | |||
3f38998fe5 | |||
1ec66adda0 | |||
60c8843734 | |||
f779053040 | |||
6becac74d0 | |||
e64a73eb67 | |||
6626afa6b6 | |||
6d35063027 |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[English Version](https://tank-doc.eyeblue.cn/en)
|
[English Version](https://tank-doc.eyeblue.cn/en)
|
||||||
|
|
||||||
# 蓝眼云盘(3.1.5)
|
# 蓝眼云盘(3.1.6)
|
||||||
[在线Demo](https://tanker.eyeblue.cn) (体验账号: demo 密码:123456)
|
[在线Demo](https://tanker.eyeblue.cn) (体验账号: demo 密码:123456)
|
||||||
|
|
||||||
蓝眼云盘是蓝眼开源系列代表作品之一,致力于打造精致,优雅,简约的云盘。核心功能如下:
|
蓝眼云盘是蓝眼开源系列代表作品之一,致力于打造精致,优雅,简约的云盘。核心功能如下:
|
||||||
@ -42,11 +42,11 @@
|
|||||||
|
|
||||||
如果您也想参与进来,请尽情的fork, star, post issue, pull requests
|
如果您也想参与进来,请尽情的fork, star, post issue, pull requests
|
||||||
|
|
||||||
当然你可以加入钉钉群一起直接交流,在钉钉群中可以获取最新beta版本。
|
当然你可以加入钉钉群(一群已满员)一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
群号:23156361
|
群号:44754005
|
||||||
|
|
||||||
|
|
||||||
### Support
|
### Support
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 136 KiB |
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.8994a208.css",
|
"main.css": "/static/css/main.b03c51fb.css",
|
||||||
"main.js": "/static/js/main.7a2a6dcd.js",
|
"main.js": "/static/js/main.b94b1947.js",
|
||||||
"static/media/logo.png": "/static/media/logo.847e54ef7fb4b744fad4.png",
|
"static/media/logo.png": "/static/media/logo.847e54ef7fb4b744fad4.png",
|
||||||
"static/media/empty.svg": "/static/media/empty.20ceb38d310075aa4c3cdaae210afb65.svg",
|
"static/media/empty.svg": "/static/media/empty.20ceb38d310075aa4c3cdaae210afb65.svg",
|
||||||
"static/media/psd.svg": "/static/media/psd.bf2ac5411c0132f292787f45855934f2.svg",
|
"static/media/psd.svg": "/static/media/psd.bf2ac5411c0132f292787f45855934f2.svg",
|
||||||
@ -18,11 +18,11 @@
|
|||||||
"static/media/folder.svg": "/static/media/folder.0bdd7430280c98bf4970b6af5a061c2c.svg",
|
"static/media/folder.svg": "/static/media/folder.0bdd7430280c98bf4970b6af5a061c2c.svg",
|
||||||
"static/media/archive.svg": "/static/media/archive.684c1e42f233aa9d53a8910d4fee091e.svg",
|
"static/media/archive.svg": "/static/media/archive.684c1e42f233aa9d53a8910d4fee091e.svg",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.8994a208.css.map": "/static/css/main.8994a208.css.map",
|
"main.b03c51fb.css.map": "/static/css/main.b03c51fb.css.map",
|
||||||
"main.7a2a6dcd.js.map": "/static/js/main.7a2a6dcd.js.map"
|
"main.b94b1947.js.map": "/static/js/main.b94b1947.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.8994a208.css",
|
"static/css/main.b03c51fb.css",
|
||||||
"static/js/main.7a2a6dcd.js"
|
"static/js/main.b94b1947.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="eyeblue tank"/><title>EyeblueTank</title><script defer="defer" src="/static/js/main.7a2a6dcd.js"></script><link href="/static/css/main.8994a208.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="eyeblue tank"/><title>EyeblueTank</title><script defer="defer" src="/static/js/main.b94b1947.js"></script><link href="/static/css/main.b03c51fb.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
build/html/static/css/main.b03c51fb.css
Normal file
8
build/html/static/css/main.b03c51fb.css
Normal file
File diff suppressed because one or more lines are too long
1
build/html/static/css/main.b03c51fb.css.map
Normal file
1
build/html/static/css/main.b03c51fb.css.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -11,7 +11,7 @@
|
|||||||
@REM prepare the variables.
|
@REM prepare the variables.
|
||||||
|
|
||||||
@REM version name
|
@REM version name
|
||||||
SET VERSION_NAME=tank-3.1.5
|
SET VERSION_NAME=tank-3.1.6
|
||||||
ECHO VERSION_NAME: %VERSION_NAME%
|
ECHO VERSION_NAME: %VERSION_NAME%
|
||||||
@REM golang proxy
|
@REM golang proxy
|
||||||
SET GOPROXY=https://goproxy.cn
|
SET GOPROXY=https://goproxy.cn
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
#
|
#
|
||||||
@ -9,7 +10,7 @@
|
|||||||
#prepare the variables.
|
#prepare the variables.
|
||||||
|
|
||||||
# version name
|
# version name
|
||||||
VERSION_NAME=tank-3.1.5
|
VERSION_NAME=tank-3.1.6
|
||||||
echo "VERSION_NAME: ${VERSION_NAME}"
|
echo "VERSION_NAME: ${VERSION_NAME}"
|
||||||
# golang proxy
|
# golang proxy
|
||||||
GOPROXY=https://goproxy.cn
|
GOPROXY=https://goproxy.cn
|
||||||
|
@ -14,7 +14,7 @@ const (
|
|||||||
//db table's prefix. tank31_ means current version is tank:3.1.x
|
//db table's prefix. tank31_ means current version is tank:3.1.x
|
||||||
TABLE_PREFIX = "tank31_"
|
TABLE_PREFIX = "tank31_"
|
||||||
|
|
||||||
VERSION = "3.1.5"
|
VERSION = "3.1.6"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config interface {
|
type Config interface {
|
||||||
|
@ -412,23 +412,35 @@ func (this *MatterDao) SizeByPuuidAndUserUuid(matterUuid string, userUuid string
|
|||||||
}
|
}
|
||||||
|
|
||||||
//delete a file from db and disk.
|
//delete a file from db and disk.
|
||||||
func (this *MatterDao) Delete(matter *Matter) {
|
func (this *MatterDao) Delete(matter *Matter, symbolLinkDir bool, symbolLevel int) {
|
||||||
|
|
||||||
// recursive if dir
|
// recursive if dir
|
||||||
if matter.Dir {
|
if matter.Dir {
|
||||||
|
stat, err := os.Lstat(matter.AbsolutePath())
|
||||||
|
if err == nil && stat.Mode()&os.ModeSymlink > 0 {
|
||||||
|
symbolLinkDir = true
|
||||||
|
}
|
||||||
|
if symbolLinkDir {
|
||||||
|
symbolLevel++
|
||||||
|
}
|
||||||
matters := this.FindByPuuidAndUserUuid(matter.Uuid, matter.UserUuid, nil)
|
matters := this.FindByPuuidAndUserUuid(matter.Uuid, matter.UserUuid, nil)
|
||||||
|
|
||||||
for _, f := range matters {
|
for _, f := range matters {
|
||||||
this.Delete(f)
|
this.Delete(f, symbolLinkDir, symbolLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete from db.
|
//delete from db.
|
||||||
db := core.CONTEXT.GetDB().Delete(&matter)
|
db := core.CONTEXT.GetDB().Delete(&matter)
|
||||||
this.PanicError(db.Error)
|
this.PanicError(db.Error)
|
||||||
|
|
||||||
|
if symbolLinkDir {
|
||||||
|
if symbolLevel == 0 {
|
||||||
|
os.Remove(matter.AbsolutePath())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
//delete dir from disk.
|
//delete dir from disk.
|
||||||
util.DeleteEmptyDir(matter.AbsolutePath())
|
util.DeleteEmptyDir(matter.AbsolutePath())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
//delete from db.
|
//delete from db.
|
||||||
@ -442,11 +454,12 @@ func (this *MatterDao) Delete(matter *Matter) {
|
|||||||
this.bridgeDao.DeleteByMatterUuid(matter.Uuid)
|
this.bridgeDao.DeleteByMatterUuid(matter.Uuid)
|
||||||
|
|
||||||
//delete from disk.
|
//delete from disk.
|
||||||
|
if !symbolLinkDir {
|
||||||
err := os.Remove(matter.AbsolutePath())
|
err := os.Remove(matter.AbsolutePath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.logger.Error("occur error when deleting file. %v", err)
|
this.logger.Error("occur error when deleting file. %v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ func (this *MatterService) Delete(request *http.Request, matter *Matter, user *U
|
|||||||
panic(result.BadRequest("matter cannot be nil"))
|
panic(result.BadRequest("matter cannot be nil"))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.matterDao.Delete(matter)
|
this.matterDao.Delete(matter, false, -1)
|
||||||
|
|
||||||
//re compute the size of Route.
|
//re compute the size of Route.
|
||||||
this.ComputeRouteSize(matter.Puuid, user)
|
this.ComputeRouteSize(matter.Puuid, user)
|
||||||
@ -987,7 +987,7 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
|
|||||||
|
|
||||||
this.logger.Info("mirror srcPath = %s destPath = %s", srcPath, destDirMatter.Path)
|
this.logger.Info("mirror srcPath = %s destPath = %s", srcPath, destDirMatter.Path)
|
||||||
|
|
||||||
if fileStat.IsDir() {
|
if fileStat.IsDir() || (fileStat.Mode()&os.ModeSymlink > 0) {
|
||||||
|
|
||||||
//判断当前文件夹下,文件是否已经存在了。
|
//判断当前文件夹下,文件是否已经存在了。
|
||||||
srcDirMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, destDirMatter.Uuid, TRUE, fileStat.Name())
|
srcDirMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, destDirMatter.Uuid, TRUE, fileStat.Name())
|
||||||
@ -1231,7 +1231,7 @@ func (this *MatterService) ScanPhysics(request *http.Request, user *User) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User) {
|
func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User) {
|
||||||
if !dirInfo.IsDir() {
|
if !dirInfo.IsDir() && !(dirInfo.Mode()&os.ModeSymlink > 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1277,7 +1277,7 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if fileInfo.IsDir() {
|
if fileInfo.IsDir() || (fileInfo.Mode()&os.ModeSymlink > 0) {
|
||||||
|
|
||||||
//create folder.
|
//create folder.
|
||||||
matter = this.createDirectory(request, dirMatter, name, user)
|
matter = this.createDirectory(request, dirMatter, name, user)
|
||||||
|
@ -278,6 +278,10 @@ func (this *ShareController) Browse(writer http.ResponseWriter, request *http.Re
|
|||||||
user := this.findUser(request)
|
user := this.findUser(request)
|
||||||
share := this.shareService.CheckShare(request, shareUuid, code, user)
|
share := this.shareService.CheckShare(request, shareUuid, code, user)
|
||||||
bridges := this.bridgeDao.FindByShareUuid(share.Uuid)
|
bridges := this.bridgeDao.FindByShareUuid(share.Uuid)
|
||||||
|
shareOwner := this.userDao.FindByUuid(share.UserUuid)
|
||||||
|
if shareOwner.Status == USER_STATUS_DISABLED {
|
||||||
|
panic(result.BadRequestI18n(request, i18n.UserDisabled))
|
||||||
|
}
|
||||||
|
|
||||||
if puuid == MATTER_ROOT {
|
if puuid == MATTER_ROOT {
|
||||||
|
|
||||||
|
@ -92,6 +92,11 @@ func (this *ShareService) ValidateMatter(request *http.Request, shareUuid string
|
|||||||
|
|
||||||
share := this.CheckShare(request, shareUuid, code, user)
|
share := this.CheckShare(request, shareUuid, code, user)
|
||||||
|
|
||||||
|
shareOwner := this.userDao.FindByUuid(share.UserUuid)
|
||||||
|
if shareOwner.Status == USER_STATUS_DISABLED {
|
||||||
|
panic(result.BadRequestI18n(request, i18n.UserDisabled))
|
||||||
|
}
|
||||||
|
|
||||||
//if shareRootUuid is root. Bridge must has record.
|
//if shareRootUuid is root. Bridge must has record.
|
||||||
if shareRootUuid == MATTER_ROOT {
|
if shareRootUuid == MATTER_ROOT {
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ func Zip(srcPath string, destPath string) error {
|
|||||||
fileHeader.Name = strings.TrimPrefix(path, baseDirPath)
|
fileHeader.Name = strings.TrimPrefix(path, baseDirPath)
|
||||||
|
|
||||||
// directory need /
|
// directory need /
|
||||||
if fileInfo.IsDir() {
|
if fileInfo.IsDir() || (fileInfo.Mode()&os.ModeSymlink > 0) {
|
||||||
fileHeader.Name += "/"
|
fileHeader.Name += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ func (fs *memFS) walk(op, fullname string, f func(dir *memFSNode, frag string, f
|
|||||||
Err: os.ErrNotExist,
|
Err: os.ErrNotExist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !child.mode.IsDir() {
|
if !child.mode.IsDir() && !(child.mode&os.ModeSymlink > 0) {
|
||||||
return &os.PathError{
|
return &os.PathError{
|
||||||
Op: op,
|
Op: op,
|
||||||
Path: original,
|
Path: original,
|
||||||
@ -468,7 +468,7 @@ func (f *memFileInfo) Name() string { return f.name }
|
|||||||
func (f *memFileInfo) Size() int64 { return f.size }
|
func (f *memFileInfo) Size() int64 { return f.size }
|
||||||
func (f *memFileInfo) Mode() os.FileMode { return f.mode }
|
func (f *memFileInfo) Mode() os.FileMode { return f.mode }
|
||||||
func (f *memFileInfo) ModTime() time.Time { return f.modTime }
|
func (f *memFileInfo) ModTime() time.Time { return f.modTime }
|
||||||
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() }
|
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() || (f.mode&os.ModeSymlink > 0) }
|
||||||
func (f *memFileInfo) Sys() interface{} { return nil }
|
func (f *memFileInfo) Sys() interface{} { return nil }
|
||||||
|
|
||||||
// A memFile is a File implementation for a memFSNode. It is a per-file (not
|
// A memFile is a File implementation for a memFSNode. It is a per-file (not
|
||||||
@ -495,7 +495,7 @@ func (f *memFile) Close() error {
|
|||||||
func (f *memFile) Read(p []byte) (int, error) {
|
func (f *memFile) Read(p []byte) (int, error) {
|
||||||
f.n.mu.Lock()
|
f.n.mu.Lock()
|
||||||
defer f.n.mu.Unlock()
|
defer f.n.mu.Unlock()
|
||||||
if f.n.mode.IsDir() {
|
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
|
||||||
return 0, os.ErrInvalid
|
return 0, os.ErrInvalid
|
||||||
}
|
}
|
||||||
if f.pos >= len(f.n.data) {
|
if f.pos >= len(f.n.data) {
|
||||||
@ -509,7 +509,7 @@ func (f *memFile) Read(p []byte) (int, error) {
|
|||||||
func (f *memFile) Readdir(count int) ([]os.FileInfo, error) {
|
func (f *memFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||||
f.n.mu.Lock()
|
f.n.mu.Lock()
|
||||||
defer f.n.mu.Unlock()
|
defer f.n.mu.Unlock()
|
||||||
if !f.n.mode.IsDir() {
|
if !f.n.mode.IsDir() && !(f.n.mode&os.ModeSymlink > 0) {
|
||||||
return nil, os.ErrInvalid
|
return nil, os.ErrInvalid
|
||||||
}
|
}
|
||||||
old := f.pos
|
old := f.pos
|
||||||
@ -564,7 +564,7 @@ func (f *memFile) Write(p []byte) (int, error) {
|
|||||||
f.n.mu.Lock()
|
f.n.mu.Lock()
|
||||||
defer f.n.mu.Unlock()
|
defer f.n.mu.Unlock()
|
||||||
|
|
||||||
if f.n.mode.IsDir() {
|
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
|
||||||
return 0, os.ErrInvalid
|
return 0, os.ErrInvalid
|
||||||
}
|
}
|
||||||
if f.pos < len(f.n.data) {
|
if f.pos < len(f.n.data) {
|
||||||
@ -693,7 +693,7 @@ func copyFiles(ctx context.Context, fs FileSystem, src, dst string, overwrite bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if srcStat.IsDir() {
|
if srcStat.IsDir() || (srcStat.Mode()&os.ModeSymlink > 0) {
|
||||||
if err := fs.Mkdir(ctx, dst, srcPerm); err != nil {
|
if err := fs.Mkdir(ctx, dst, srcPerm); err != nil {
|
||||||
return http.StatusForbidden, err
|
return http.StatusForbidden, err
|
||||||
}
|
}
|
||||||
@ -752,12 +752,12 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
|
|||||||
// This implementation is based on Walk's code in the standard path/filepath package.
|
// This implementation is based on Walk's code in the standard path/filepath package.
|
||||||
err := walkFn(name, info, nil)
|
err := walkFn(name, info, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if info.IsDir() && err == filepath.SkipDir {
|
if (info.IsDir() || (info.Mode()&os.ModeSymlink > 0)) && err == filepath.SkipDir {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !info.IsDir() || depth == 0 {
|
if (!info.IsDir() && !(info.Mode()&os.ModeSymlink > 0)) || depth == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if depth == 1 {
|
if depth == 1 {
|
||||||
@ -785,7 +785,7 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
|
|||||||
} else {
|
} else {
|
||||||
err = walkFS(ctx, fs, depth, filename, fileInfo, walkFn)
|
err = walkFS(ctx, fs, depth, filename, fileInfo, walkFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !fileInfo.IsDir() || err != filepath.SkipDir {
|
if (!fileInfo.IsDir() && !(fileInfo.Mode()&os.ModeSymlink > 0)) || err != filepath.SkipDir {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ func find(ctx context.Context, ss []string, fs FileSystem, name string) ([]strin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ss = append(ss, name)
|
ss = append(ss, name)
|
||||||
if stat.IsDir() {
|
if stat.IsDir() || (stat.Mode()&os.ModeSymlink > 0) {
|
||||||
f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0)
|
f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -480,7 +480,7 @@ func testFS(t *testing.T, fs FileSystem) {
|
|||||||
var stat os.FileInfo
|
var stat os.FileInfo
|
||||||
fileName := parts[0]
|
fileName := parts[0]
|
||||||
if stat, opErr = fs.Stat(ctx, fileName); opErr == nil {
|
if stat, opErr = fs.Stat(ctx, fileName); opErr == nil {
|
||||||
if stat.IsDir() {
|
if stat.IsDir() || (stat.Mode()&os.ModeSymlink > 0) {
|
||||||
got = "dir"
|
got = "dir"
|
||||||
} else {
|
} else {
|
||||||
got = strconv.Itoa(int(stat.Size()))
|
got = strconv.Itoa(int(stat.Size()))
|
||||||
@ -538,7 +538,7 @@ func TestMemFSRoot(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("i=%d: Stat: %v", i, err)
|
t.Fatalf("i=%d: Stat: %v", i, err)
|
||||||
}
|
}
|
||||||
if !stat.IsDir() {
|
if !stat.IsDir() && !(stat.Mode()&os.ModeSymlink > 0) {
|
||||||
t.Fatalf("i=%d: Stat.IsDir is false, want true", i)
|
t.Fatalf("i=%d: Stat.IsDir is false, want true", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ func Props(ctx context.Context, fs FileSystem, ls LockSystem, name string, pname
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
isDir := fi.IsDir()
|
isDir := fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0)
|
||||||
|
|
||||||
var deadProps map[xml.Name]Property
|
var deadProps map[xml.Name]Property
|
||||||
if dph, ok := f.(DeadPropsHolder); ok {
|
if dph, ok := f.(DeadPropsHolder); ok {
|
||||||
|
@ -177,7 +177,7 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status
|
|||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
||||||
if fi, err := h.FileSystem.Stat(ctx, reqPath); err == nil {
|
if fi, err := h.FileSystem.Stat(ctx, reqPath); err == nil {
|
||||||
if fi.IsDir() {
|
if fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0) {
|
||||||
allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND"
|
allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND"
|
||||||
} else {
|
} else {
|
||||||
allow = "OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT"
|
allow = "OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT"
|
||||||
@ -207,7 +207,7 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusNotFound, err
|
return http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
if fi.IsDir() {
|
if fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0) {
|
||||||
return http.StatusMethodNotAllowed, nil
|
return http.StatusMethodNotAllowed, nil
|
||||||
}
|
}
|
||||||
etag, err := findETag(ctx, h.FileSystem, h.LockSystem, reqPath, fi)
|
etag, err := findETag(ctx, h.FileSystem, h.LockSystem, reqPath, fi)
|
||||||
@ -557,7 +557,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
href := path.Join(h.Prefix, reqPath)
|
href := path.Join(h.Prefix, reqPath)
|
||||||
if href != "/" && info.IsDir() {
|
if href != "/" && (info.IsDir() || (info.Mode()&os.ModeSymlink > 0)) {
|
||||||
href += "/"
|
href += "/"
|
||||||
}
|
}
|
||||||
return mw.write(MakePropstatResponse(href, pstats))
|
return mw.write(MakePropstatResponse(href, pstats))
|
||||||
|
Reference in New Issue
Block a user