commit 529d85fc3527f7b64355793d39e6a5a62a201f01
parent ce9451789556414d4d0e7e4d943bf8d64351ba55
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Mon, 30 Jan 2023 22:02:52 -0800
reconstruct file from chunks
Diffstat:
2 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go
@@ -2,12 +2,14 @@ package handlers
import (
"bytes"
+ "crypto/sha256"
dutils "dkforest/pkg/database/utils"
"dkforest/pkg/hashset"
pubsub2 "dkforest/pkg/pubsub"
v1 "dkforest/pkg/web/handlers/api/v1"
"encoding/base64"
"encoding/csv"
+ "encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
@@ -29,6 +31,7 @@ import (
"path/filepath"
"regexp"
"sort"
+ "strconv"
"strings"
"time"
"unicode/utf8"
@@ -4305,6 +4308,65 @@ func FileDropHandler(c echo.Context) error {
return c.Render(http.StatusOK, filedropTmplName, data)
}
+func FileDropTmpReconstructHandler(c echo.Context) error {
+ filedropUUID := c.Param("uuid")
+ dirEntries, _ := os.ReadDir(filepath.Join(config.Global.ProjectFiledropPath(), filedropUUID))
+ fileNames := make([]string, 0)
+ for _, dirEntry := range dirEntries {
+ if !strings.HasPrefix(dirEntry.Name(), "part_") {
+ continue
+ }
+ fileNames = append(fileNames, dirEntry.Name())
+ }
+ sort.Slice(fileNames, func(i, j int) bool {
+ a := strings.Split(fileNames[i], "_")[1]
+ b := strings.Split(fileNames[j], "_")[1]
+ numA, _ := strconv.Atoi(a)
+ numB, _ := strconv.Atoi(b)
+ return numA < numB
+ })
+
+ metadata, err := os.ReadFile(filepath.Join(config.Global.ProjectFiledropPath(), filedropUUID, "metadata"))
+ if err != nil {
+ logrus.Error(err)
+ return c.NoContent(http.StatusInternalServerError)
+ }
+ lines := strings.Split(string(metadata), "\n")
+ fileName := lines[0]
+ fileSha256 := lines[2]
+
+ f, err := os.OpenFile(filepath.Join(config.Global.ProjectFiledropPath(), filedropUUID, fileName), os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ logrus.Error(err)
+ return c.NoContent(http.StatusInternalServerError)
+ }
+ defer f.Close()
+ h := sha256.New()
+
+ for _, fileName := range fileNames {
+ by, err := os.ReadFile(filepath.Join(config.Global.ProjectFiledropPath(), filedropUUID, fileName))
+ if err != nil {
+ logrus.Error(err)
+ return c.NoContent(http.StatusInternalServerError)
+ }
+ _, _ = h.Write(by)
+ _, err = f.Write(by)
+ if err != nil {
+ logrus.Error(err)
+ return c.NoContent(http.StatusInternalServerError)
+ }
+ }
+
+ newFileSha256 := hex.EncodeToString(h.Sum(nil))
+
+ if newFileSha256 != fileSha256 {
+ logrus.Errorf("%s != %s", newFileSha256, fileSha256)
+ return c.NoContent(http.StatusInternalServerError)
+ }
+
+ return c.NoContent(http.StatusOK)
+}
+
func FileDropTmpInitHandler(c echo.Context) error {
filedropUUID := c.Param("uuid")
if err := os.Mkdir(filepath.Join(config.Global.ProjectFiledropPath(), filedropUUID), 0755); err != nil {
diff --git a/pkg/web/web.go b/pkg/web/web.go
@@ -248,6 +248,7 @@ func getMainServer(i18nBundle *i18n.Bundle, renderer *tmp.Templates) echo.Handle
adminGroup.POST("/admin/uploads", handlers.AdminUploadsHandler)
adminGroup.GET("/admin/filedrops", handlers.AdminFiledropsHandler)
adminGroup.POST("/admin/filedrops", handlers.AdminFiledropsHandler)
+ adminGroup.GET("/file-drop/:uuid/tmp-reconstruct", handlers.FileDropTmpReconstructHandler)
adminGroup.GET("/admin/file-drop/:filename", handlers.FiledropDownloadHandler)
adminGroup.GET("/admin/downloads", handlers.AdminDownloadsHandler)
adminGroup.GET("/admin/gists", handlers.AdminGistsHandler)