199 lines
5.4 KiB
Go
199 lines
5.4 KiB
Go
package webdav
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
|
"git.ma-al.com/goc_daniel/b2b/app/service/storageService"
|
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
type StorageHandler struct {
|
|
storageService *storageService.StorageService
|
|
config *config.Config
|
|
}
|
|
|
|
func NewStorageHandler() *StorageHandler {
|
|
return &StorageHandler{
|
|
storageService: storageService.New(),
|
|
config: config.Get(),
|
|
}
|
|
}
|
|
|
|
func StorageHandlerRoutes(r fiber.Router) fiber.Router {
|
|
handler := NewStorageHandler()
|
|
|
|
// for webdav use only
|
|
r.Get("/*", handler.Get)
|
|
r.Head("/*", handler.Get)
|
|
r.Put("/*", handler.Put)
|
|
r.Delete("/*", handler.Delete)
|
|
r.Add([]string{"MKCOL"}, "/*", handler.Mkcol)
|
|
r.Add([]string{"PROPFIND"}, "/*", handler.Propfind)
|
|
r.Add([]string{"PROPPATCH"}, "/*", handler.Proppatch)
|
|
r.Add([]string{"MOVE"}, "/*", handler.Move)
|
|
r.Add([]string{"COPY"}, "/*", handler.Copy)
|
|
|
|
return r
|
|
}
|
|
|
|
func (h *StorageHandler) Get(c fiber.Ctx) error {
|
|
// fmt.Println("GET")
|
|
absPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
info, err := h.storageService.EntryInfo(absPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
if info.IsDir() {
|
|
xml, err := h.storageService.Propfind(h.config.Storage.RootFolder, absPath, "1")
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
c.Set("Content-Type", `application/xml; charset="utf-8"`)
|
|
return c.Status(http.StatusMultiStatus).SendString(xml)
|
|
|
|
} else {
|
|
f, filename, filesize, err := h.storageService.DownloadFilePrep(absPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
c.Attachment(filename)
|
|
c.Set("Content-Length", strconv.FormatInt(filesize, 10))
|
|
c.Set("Content-Type", "application/octet-stream")
|
|
return c.SendStream(f, int(filesize))
|
|
}
|
|
}
|
|
|
|
func (h *StorageHandler) Put(c fiber.Ctx) error {
|
|
// fmt.Println("PUT")
|
|
absPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
var src io.Reader
|
|
if bodyStream := c.Request().BodyStream(); bodyStream != nil {
|
|
defer c.Request().CloseBodyStream()
|
|
src = bodyStream
|
|
} else {
|
|
src = bytes.NewReader(c.Body())
|
|
}
|
|
|
|
err = h.storageService.Put(absPath, src)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
return c.SendStatus(http.StatusCreated)
|
|
}
|
|
|
|
func (h *StorageHandler) Delete(c fiber.Ctx) error {
|
|
// fmt.Println("DELETE")
|
|
absPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
if absPath == h.config.Storage.RootFolder {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(responseErrors.ErrAccessDenied))
|
|
}
|
|
|
|
err = h.storageService.Delete(absPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
return c.SendStatus(http.StatusNoContent)
|
|
}
|
|
|
|
func (h *StorageHandler) Mkcol(c fiber.Ctx) error {
|
|
// fmt.Println("Mkcol")
|
|
absPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
err = h.storageService.Mkcol(absPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
return c.SendStatus(http.StatusCreated)
|
|
}
|
|
|
|
func (h *StorageHandler) Propfind(c fiber.Ctx) error {
|
|
// fmt.Println("PROPFIND")
|
|
absPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
xml, err := h.storageService.Propfind(h.config.Storage.RootFolder, absPath, "1")
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
c.Set("Content-Type", `application/xml; charset="utf-8"`)
|
|
return c.Status(http.StatusMultiStatus).SendString(xml)
|
|
}
|
|
|
|
func (h *StorageHandler) Proppatch(c fiber.Ctx) error {
|
|
return c.SendStatus(http.StatusNotImplemented) // 501
|
|
}
|
|
|
|
func (h *StorageHandler) Move(c fiber.Ctx) error {
|
|
// fmt.Println("MOVE")
|
|
srcAbsPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
dest := c.Get("Destination")
|
|
if dest == "" {
|
|
return c.SendStatus(http.StatusBadRequest)
|
|
}
|
|
destAbsPath, err := h.storageService.ObtainDestPath(h.config.Storage.RootFolder, dest)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
err = h.storageService.Move(srcAbsPath, destAbsPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
return c.SendStatus(http.StatusCreated)
|
|
}
|
|
|
|
func (h *StorageHandler) Copy(c fiber.Ctx) error {
|
|
// fmt.Println("COPY")
|
|
srcAbsPath, err := h.storageService.AbsPath(h.config.Storage.RootFolder, c.Params("*"))
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
dest := c.Get("Destination")
|
|
if dest == "" {
|
|
return c.SendStatus(http.StatusBadRequest)
|
|
}
|
|
destAbsPath, err := h.storageService.ObtainDestPath(h.config.Storage.RootFolder, dest)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
|
|
err = h.storageService.Copy(srcAbsPath, destAbsPath)
|
|
if err != nil {
|
|
return c.SendStatus(responseErrors.GetErrorStatus(err))
|
|
}
|
|
return c.SendStatus(http.StatusCreated)
|
|
}
|