76 lines
2.0 KiB
Go
76 lines
2.0 KiB
Go
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
|
|
}
|