package http import ( "io" "io/fs" "net/http" "os" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) func serveFile(w http.ResponseWriter, r *http.Request, fs fs.FS, path string) { ctx := logger.With(r.Context(), logger.F("path", path)) file, err := fs.Open(path) if err != nil { if errors.Is(err, os.ErrNotExist) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } logger.Error(ctx, "error while opening fs file", logger.E(errors.WithStack(err))) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } defer func() { if err := file.Close(); err != nil { logger.Error(ctx, "error while closing fs file", logger.E(errors.WithStack(err))) } }() info, err := file.Stat() if err != nil { logger.Error(ctx, "error while retrieving fs file stat", logger.E(errors.WithStack(err))) return } reader, ok := file.(io.ReadSeeker) if !ok { logger.Error(ctx, "could not convert file to readseeker", logger.E(errors.WithStack(err))) return } http.ServeContent(w, r, path, info.ModTime(), reader) }