mirror of
https://github.com/siyuan-note/siyuan
synced 2026-04-21 13:37:52 +00:00
🎨 Improve some file operation APIs https://github.com/siyuan-note/siyuan/issues/17409 (#17460)
This commit is contained in:
parent
ca38872f11
commit
cce07ff01f
2 changed files with 216 additions and 86 deletions
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
|
|
@ -36,8 +37,8 @@ func zip(c *gin.Context) {
|
|||
|
||||
var entryPath, zipFilePath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("path", &entryPath, true, false),
|
||||
util.BindJsonArg("zipPath", &zipFilePath, true, false),
|
||||
util.BindJsonArg("path", &entryPath, true, true), // 相对于工作空间的路径(待打包目录或文件)
|
||||
util.BindJsonArg("zipPath", &zipFilePath, true, true), // 相对于工作空间的路径(生成的 zip)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
@ -56,8 +57,9 @@ func zip(c *gin.Context) {
|
|||
|
||||
zipFile, err := gulu.Zip.Create(zipAbsFilePath)
|
||||
if err != nil {
|
||||
logging.LogErrorf("create zip [%s] failed: %s", zipAbsFilePath, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = "create zip file failed" + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -68,14 +70,16 @@ func zip(c *gin.Context) {
|
|||
err = zipFile.AddEntry(base, entryAbsPath)
|
||||
}
|
||||
if err != nil {
|
||||
logging.LogErrorf("zip add entry [%s] failed: %s", entryAbsPath, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = "zip failed" + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
if err = zipFile.Close(); err != nil {
|
||||
logging.LogErrorf("close zip [%s] failed: %s", zipAbsFilePath, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = "close zip file failed" + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -91,8 +95,8 @@ func unzip(c *gin.Context) {
|
|||
|
||||
var zipFilePath, entryPath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("zipPath", &zipFilePath, true, false),
|
||||
util.BindJsonArg("path", &entryPath, true, false),
|
||||
util.BindJsonArg("zipPath", &zipFilePath, true, true), // 相对于工作空间的路径
|
||||
util.BindJsonArg("path", &entryPath, true, false), // 相对于工作空间的路径(解压目标目录)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
@ -109,9 +113,16 @@ func unzip(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := gulu.Zip.Unzip(zipAbsFilePath, entryAbsPath); err != nil {
|
||||
if !gulu.File.IsExist(zipAbsFilePath) {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = "zip file does not exist"
|
||||
return
|
||||
}
|
||||
|
||||
if err := gulu.Zip.Unzip(zipAbsFilePath, entryAbsPath); err != nil {
|
||||
logging.LogErrorf("unzip [%s] -> [%s] failed: %s", zipAbsFilePath, entryAbsPath, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = "unzip failed" + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ import (
|
|||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
// errMsgSeeKernelLog 接在 API 错误提示末尾,引导用户查看内核日志以获取完整信息(避免在 Msg 暴露工作空间绝对路径)。
|
||||
const errMsgSeeKernelLog = ". For details, see the SiYuan kernel log."
|
||||
|
||||
func getUniqueFilename(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
@ -47,7 +50,13 @@ func getUniqueFilename(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
filePath := arg["path"].(string)
|
||||
var filePath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("path", &filePath, true, true),
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
ret.Data = map[string]any{
|
||||
"path": util.GetUniqueFilename(filePath),
|
||||
}
|
||||
|
|
@ -62,36 +71,80 @@ func globalCopyFiles(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
var srcsArg []any
|
||||
var destDirArg string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("srcs", &srcsArg, true, true), // 绝对路径
|
||||
util.BindJsonArg("destDir", &destDirArg, true, false), // 相对于工作空间的路径
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
var srcs []string
|
||||
srcsArg := arg["srcs"].([]any)
|
||||
for _, s := range srcsArg {
|
||||
srcs = append(srcs, s.(string))
|
||||
str, elemOk := s.(string)
|
||||
if !elemOk {
|
||||
ret.Code = -1
|
||||
ret.Msg = "Field [srcs]: each element should be of type [String]"
|
||||
return
|
||||
}
|
||||
srcs = append(srcs, str)
|
||||
}
|
||||
|
||||
for i, src := range srcs {
|
||||
if !filepath.IsAbs(src) {
|
||||
logging.LogErrorf("global copy files src [%s] is not an absolute path", src)
|
||||
ret.Code = -1
|
||||
ret.Msg = "Field [srcs]: each path must be absolute"
|
||||
return
|
||||
}
|
||||
|
||||
absSrc, _ := filepath.Abs(src)
|
||||
|
||||
if !filelock.IsExist(absSrc) {
|
||||
msg := fmt.Sprintf("file [%s] does not exist", src)
|
||||
logging.LogErrorf(msg)
|
||||
logging.LogErrorf("file [%s] does not exist", src)
|
||||
ret.Code = -1
|
||||
ret.Msg = msg
|
||||
ret.Msg = fmt.Sprintf("file [%s] does not exist", src)
|
||||
return
|
||||
}
|
||||
|
||||
if util.IsSensitivePath(absSrc) {
|
||||
msg := fmt.Sprintf("refuse to copy sensitive file [%s]", src)
|
||||
logging.LogErrorf(msg)
|
||||
logging.LogErrorf("refuse to copy sensitive file [%s]", src)
|
||||
ret.Code = -2
|
||||
ret.Msg = msg
|
||||
ret.Msg = fmt.Sprintf("refuse to copy sensitive file [%s]", src)
|
||||
return
|
||||
}
|
||||
|
||||
srcs[i] = absSrc
|
||||
}
|
||||
|
||||
destDir := arg["destDir"].(string) // 相对于工作空间的路径
|
||||
destDir = filepath.Join(util.WorkspaceDir, destDir)
|
||||
destDir, err := util.GetAbsPathInWorkspace(destDirArg)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if filelock.IsExist(destDir) {
|
||||
destInfo, statErr := os.Stat(destDir)
|
||||
if statErr != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = statErr.Error()
|
||||
return
|
||||
}
|
||||
if !destInfo.IsDir() {
|
||||
ret.Code = -1
|
||||
ret.Msg = fmt.Sprintf("Field [destDir]: path [%s] is not a directory", destDirArg)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = os.MkdirAll(destDir, 0755); err != nil {
|
||||
logging.LogErrorf("make dir [%s] failed: %s", destDir, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, src := range srcs {
|
||||
dest := filepath.Join(destDir, filepath.Base(src))
|
||||
if err := filelock.Copy(src, dest); err != nil {
|
||||
|
|
@ -115,18 +168,18 @@ func workspaceCopyFiles(c *gin.Context) {
|
|||
}
|
||||
|
||||
var srcsArg []any
|
||||
var destDirArg string // 相对于工作空间的路径
|
||||
var destDirArg string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("srcs", &srcsArg, true, true),
|
||||
util.BindJsonArg("destDir", &destDirArg, true, false),
|
||||
util.BindJsonArg("srcs", &srcsArg, true, true), // 相对于工作空间的路径
|
||||
util.BindJsonArg("destDir", &destDirArg, true, false), // 相对于工作空间的路径
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
var relSrcs []string
|
||||
for _, s := range srcsArg {
|
||||
str, ok := s.(string) // 相对于工作空间的路径
|
||||
if !ok {
|
||||
str, elemOk := s.(string)
|
||||
if !elemOk {
|
||||
ret.Code = -1
|
||||
ret.Msg = "Field [srcs]: each element should be of type [String]"
|
||||
return
|
||||
|
|
@ -134,39 +187,12 @@ func workspaceCopyFiles(c *gin.Context) {
|
|||
str = strings.TrimSpace(str)
|
||||
if str == "" {
|
||||
ret.Code = -1
|
||||
ret.Msg = "src path must not be empty"
|
||||
ret.Msg = "Field [srcs]: path must not be empty"
|
||||
return
|
||||
}
|
||||
relSrcs = append(relSrcs, str)
|
||||
}
|
||||
|
||||
destDir, err := util.GetAbsPathInWorkspace(destDirArg)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if filelock.IsExist(destDir) {
|
||||
destInfo, err := os.Stat(destDir)
|
||||
if err != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if !destInfo.IsDir() {
|
||||
ret.Code = -1
|
||||
ret.Msg = fmt.Sprintf("destDir [%s] is not a directory", destDirArg)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = os.MkdirAll(destDir, 0755); err != nil {
|
||||
logging.LogErrorf("make dir [%s] failed: %s", destDir, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var absSrcs []string
|
||||
for _, src := range relSrcs {
|
||||
absSrc, err := util.GetAbsPathInWorkspace(src)
|
||||
|
|
@ -190,6 +216,33 @@ func workspaceCopyFiles(c *gin.Context) {
|
|||
absSrcs = append(absSrcs, absSrc)
|
||||
}
|
||||
|
||||
destDir, err := util.GetAbsPathInWorkspace(destDirArg)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if filelock.IsExist(destDir) {
|
||||
destInfo, err := os.Stat(destDir)
|
||||
if err != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if !destInfo.IsDir() {
|
||||
ret.Code = -1
|
||||
ret.Msg = "Field [destDir]: path is not a directory"
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = os.MkdirAll(destDir, 0755); err != nil {
|
||||
logging.LogErrorf("make dir [%s] failed: %s", destDir, err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, absSrc := range absSrcs {
|
||||
dest := filepath.Join(destDir, filepath.Base(absSrc))
|
||||
if err := filelock.Copy(absSrc, dest); err != nil {
|
||||
|
|
@ -212,7 +265,22 @@ func copyFile(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
src := arg["src"].(string)
|
||||
var src, dest string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("src", &src, true, true), // 资源路径,由 GetAssetAbsPath 解析
|
||||
util.BindJsonArg("dest", &dest, true, true), // 绝对路径
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
if !filepath.IsAbs(dest) {
|
||||
logging.LogErrorf("copy file dest [%s] is not an absolute path", dest)
|
||||
ret.Code = -1
|
||||
ret.Msg = "Field [dest]: path must be absolute"
|
||||
ret.Data = map[string]any{"closeTimeout": 5000}
|
||||
return
|
||||
}
|
||||
|
||||
src, err := model.GetAssetAbsPath(src)
|
||||
if err != nil {
|
||||
logging.LogErrorf("get asset [%s] abs path failed: %s", src, err)
|
||||
|
|
@ -233,17 +301,15 @@ func copyFile(c *gin.Context) {
|
|||
|
||||
if info.IsDir() {
|
||||
ret.Code = -1
|
||||
ret.Msg = "file is a directory"
|
||||
ret.Msg = "Field [src]: path is a directory"
|
||||
ret.Data = map[string]any{"closeTimeout": 5000}
|
||||
return
|
||||
}
|
||||
|
||||
dest := arg["dest"].(string)
|
||||
if util.IsSensitivePath(dest) {
|
||||
msg := fmt.Sprintf("refuse to copy sensitive file [%s]", dest)
|
||||
logging.LogErrorf(msg)
|
||||
logging.LogErrorf("refuse to copy sensitive file [%s]", dest)
|
||||
ret.Code = -2
|
||||
ret.Msg = msg
|
||||
ret.Msg = fmt.Sprintf("refuse to copy sensitive file [%s]", dest)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +333,14 @@ func getFile(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
filePath := arg["path"].(string)
|
||||
var filePath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("path", &filePath, true, true),
|
||||
) {
|
||||
c.JSON(http.StatusAccepted, ret)
|
||||
return
|
||||
}
|
||||
|
||||
fileAbsPath, err := util.GetAbsPathInWorkspace(filePath)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
|
|
@ -298,8 +371,8 @@ func getFile(c *gin.Context) {
|
|||
}
|
||||
if info.IsDir() {
|
||||
logging.LogErrorf("path [%s] is a directory path", fileAbsPath)
|
||||
ret.Code = http.StatusMethodNotAllowed
|
||||
ret.Msg = "This is a directory path"
|
||||
ret.Code = http.StatusConflict
|
||||
ret.Msg = "path is a directory"
|
||||
c.JSON(http.StatusAccepted, ret)
|
||||
return
|
||||
}
|
||||
|
|
@ -420,7 +493,13 @@ func readDir(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
dirPath := arg["path"].(string)
|
||||
var dirPath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("path", &dirPath, true, false),
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
dirAbsPath, err := util.GetAbsPathInWorkspace(dirPath)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
|
|
@ -430,19 +509,19 @@ func readDir(c *gin.Context) {
|
|||
info, err := os.Stat(dirAbsPath)
|
||||
if os.IsNotExist(err) {
|
||||
ret.Code = http.StatusNotFound
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = "path does not exist"
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
logging.LogErrorf("stat [%s] failed: %s", dirAbsPath, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
if !info.IsDir() {
|
||||
logging.LogErrorf("file [%s] is not a directory", dirAbsPath)
|
||||
ret.Code = http.StatusMethodNotAllowed
|
||||
ret.Msg = "file is not a directory"
|
||||
ret.Code = http.StatusConflict
|
||||
ret.Msg = "path is not a directory"
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +529,7 @@ func readDir(c *gin.Context) {
|
|||
if err != nil {
|
||||
logging.LogErrorf("read dir [%s] failed: %s", dirAbsPath, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -461,7 +540,7 @@ func readDir(c *gin.Context) {
|
|||
if err != nil {
|
||||
logging.LogErrorf("stat [%s] failed: %s", path, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
files = append(files, map[string]any{
|
||||
|
|
@ -485,9 +564,10 @@ func renameFile(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
var srcPath string
|
||||
var srcPath, destPath string
|
||||
if !util.ParseJsonArgs(arg, ret,
|
||||
util.BindJsonArg("path", &srcPath, true, true),
|
||||
util.BindJsonArg("newPath", &destPath, true, true),
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
@ -498,14 +578,19 @@ func renameFile(c *gin.Context) {
|
|||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
if !filelock.IsExist(srcAbsPath) {
|
||||
srcInfo, srcStatErr := os.Stat(srcAbsPath)
|
||||
if os.IsNotExist(srcStatErr) {
|
||||
ret.Code = http.StatusNotFound
|
||||
ret.Msg = "the [path] file or directory does not exist"
|
||||
ret.Msg = "Field [path]: path does not exist"
|
||||
return
|
||||
}
|
||||
if srcStatErr != nil {
|
||||
logging.LogErrorf("stat [%s] failed: %s", srcAbsPath, srcStatErr)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
destPath := arg["newPath"].(string)
|
||||
destPath = strings.TrimSpace(destPath)
|
||||
destAbsPath, err := util.GetAbsPathInWorkspace(destPath)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
|
|
@ -514,14 +599,43 @@ func renameFile(c *gin.Context) {
|
|||
}
|
||||
if filelock.IsExist(destAbsPath) {
|
||||
ret.Code = http.StatusConflict
|
||||
ret.Msg = "the [newPath] file or directory already exists"
|
||||
ret.Msg = "Field [newPath]: path already exists"
|
||||
return
|
||||
}
|
||||
|
||||
if err := filelock.Rename(srcAbsPath, destAbsPath); err != nil {
|
||||
logging.LogErrorf("rename file [%s] to [%s] failed: %s", srcAbsPath, destAbsPath, err)
|
||||
if srcInfo.IsDir() && gulu.File.IsSubPath(srcAbsPath, destAbsPath) {
|
||||
ret.Code = http.StatusConflict
|
||||
ret.Msg = "Field [newPath]: cannot rename a directory into its own subdirectory"
|
||||
return
|
||||
}
|
||||
|
||||
destParent := filepath.Dir(destAbsPath)
|
||||
if filelock.IsExist(destParent) {
|
||||
parentInfo, statErr := os.Stat(destParent)
|
||||
if statErr != nil {
|
||||
logging.LogErrorf("stat [%s] failed: %s", destParent, statErr)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
if !parentInfo.IsDir() {
|
||||
ret.Code = http.StatusConflict
|
||||
ret.Msg = fmt.Sprintf("Field [newPath]: parent path [%s] is not a directory", filepath.Dir(destPath))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = os.MkdirAll(destParent, 0755); err != nil {
|
||||
logging.LogErrorf("make dir [%s] failed: %s", destParent, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := filelock.RenameWithoutFatal(srcAbsPath, destAbsPath); err != nil {
|
||||
logging.LogErrorf("rename file failed: %s", err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -554,19 +668,20 @@ func removeFile(c *gin.Context) {
|
|||
_, err = os.Stat(fileAbsPath)
|
||||
if os.IsNotExist(err) {
|
||||
ret.Code = http.StatusNotFound
|
||||
ret.Msg = "path does not exist"
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
logging.LogErrorf("stat [%s] failed: %s", fileAbsPath, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
if err = filelock.Remove(fileAbsPath); err != nil {
|
||||
if err = filelock.RemoveWithoutFatal(fileAbsPath); err != nil {
|
||||
logging.LogErrorf("remove [%s] failed: %s", fileAbsPath, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
ret.Msg = http.StatusText(http.StatusInternalServerError) + errMsgSeeKernelLog
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -583,6 +698,11 @@ func putFile(c *gin.Context) {
|
|||
var err error
|
||||
filePath := c.PostForm("path")
|
||||
filePath = strings.TrimSpace(filePath)
|
||||
if filePath == "" {
|
||||
ret.Code = http.StatusBadRequest
|
||||
ret.Msg = "path must not be empty"
|
||||
return
|
||||
}
|
||||
fileAbsPath, err := util.GetAbsPathInWorkspace(filePath)
|
||||
if err != nil {
|
||||
ret.Code = http.StatusForbidden
|
||||
|
|
@ -594,7 +714,7 @@ func putFile(c *gin.Context) {
|
|||
if !fileExists {
|
||||
if !util.IsValidUploadFileName(filepath.Base(fileAbsPath)) { // Improve kernel API `/api/file/putFile` parameter validation https://github.com/siyuan-note/siyuan/issues/14658
|
||||
ret.Code = http.StatusBadRequest
|
||||
ret.Msg = "invalid file path, please check https://github.com/siyuan-note/siyuan/issues/14658 for more details"
|
||||
ret.Msg = "invalid file path. For details, please check https://github.com/siyuan-note/siyuan/issues/14658"
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
|
@ -607,7 +727,7 @@ func putFile(c *gin.Context) {
|
|||
}
|
||||
if info.IsDir() && !isDir {
|
||||
ret.Code = http.StatusBadRequest
|
||||
ret.Msg = "the path is a directory"
|
||||
ret.Msg = "path is a directory"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -622,11 +742,11 @@ func putFile(c *gin.Context) {
|
|||
if nil == fileHeader {
|
||||
logging.LogErrorf("form file is nil [path=%s]", fileAbsPath)
|
||||
ret.Code = http.StatusBadRequest
|
||||
ret.Msg = "form file is nil"
|
||||
ret.Msg = "Field [file] must not be empty"
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
for range 1 {
|
||||
dir := filepath.Dir(fileAbsPath)
|
||||
if err = os.MkdirAll(dir, 0755); err != nil {
|
||||
logging.LogErrorf("put file [%s] make dir [%s] failed: %s", fileAbsPath, dir, err)
|
||||
|
|
@ -652,7 +772,6 @@ func putFile(c *gin.Context) {
|
|||
logging.LogErrorf("write file [%s] failed: %s", fileAbsPath, err)
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue