/* * Copyright 2026 Oleg Borodin * * This work is published and licensed under a Creative Commons * Attribution-NonCommercial-NoDerivatives 4.0 International License. * * Distribution of this work is permitted, but commercial use and * modifications are strictly prohibited. */ package handler import ( "fmt" "io" "mstore/app/descr" "mstore/app/operator" "mstore/app/router" ) const zeroContentLength = "0" func (hand *Handler) FileInfo(rctx *router.Context) { filepath, _ := rctx.GetSubpath("filepath") params := &operator.FileInfoParams{ Filepath: filepath, } // Rigth checking operatorID, _ := rctx.GetString(userTag) opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, descr.RightReadFiles, "") if err != nil { err := fmt.Errorf("Operation error: %v", err) hand.SendError(rctx, err) return } if !opEnable { err := fmt.Errorf("Operation not enabled for this account") hand.SendError(rctx, err) return } // Execution of the operation ctx := rctx.GetContext() code, res, err := hand.oper.FileInfo(ctx, params) if err != nil { hand.logg.Errorf("FileInfo error: %v", err) rctx.SetStatus(code) return } rctx.SetHeader("Content-Collection", res.ContentCollection) rctx.SetHeader("Content-Name", res.ContentName) rctx.SetHeader("Content-Type", res.ContentType) rctx.SetHeader("Content-Size", res.ContentSize) rctx.SetHeader("Content-Digest", res.ContentDigest) rctx.SetHeader("Content-Length", zeroContentLength) rctx.SetStatus(code) } func (hand *Handler) PutFile(rctx *router.Context) { contentSize := rctx.GetHeader("Content-Size") contentType := rctx.GetHeader("Content-Type") filepath, _ := rctx.GetSubpath("filepath") params := &operator.PutFileParams{ Filepath: filepath, ContentType: contentType, ContentSize: contentSize, Source: rctx.Request.Body, } // Rigth checking operatorID, _ := rctx.GetString(userTag) opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, descr.RightWriteFiles, "") if err != nil { err := fmt.Errorf("Operation error: %v", err) hand.SendError(rctx, err) return } if !opEnable { err := fmt.Errorf("Operation not enabled for this account") hand.SendError(rctx, err) return } // Execution of the operation ctx := rctx.GetContext() code, _, err := hand.oper.PutFile(ctx, params) if err != nil { hand.logg.Errorf("PutFile error: %v", err) rctx.SetStatus(code) return } rctx.SetStatus(code) } func (hand *Handler) GetFile(rctx *router.Context) { filepath, _ := rctx.GetSubpath("filepath") params := &operator.GetFileParams{ Filepath: filepath, } // Rigth checking operatorID, _ := rctx.GetString(userTag) opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, descr.RightReadFiles, "") if err != nil { err := fmt.Errorf("Operation error: %v", err) hand.SendError(rctx, err) return } if !opEnable { err := fmt.Errorf("Operation not enabled for this account") hand.SendError(rctx, err) return } // Execution of the operation ctx := rctx.GetContext() code, res, err := hand.oper.GetFile(ctx, params) if err != nil { hand.logg.Errorf("PutFile error: %v", err) rctx.SetStatus(code) return } rctx.SetHeader("Content-Type", res.ContentType) rctx.SetHeader("Content-Size", res.ContentSize) rctx.SetHeader("Content-Digest", res.ContentDigest) rctx.SetHeader("Content-Length", res.ContentSize) rctx.SetStatus(code) if res.Source != nil { defer res.Source.Close() _, err = io.Copy(rctx.Writer, res.Source) if err != nil { hand.logg.Errorf("GetFile error: %v", err) return } } } func (hand *Handler) DeleteFile(rctx *router.Context) { filepath, _ := rctx.GetSubpath("filepath") params := &operator.DeleteFileParams{ Filepath: filepath, } // Rigth checking operatorID, _ := rctx.GetString(userTag) opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, descr.RightWriteFiles, "") if err != nil { err := fmt.Errorf("Operation error: %v", err) hand.SendError(rctx, err) return } if !opEnable { err := fmt.Errorf("Operation not enabled for this account") hand.SendError(rctx, err) return } // Execution of the operation ctx := rctx.GetContext() code, _, err := hand.oper.DeleteFile(ctx, params) if err != nil { hand.logg.Errorf("GetFile error: %v", err) } rctx.SetStatus(code) } func (hand *Handler) ListFiles(rctx *router.Context) { filepath, _ := rctx.GetSubpath("filepath") if filepath == "" { filepath = "/" } params := &operator.ListFilesParams{ Filepath: filepath, } // Rigth checking operatorID, _ := rctx.GetString(userTag) opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, descr.RightReadFiles, "") if err != nil { err := fmt.Errorf("Operation error: %v", err) hand.SendError(rctx, err) return } if !opEnable { err := fmt.Errorf("Operation not enabled for this account") hand.SendError(rctx, err) return } // Execution of the operation ctx := rctx.GetContext() code, res, err := hand.oper.ListFiles(ctx, params) if err != nil { hand.logg.Errorf("ListFiles error: %v", err) rctx.SetStatus(code) return } rctx.SendJSON(code, res.Files) }