diff --git a/internal/objectstorage/objectstorage.go b/internal/objectstorage/objectstorage.go index a9dbce4..8e34370 100644 --- a/internal/objectstorage/objectstorage.go +++ b/internal/objectstorage/objectstorage.go @@ -17,6 +17,7 @@ package objectstorage import ( "errors" "io" + "time" ) // TODO(sgotti) @@ -36,6 +37,8 @@ type Storage interface { type ObjectInfo struct { Path string + LastModified time.Time + Err error } diff --git a/internal/objectstorage/posix.go b/internal/objectstorage/posix.go index 243c809..36a1baf 100644 --- a/internal/objectstorage/posix.go +++ b/internal/objectstorage/posix.go @@ -240,14 +240,15 @@ func (s *PosixStorage) Stat(p string) (*ObjectInfo, error) { return nil, err } - if _, err := os.Stat(fspath); err != nil { + fi, err := os.Stat(fspath) + if err != nil { if os.IsNotExist(err) { return nil, ErrNotExist } return nil, err } - return &ObjectInfo{Path: p}, nil + return &ObjectInfo{Path: p, LastModified: fi.ModTime()}, nil } func (s *PosixStorage) ReadObject(p string) (io.ReadCloser, error) { @@ -409,7 +410,7 @@ func (s *PosixStorage) List(prefix, startWith, delimiter string, doneCh <-chan s if p > prevp { select { // Send object content. - case objectCh <- ObjectInfo{Path: p}: + case objectCh <- ObjectInfo{Path: p, LastModified: info.ModTime()}: // If receives done from the caller, return here. case <-doneCh: return io.EOF diff --git a/internal/objectstorage/s3.go b/internal/objectstorage/s3.go index 6ec4455..5ffdf5c 100644 --- a/internal/objectstorage/s3.go +++ b/internal/objectstorage/s3.go @@ -61,7 +61,8 @@ func NewS3Storage(bucket, location, endpoint, accessKeyID, secretAccessKey strin } func (s *S3Storage) Stat(p string) (*ObjectInfo, error) { - if _, err := s.minioClient.StatObject(s.bucket, p, minio.StatObjectOptions{}); err != nil { + oi, err := s.minioClient.StatObject(s.bucket, p, minio.StatObjectOptions{}) + if err != nil { merr := minio.ToErrorResponse(err) if merr.StatusCode == http.StatusNotFound { return nil, ErrNotExist @@ -69,7 +70,7 @@ func (s *S3Storage) Stat(p string) (*ObjectInfo, error) { return nil, merr } - return &ObjectInfo{Path: p}, nil + return &ObjectInfo{Path: p, LastModified: oi.LastModified}, nil } func (s *S3Storage) ReadObject(filepath string) (io.ReadCloser, error) { @@ -144,7 +145,7 @@ func (s *S3Storage) List(prefix, startWith, delimiter string, doneCh <-chan stru for _, object := range result.Contents { select { // Send object content. - case objectCh <- ObjectInfo{Path: object.Key}: + case objectCh <- ObjectInfo{Path: object.Key, LastModified: object.LastModified}: // If receives done from the caller, return here. case <-doneCh: return