qudoco-be/app/module/cms_media/service/cms_media.service.go

76 lines
2.0 KiB
Go
Raw Normal View History

package service
import (
"context"
"io"
"mime"
"path/filepath"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/minio/minio-go/v7"
"github.com/rs/zerolog"
minioStorage "web-qudo-be/config/config"
)
type CmsMediaService struct {
Minio *minioStorage.MinioStorage
Log zerolog.Logger
}
func NewCmsMediaService(minio *minioStorage.MinioStorage, log zerolog.Logger) *CmsMediaService {
return &CmsMediaService{Minio: minio, Log: log}
}
// Viewer streams a CMS object from MinIO (same idea as article-files viewer).
func (s *CmsMediaService) Viewer(c *fiber.Ctx) error {
objectKey := strings.TrimSpace(c.Params("*"))
objectKey = strings.TrimPrefix(objectKey, "/")
if objectKey == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"messages": []string{"object key required"},
})
}
if !strings.HasPrefix(objectKey, "cms/") || strings.Contains(objectKey, "..") {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"messages": []string{"invalid object key"},
})
}
ctx := context.Background()
bucket := s.Minio.Cfg.ObjectStorage.MinioStorage.BucketName
client, err := s.Minio.ConnectMinio()
if err != nil {
s.Log.Error().Err(err).Msg("cms media viewer: minio connect")
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"messages": []string{"storage unavailable"},
})
}
obj, err := client.GetObject(ctx, bucket, objectKey, minio.GetObjectOptions{})
if err != nil {
s.Log.Error().Err(err).Str("key", objectKey).Msg("cms media viewer: get object")
return c.Status(fiber.StatusNotFound).SendString("not found")
}
defer obj.Close()
ext := strings.ToLower(filepath.Ext(objectKey))
contentType := mime.TypeByExtension(ext)
if contentType == "" {
contentType = "application/octet-stream"
}
c.Set("Content-Type", contentType)
c.Set("Cache-Control", "public, max-age=86400")
if _, err := io.Copy(c.Response().BodyWriter(), obj); err != nil {
s.Log.Error().Err(err).Msg("cms media viewer: stream")
return err
}
return nil
}