diff --git a/internal/http-server/handlers/recipeImage/recipeImage.go b/internal/http-server/handlers/recipeImage/recipeImage.go new file mode 100644 index 0000000..5974a85 --- /dev/null +++ b/internal/http-server/handlers/recipeImage/recipeImage.go @@ -0,0 +1,54 @@ +package recipeimage + +import ( + "context" + "io" + "log/slog" + "net/http" + + resp "recipes/internal/lib/api/response" + "recipes/internal/lib/logger/sl" + + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/render" +) + +type ImageProvider interface { + RecipeImage(ctx context.Context, filename string) (io.ReadCloser, error) +} + +func New(log *slog.Logger, imageProvider ImageProvider) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + const op = "http-server.handlers.recipeImage.New" + + log = log.With( + slog.String("op", op), + slog.String("request_id", middleware.GetReqID(r.Context())), + ) + // get filename + filename := r.URL.Query().Get("filename") + if filename == "" { + log.Error("filename not in query") + render.JSON(w, r, resp.Error("invalid request")) + return + } + // get object + obj, err := imageProvider.RecipeImage(r.Context(), filename) + if err != nil { + log.Error("cannot get file", sl.Err(err)) + render.JSON(w, r, resp.Error("cannot get file")) + return + } + defer obj.Close() + // return object + err = renderObject(w, r, obj) + if err != nil { + log.Error("Fail on rendering object", sl.Err(err)) + } + } +} + +func renderObject(w http.ResponseWriter, r *http.Request, obj io.Reader) error { + _, err := io.Copy(w, obj) + return err +} diff --git a/internal/media_storage/minio/minio.go b/internal/media_storage/minio/minio.go index c814deb..73b9379 100644 --- a/internal/media_storage/minio/minio.go +++ b/internal/media_storage/minio/minio.go @@ -99,7 +99,7 @@ func (o *ObjStorage) SaveRecipeImage(ctx context.Context, imageFile io.Reader, f } // RecipeImage gets image from recipe's images bucket by filename. -func (o *ObjStorage) RecipeImage(ctx context.Context, filename string) (*minio.Object, error) { +func (o *ObjStorage) RecipeImage(ctx context.Context, filename string) (io.ReadCloser, error) { const op = "media_storage.minio.RecipeImage" err := o.checkBucketExists(ctx, recipeImgBucket) if err != nil {