From b6bb1f400714e45fcae1144f514f3ca6ce4c0e69 Mon Sep 17 00:00:00 2001 From: Rama Priyanto Date: Thu, 8 Jan 2026 14:49:23 +0700 Subject: [PATCH] fix:ai chat file viewer --- .../service/ai_chat_files.service.go | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/app/module/ai_chat_files/service/ai_chat_files.service.go b/app/module/ai_chat_files/service/ai_chat_files.service.go index 9cdfa7c..a0513e9 100644 --- a/app/module/ai_chat_files/service/ai_chat_files.service.go +++ b/app/module/ai_chat_files/service/ai_chat_files.service.go @@ -4,9 +4,7 @@ import ( "context" "fmt" "io" - "log" "math/rand" - "mime" "mime/multipart" "narasi-ahli-be/app/module/ai_chat_files/mapper" "narasi-ahli-be/app/module/ai_chat_files/repository" @@ -296,8 +294,9 @@ func (_i *aiChatFilesService) Delete(id uint) error { return _i.Repo.Update(id, result) } -func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) (err error) { +func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) error { filename := c.Params("filename") + result, err := _i.Repo.FindByFilename(filename) if err != nil { return err @@ -307,41 +306,48 @@ func (_i *aiChatFilesService) Viewer(c *fiber.Ctx) (err error) { bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName objectName := *result.FilePath - _i.Log.Info().Str("timestamp", time.Now(). - Format(time.RFC3339)).Str("Service:Resource", "AiChat:Uploads"). - Interface("data", objectName).Msg("") - - // Create minio connection. minioClient, err := _i.MinioStorage.ConnectMinio() if err != nil { - // Return status 500 and minio connection error. return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": true, "msg": err.Error(), }) } - fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{}) + object, err := minioClient.GetObject( + ctx, + bucketName, + objectName, + minio.GetObjectOptions{}, + ) if err != nil { - log.Fatalln(err) + return err } - defer fileContent.Close() + defer object.Close() - // Tentukan Content-Type berdasarkan ekstensi file - contentType := mime.TypeByExtension("." + getFileExtension(objectName)) - if contentType == "" { - contentType = "application/octet-stream" // fallback jika tidak ada tipe MIME yang cocok - } - - c.Set("Content-Type", contentType) - - if _, err := io.Copy(c.Response().BodyWriter(), fileContent); err != nil { + // 🔥 Ambil metadata object (INI PENTING) + stat, err := object.Stat() + if err != nil { return err } - return + // 🔥 Content-Type yang BENAR + if stat.ContentType != "" { + c.Set("Content-Type", stat.ContentType) + } else { + // fallback kalau metadata kosong + c.Type(filepath.Ext(objectName)) + } + + // 🔥 WAJIB untuk preview media + c.Set("Content-Disposition", "inline") + c.Set("Accept-Ranges", "bytes") + + // 🔥 BIARKAN FIBER HANDLE STREAMING + return c.SendStream(object) } + func getFileExtension(filename string) string { // split file name parts := strings.Split(filename, ".")