feat: add form upload api (close #1693 #1709)

pull/1831/head
Noah Hsu 2022-09-22 16:53:58 +08:00
parent c7f6684eed
commit 4d6ab53336
3 changed files with 136 additions and 57 deletions

View File

@ -2,10 +2,7 @@ package handles
import (
"fmt"
"net/url"
stdpath "path"
"strconv"
"time"
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/errs"
@ -188,59 +185,6 @@ func FsRemove(c *gin.Context) {
common.SuccessResp(c)
}
func FsPut(c *gin.Context) {
path := c.GetHeader("File-Path")
path, err := url.PathUnescape(path)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
asTask := c.GetHeader("As-Task") == "true"
user := c.MustGet("user").(*model.User)
path = stdpath.Join(user.BasePath, path)
if !user.CanWrite() {
meta, err := db.GetNearestMeta(stdpath.Dir(path))
if err != nil {
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
common.ErrorResp(c, err, 500, true)
return
}
}
if !canWrite(meta, path) {
common.ErrorResp(c, errs.PermissionDenied, 403)
return
}
}
dir, name := stdpath.Split(path)
sizeStr := c.GetHeader("Content-Length")
size, err := strconv.ParseInt(sizeStr, 10, 64)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
stream := &model.FileStream{
Obj: &model.Object{
Name: name,
Size: size,
Modified: time.Now(),
},
ReadCloser: c.Request.Body,
Mimetype: c.GetHeader("Content-Type"),
WebPutAsTask: asTask,
}
if asTask {
err = fs.PutAsTask(dir, stream)
} else {
err = fs.PutDirectly(c, dir, stream)
}
if err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}
// Link return real link, just for proxy program, it may contain cookie, so just allowed for admin
func Link(c *gin.Context) {
var req MkdirOrLinkReq

134
server/handles/fsup.go Normal file
View File

@ -0,0 +1,134 @@
package handles
import (
"net/url"
stdpath "path"
"strconv"
"time"
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/fs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/server/common"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
)
func FsStream(c *gin.Context) {
path := c.GetHeader("File-Path")
path, err := url.PathUnescape(path)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
asTask := c.GetHeader("As-Task") == "true"
user := c.MustGet("user").(*model.User)
path = stdpath.Join(user.BasePath, path)
if !user.CanWrite() {
meta, err := db.GetNearestMeta(stdpath.Dir(path))
if err != nil {
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
common.ErrorResp(c, err, 500, true)
return
}
}
if !canWrite(meta, path) {
common.ErrorResp(c, errs.PermissionDenied, 403)
return
}
}
dir, name := stdpath.Split(path)
sizeStr := c.GetHeader("Content-Length")
size, err := strconv.ParseInt(sizeStr, 10, 64)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
stream := &model.FileStream{
Obj: &model.Object{
Name: name,
Size: size,
Modified: time.Now(),
},
ReadCloser: c.Request.Body,
Mimetype: c.GetHeader("Content-Type"),
WebPutAsTask: asTask,
}
if asTask {
err = fs.PutAsTask(dir, stream)
} else {
err = fs.PutDirectly(c, dir, stream)
}
if err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}
func FsForm(c *gin.Context) {
path := c.GetHeader("File-Path")
path, err := url.PathUnescape(path)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
asTask := c.GetHeader("As-Task") == "true"
user := c.MustGet("user").(*model.User)
path = stdpath.Join(user.BasePath, path)
if !user.CanWrite() {
meta, err := db.GetNearestMeta(stdpath.Dir(path))
if err != nil {
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
common.ErrorResp(c, err, 500, true)
return
}
}
if !canWrite(meta, path) {
common.ErrorResp(c, errs.PermissionDenied, 403)
return
}
}
storage, err := fs.GetStorage(path)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
if storage.Config().NoUpload {
common.ErrorStrResp(c, "Current storage doesn't support upload", 405)
return
}
file, err := c.FormFile("file")
if err != nil {
common.ErrorResp(c, err, 500)
return
}
f, err := file.Open()
if err != nil {
common.ErrorResp(c, err, 500)
return
}
dir, name := stdpath.Split(path)
stream := &model.FileStream{
Obj: &model.Object{
Name: name,
Size: file.Size,
Modified: time.Now(),
},
ReadCloser: f,
Mimetype: file.Header.Get("Content-Type"),
WebPutAsTask: false,
}
if asTask {
err = fs.PutAsTask(dir, stream)
} else {
err = fs.PutDirectly(c, dir, stream)
}
if err != nil {
common.ErrorResp(c, err, 500)
return
}
common.SuccessResp(c)
}

View File

@ -119,7 +119,8 @@ func _fs(g *gin.RouterGroup) {
g.POST("/move", handles.FsMove)
g.POST("/copy", handles.FsCopy)
g.POST("/remove", handles.FsRemove)
g.PUT("/put", handles.FsPut)
g.PUT("/put", handles.FsStream)
g.PUT("/form", handles.FsForm)
g.POST("/link", middlewares.AuthAdmin, handles.Link)
g.POST("/add_aria2", handles.AddAria2)
}