neko/internal/api/room/upload.go

163 lines
4.0 KiB
Go
Raw Normal View History

2021-01-07 06:57:50 +13:00
package room
import (
2021-01-07 08:03:41 +13:00
"io"
2021-02-15 02:40:17 +13:00
"net/http"
"os"
2021-01-07 08:03:41 +13:00
"path"
"strconv"
2021-01-07 06:57:50 +13:00
"demodesk/neko/internal/utils"
)
2021-09-17 06:16:51 +12:00
// TODO: Extract file uploading to custom utility.
2021-09-03 07:37:24 +12:00
// maximum upload size of 32 MB
const maxUploadSize = 32 << 20
2021-01-07 06:57:50 +13:00
2021-09-17 10:58:50 +12:00
func (h *RoomHandler) uploadDrop(w http.ResponseWriter, r *http.Request) error {
2021-09-03 07:37:24 +12:00
err := r.ParseMultipartForm(maxUploadSize)
2021-01-26 05:45:52 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
2021-01-15 07:54:22 +13:00
}
2021-01-26 05:45:52 +13:00
//nolint
2021-01-15 07:54:22 +13:00
defer r.MultipartForm.RemoveAll()
2021-01-07 08:03:41 +13:00
X, err := strconv.Atoi(r.FormValue("x"))
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpBadRequest("no X coordinate received").WithInternalErr(err)
2021-01-07 08:03:41 +13:00
}
Y, err := strconv.Atoi(r.FormValue("y"))
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpBadRequest("no Y coordinate received").WithInternalErr(err)
}
2021-01-07 08:03:41 +13:00
req_files := r.MultipartForm.File["files"]
if len(req_files) == 0 {
2021-09-17 10:58:50 +12:00
return utils.HttpBadRequest("no files received")
2021-01-07 08:03:41 +13:00
}
2021-08-30 03:12:37 +12:00
dir, err := os.MkdirTemp("", "neko-drop-*")
2021-01-07 08:03:41 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to create temporary directory")
2021-01-07 06:57:50 +13:00
}
2021-01-07 08:03:41 +13:00
files := []string{}
for _, req_file := range req_files {
path := path.Join(dir, req_file.Filename)
srcFile, err := req_file.Open()
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to open uploaded file")
2021-01-07 08:03:41 +13:00
}
defer srcFile.Close()
2021-02-15 02:40:17 +13:00
dstFile, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
2021-01-07 08:03:41 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to open destination file")
2021-01-07 08:03:41 +13:00
}
defer dstFile.Close()
_, err = io.Copy(dstFile, srcFile)
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to copy uploaded file to destination file")
2021-01-07 08:03:41 +13:00
}
files = append(files, path)
}
2021-01-15 07:54:22 +13:00
if !h.desktop.DropFiles(X, Y, files) {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalMsg("unable to drop files")
2021-01-15 07:54:22 +13:00
}
2021-09-17 10:58:50 +12:00
return utils.HttpSuccess(w)
2021-01-07 06:57:50 +13:00
}
2021-01-18 11:50:03 +13:00
2021-09-17 10:58:50 +12:00
func (h *RoomHandler) uploadDialogPost(w http.ResponseWriter, r *http.Request) error {
2021-09-03 07:37:24 +12:00
err := r.ParseMultipartForm(maxUploadSize)
2021-01-26 05:45:52 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
2021-01-18 11:50:03 +13:00
}
2021-01-26 05:45:52 +13:00
//nolint
2021-01-18 11:50:03 +13:00
defer r.MultipartForm.RemoveAll()
if !h.desktop.IsFileChooserDialogOpened() {
2021-09-17 10:58:50 +12:00
return utils.HttpUnprocessableEntity("file chooser dialog is not open")
2021-01-18 11:50:03 +13:00
}
req_files := r.MultipartForm.File["files"]
if len(req_files) == 0 {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to copy uploaded file to destination file")
2021-01-18 11:50:03 +13:00
}
2021-08-30 03:12:37 +12:00
dir, err := os.MkdirTemp("", "neko-dialog-*")
2021-01-18 11:50:03 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to create temporary directory")
2021-01-18 11:50:03 +13:00
}
for _, req_file := range req_files {
path := path.Join(dir, req_file.Filename)
srcFile, err := req_file.Open()
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to open uploaded file")
2021-01-18 11:50:03 +13:00
}
defer srcFile.Close()
2021-02-15 02:40:17 +13:00
dstFile, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
2021-01-18 11:50:03 +13:00
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to open destination file")
2021-01-18 11:50:03 +13:00
}
defer dstFile.Close()
_, err = io.Copy(dstFile, srcFile)
if err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to copy uploaded file to destination file")
2021-01-18 11:50:03 +13:00
}
}
if err := h.desktop.HandleFileChooserDialog(dir); err != nil {
2021-09-17 10:58:50 +12:00
return utils.HttpInternalServerError().
WithInternalErr(err).
WithInternalMsg("unable to handle file chooser dialog")
2021-01-18 11:50:03 +13:00
}
2021-09-17 10:58:50 +12:00
return utils.HttpSuccess(w)
2021-01-18 11:50:03 +13:00
}
2021-01-18 22:34:33 +13:00
2021-09-17 10:58:50 +12:00
func (h *RoomHandler) uploadDialogClose(w http.ResponseWriter, r *http.Request) error {
if !h.desktop.IsFileChooserDialogOpened() {
2021-09-17 10:58:50 +12:00
return utils.HttpUnprocessableEntity("file chooser dialog is not open")
2021-01-18 22:34:33 +13:00
}
h.desktop.CloseFileChooserDialog()
2021-09-17 10:58:50 +12:00
return utils.HttpSuccess(w)
2021-01-18 22:34:33 +13:00
}