dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 529d85fc3527f7b64355793d39e6a5a62a201f01
parent ce9451789556414d4d0e7e4d943bf8d64351ba55
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Mon, 30 Jan 2023 22:02:52 -0800

reconstruct file from chunks

Diffstat:
Mpkg/web/handlers/handlers.go | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/web/web.go | 1+
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)