yaxc/internal/server/request_post.go
2021-05-13 19:01:22 +02:00

94 lines
2.7 KiB
Go

package server
import (
"errors"
"fmt"
"github.com/darmiel/yaxc/internal/common"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
"github.com/muesli/termenv"
"net/http"
"strings"
"time"
)
var errEncryptionNotEnabled = errors.New("encryption not enabled")
func (s *yAxCServer) handlePostAnywhere(ctx *fiber.Ctx) (err error) {
path := utils.CopyString(strings.TrimSpace(ctx.Params("anywhere")))
return s.setAnywhereWithHash(ctx, path, "")
}
func (s *yAxCServer) handlePostAnywhereWithHash(ctx *fiber.Ctx) (err error) {
path := utils.CopyString(strings.TrimSpace(ctx.Params("anywhere")))
hash := utils.CopyString(strings.TrimSpace(ctx.Params("hash")))
// validate hash
if !common.ValidateHex(hash) {
return ctx.Status(400).SendString("ERROR: Invalid hash")
}
return s.setAnywhereWithHash(ctx, path, hash)
}
func (s *yAxCServer) setAnywhereWithHash(ctx *fiber.Ctx, path, hash string) (err error) {
// validate path
if !common.ValidateAnywherePath(path) {
return fiber.NewError(http.StatusNotAcceptable, "invalid anywhere-path")
}
// Read content
bytes := ctx.Body()
if s.MaxBodyLength > 0 && len(bytes) > s.MaxBodyLength {
return fiber.NewError(http.StatusRequestEntityTooLarge, "exceeded max body length")
}
content := string(bytes)
// TTL
ttl := s.DefaultTTL
if q := ctx.Query("ttl"); q != "" {
if ttl, err = time.ParseDuration(q); err != nil {
return fiber.NewError(http.StatusUnprocessableEntity, "invalid ttl. (examples: 10s, 5m, 1h)")
}
}
// Encryption
if q := ctx.Query("secret"); q != "" {
if !s.EnableEncryption {
return fiber.NewError(http.StatusLocked, "encryption is currently not enabled on this server")
}
// fail on error
encrypt, err := common.Encrypt(content, q)
if err != nil {
return fiber.NewError(http.StatusInternalServerError, "error encrypting content: "+err.Error())
}
content = string(encrypt)
}
// Check if ttl is valid
if (s.MinTTL != 0 && s.MinTTL > ttl) || (s.MaxTTL != 0 && s.MaxTTL < ttl) {
return fiber.NewError(http.StatusRequestedRangeNotSatisfiable, "ttl out of range")
}
// generate hash
if hash == "" {
hash = common.MD5Hash(content)
}
// Set contents
errVal := s.Backend.Set(path, content, ttl)
errHsh := s.Backend.SetHash(path, hash, ttl)
if errVal != nil || errHsh != nil {
log.Warning("ERROR saving Value / MD5Hash:", errVal, errHsh)
return ctx.Status(500).SendString(
fmt.Sprintf("ERROR (Val): %v\nERROR (Hsh): %v", errVal, errHsh))
}
fmt.Println(common.StyleServe(),
termenv.String(ctx.IP()).Foreground(common.Profile().Color("#DBAB79")),
"updated",
termenv.String(path).Foreground(common.Profile().Color("#D290E4")),
"with hash",
termenv.String(hash).Foreground(common.Profile().Color("#71BEF2")))
return ctx.Status(200).SendString(content)
}