- commit
- 0c80ce2
- parent
- b60f3d1
- author
- Eric Bower
- date
- 2025-01-15 12:53:16 -0500 EST
fix(imgproxy): properly handle missing last-modified
15 files changed,
+50,
-39
1@@ -45,7 +45,7 @@ func main() {
2
3 var st storage.StorageServe
4 var err error
5- st, err = storage.NewStorageMinio(picoCfg.MinioURL, picoCfg.MinioUser, picoCfg.MinioPass)
6+ st, err = storage.NewStorageMinio(logger, picoCfg.MinioURL, picoCfg.MinioUser, picoCfg.MinioPass)
7 bail(err)
8
9 logger.Info("fetching all users")
+2,
-2
1@@ -81,9 +81,9 @@ func StartApiServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+2,
-2
1@@ -68,9 +68,9 @@ func StartSshServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+2,
-2
1@@ -313,9 +313,9 @@ func StartApiServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+1,
-1
1@@ -265,7 +265,7 @@ func StartSshServer() {
2 logger := shared.CreateLogger("imgs")
3 logger.Info("bootup", "registry", registryUrl, "minio", minioUrl)
4 dbh := postgres.NewDB(dbUrl, logger)
5- st, err := storage.NewStorageMinio(minioUrl, minioUser, minioPass)
6+ st, err := storage.NewStorageMinio(logger, minioUrl, minioUser, minioPass)
7 if err != nil {
8 panic(err)
9 }
+2,
-2
1@@ -373,9 +373,9 @@ func StartApiServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+2,
-2
1@@ -67,9 +67,9 @@ func StartSshServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+2,
-2
1@@ -64,9 +64,9 @@ func StartSshServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+5,
-5
1@@ -53,9 +53,9 @@ func StartApiServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
13@@ -472,8 +472,8 @@ func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, fro
14 bucket, err = web.Storage.GetBucket(shared.GetImgsBucketName(user.ID))
15 } else {
16 bucket, err = web.Storage.GetBucket(shared.GetAssetBucketName(user.ID))
17- project, err := web.Dbpool.FindProjectByName(user.ID, props.ProjectName)
18- if err != nil {
19+ project, perr := web.Dbpool.FindProjectByName(user.ID, props.ProjectName)
20+ if perr != nil {
21 logger.Info("project not found")
22 http.Error(w, "project not found", http.StatusNotFound)
23 return
24@@ -499,7 +499,7 @@ func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, fro
25 }
26
27 if err != nil {
28- logger.Info("bucket not found")
29+ logger.Error("bucket not found", "err", err)
30 http.Error(w, "bucket not found", http.StatusNotFound)
31 return
32 }
+8,
-4
1@@ -131,15 +131,19 @@ func (h *ApiAssetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
2 return
3 }
4
5- attempts = append(attempts, fp.Filepath)
6- logger = logger.With("filename", fp.Filepath)
7 var c io.ReadCloser
8+ fpath := fp.Filepath
9+ attempts = append(attempts, fpath)
10+ logger = logger.With("object", fpath)
11+ logger.Info("serving object")
12 c, info, err = h.Storage.ServeObject(
13 h.Bucket,
14- fp.Filepath,
15+ fpath,
16 h.ImgProcessOpts,
17 )
18- if err == nil {
19+ if err != nil {
20+ logger.Error("serving object", "err", err)
21+ } else {
22 contents = c
23 assetFilepath = fp.Filepath
24 status = fp.Status
+2,
-2
1@@ -898,9 +898,9 @@ func StartApiServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
+2,
-2
1@@ -69,9 +69,9 @@ func StartSshServer() {
2 var st storage.StorageServe
3 var err error
4 if cfg.MinioURL == "" {
5- st, err = storage.NewStorageFS(cfg.StorageDir)
6+ st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
7 } else {
8- st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
9+ st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
10 }
11
12 if err != nil {
1@@ -3,6 +3,7 @@ package storage
2 import (
3 "fmt"
4 "io"
5+ "log/slog"
6 "os"
7 "path/filepath"
8 "strings"
9@@ -12,14 +13,15 @@ import (
10
11 type StorageFS struct {
12 *sst.StorageFS
13+ Logger *slog.Logger
14 }
15
16-func NewStorageFS(dir string) (*StorageFS, error) {
17+func NewStorageFS(logger *slog.Logger, dir string) (*StorageFS, error) {
18 st, err := sst.NewStorageFS(dir)
19 if err != nil {
20 return nil, err
21 }
22- return &StorageFS{st}, nil
23+ return &StorageFS{st, logger}, nil
24 }
25
26 func (s *StorageFS) ServeObject(bucket sst.Bucket, fpath string, opts *ImgProcessOpts) (io.ReadCloser, *sst.ObjectInfo, error) {
27@@ -37,7 +39,7 @@ func (s *StorageFS) ServeObject(bucket sst.Bucket, fpath string, opts *ImgProces
28 } else {
29 filePath := filepath.Join(bucket.Name, fpath)
30 dataURL := fmt.Sprintf("s3://%s", filePath)
31- rc, info, err = HandleProxy(dataURL, opts)
32+ rc, info, err = HandleProxy(s.Logger, dataURL, opts)
33 }
34 if err != nil {
35 return nil, nil, err
1@@ -3,6 +3,7 @@ package storage
2 import (
3 "fmt"
4 "io"
5+ "log/slog"
6 "os"
7 "path/filepath"
8 "strings"
9@@ -12,14 +13,15 @@ import (
10
11 type StorageMinio struct {
12 *sst.StorageMinio
13+ Logger *slog.Logger
14 }
15
16-func NewStorageMinio(address, user, pass string) (*StorageMinio, error) {
17+func NewStorageMinio(logger *slog.Logger, address, user, pass string) (*StorageMinio, error) {
18 st, err := sst.NewStorageMinio(address, user, pass)
19 if err != nil {
20 return nil, err
21 }
22- return &StorageMinio{st}, nil
23+ return &StorageMinio{st, logger}, nil
24 }
25
26 func (s *StorageMinio) ServeObject(bucket sst.Bucket, fpath string, opts *ImgProcessOpts) (io.ReadCloser, *sst.ObjectInfo, error) {
27@@ -37,7 +39,7 @@ func (s *StorageMinio) ServeObject(bucket sst.Bucket, fpath string, opts *ImgPro
28 } else {
29 filePath := filepath.Join(bucket.Name, fpath)
30 dataURL := fmt.Sprintf("s3://%s", filePath)
31- rc, info, err = HandleProxy(dataURL, opts)
32+ rc, info, err = HandleProxy(s.Logger, dataURL, opts)
33 }
34 if err != nil {
35 return nil, nil, err
1@@ -7,6 +7,7 @@ import (
2 "encoding/hex"
3 "fmt"
4 "io"
5+ "log/slog"
6 "net/http"
7 "os"
8 "path/filepath"
9@@ -202,7 +203,7 @@ func (img *ImgProcessOpts) String() string {
10 return processOpts
11 }
12
13-func HandleProxy(dataURL string, opts *ImgProcessOpts) (io.ReadCloser, *storage.ObjectInfo, error) {
14+func HandleProxy(logger *slog.Logger, dataURL string, opts *ImgProcessOpts) (io.ReadCloser, *storage.ObjectInfo, error) {
15 imgProxyURL := os.Getenv("IMGPROXY_URL")
16 imgProxySalt := os.Getenv("IMGPROXY_SALT")
17 imgProxyKey := os.Getenv("IMGPROXY_KEY")
18@@ -242,13 +243,15 @@ func HandleProxy(dataURL string, opts *ImgProcessOpts) (io.ReadCloser, *storage.
19 lastModified := res.Header.Get("Last-Modified")
20 parsedTime, err := time.Parse(time.RFC1123, lastModified)
21 if err != nil {
22- return nil, nil, fmt.Errorf("decoding last-modified: %w", err)
23+ logger.Error("decoding last-modified", "err", err)
24 }
25 info := &storage.ObjectInfo{
26- Size: res.ContentLength,
27- LastModified: parsedTime,
28- ETag: trimEtag(res.Header.Get("etag")),
29- Metadata: res.Header,
30+ Size: res.ContentLength,
31+ ETag: trimEtag(res.Header.Get("etag")),
32+ Metadata: res.Header,
33+ }
34+ if !parsedTime.IsZero() {
35+ info.LastModified = parsedTime
36 }
37
38 return res.Body, info, nil