diff --git a/fakestorage/object.go b/fakestorage/object.go index b229a45233..cf48cff63a 100644 --- a/fakestorage/object.go +++ b/fakestorage/object.go @@ -32,6 +32,7 @@ type ObjectAttrs struct { BucketName string Name string Size int64 + StorageClass string ContentType string ContentEncoding string ContentDisposition string @@ -59,6 +60,7 @@ type jsonObject struct { BucketName string `json:"bucket"` Name string `json:"name"` Size int64 `json:"size,string"` + StorageClass string `json:"storageClass"` ContentType string `json:"contentType"` ContentEncoding string `json:"contentEncoding"` ContentDisposition string `json:"contentDisposition"` @@ -79,6 +81,7 @@ func (o ObjectAttrs) MarshalJSON() ([]byte, error) { temp := jsonObject{ BucketName: o.BucketName, Name: o.Name, + StorageClass: o.StorageClass, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, @@ -108,6 +111,7 @@ func (o *ObjectAttrs) UnmarshalJSON(data []byte) error { } o.BucketName = temp.BucketName o.Name = temp.Name + o.StorageClass = temp.StorageClass o.ContentType = temp.ContentType o.ContentEncoding = temp.ContentEncoding o.ContentDisposition = temp.ContentDisposition @@ -394,6 +398,7 @@ func toBackendObjects(objects []StreamingObject) []backend.StreamingObject { ObjectAttrs: backend.ObjectAttrs{ BucketName: o.BucketName, Name: o.Name, + StorageClass: o.StorageClass, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, @@ -420,6 +425,7 @@ func bufferedObjectsToBackendObjects(objects []Object) []backend.StreamingObject ObjectAttrs: backend.ObjectAttrs{ BucketName: o.BucketName, Name: o.Name, + StorageClass: o.StorageClass, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, @@ -449,6 +455,7 @@ func fromBackendObjects(objects []backend.StreamingObject) []StreamingObject { BucketName: o.BucketName, Name: o.Name, Size: o.Size, + StorageClass: o.StorageClass, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, @@ -477,6 +484,7 @@ func fromBackendObjectsAttrs(objectAttrs []backend.ObjectAttrs) []ObjectAttrs { BucketName: o.BucketName, Name: o.Name, Size: o.Size, + StorageClass: o.StorageClass, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, diff --git a/fakestorage/object_test.go b/fakestorage/object_test.go index 2fb33d02da..0deef8b863 100644 --- a/fakestorage/object_test.go +++ b/fakestorage/object_test.go @@ -47,6 +47,7 @@ type objectTestCases []struct { func getObjectTestCases() objectTestCases { const ( bucketName = "some-bucket" + storageClass = "COLDLINE" content = "some nice content" contentType = "text/plain; charset=utf-8" contentEncoding = "gzip" @@ -129,6 +130,17 @@ func getObjectTestCases() objectTestCases { }, }, }, + { + "object with no contents neither dates", + Object{ + ObjectAttrs: ObjectAttrs{ + BucketName: bucketName, + Name: "video/hi-res/best_video_1080p.mp4", + ContentType: "text/html; charset=utf-8", + StorageClass: "COLDLINE", + }, + }, + }, } return tests } @@ -148,6 +160,9 @@ func checkObjectAttrs(testObj Object, attrs *storage.ObjectAttrs, t *testing.T) if attrs.Name != testObj.Name { t.Errorf("wrong object name\nwant %q\ngot %q", testObj.Name, attrs.Name) } + if testObj.StorageClass != "" && attrs.StorageClass != testObj.StorageClass { + t.Errorf("wrong object storage class\nwant %q\ngot %q", testObj.StorageClass, attrs.StorageClass) + } if !(testObj.Created.IsZero()) && !testObj.Created.Equal(attrs.Created) { t.Errorf("wrong created date\nwant %v\ngot %v\nname %v", testObj.Created, attrs.Created, attrs.Name) } diff --git a/fakestorage/response.go b/fakestorage/response.go index f40dcd3fe9..89585ec660 100644 --- a/fakestorage/response.go +++ b/fakestorage/response.go @@ -146,6 +146,10 @@ func newProjectedObjectResponse(obj ObjectAttrs, externalURL string, projection func newObjectResponse(obj ObjectAttrs, externalURL string) objectResponse { acl := getAccessControlsListFromObject(obj) + storageClass := obj.StorageClass + if storageClass == "" { + storageClass = "STANDARD" + } return objectResponse{ Kind: "storage#object", @@ -160,7 +164,7 @@ func newObjectResponse(obj ObjectAttrs, externalURL string) objectResponse { Md5Hash: obj.Md5Hash, Etag: obj.Etag, ACL: acl, - StorageClass: "STANDARD", + StorageClass: storageClass, Metadata: obj.Metadata, TimeCreated: formatTime(obj.Created), TimeDeleted: formatTime(obj.Deleted), diff --git a/fakestorage/upload.go b/fakestorage/upload.go index e9181df46f..ff0fa88eca 100644 --- a/fakestorage/upload.go +++ b/fakestorage/upload.go @@ -57,6 +57,7 @@ type multipartMetadata struct { CacheControl string `json:"cacheControl"` CustomTime time.Time `json:"customTime,omitempty"` Name string `json:"name"` + StorageClass string `json:"storageClass"` Metadata map[string]string `json:"metadata"` } @@ -378,6 +379,7 @@ func (s *Server) multipartUpload(bucketName string, r *http.Request) jsonRespons ObjectAttrs: ObjectAttrs{ BucketName: bucketName, Name: objName, + StorageClass: metadata.StorageClass, ContentType: contentType, CacheControl: metadata.CacheControl, ContentEncoding: metadata.ContentEncoding, diff --git a/internal/backend/object.go b/internal/backend/object.go index 63bf8d6d14..5040afb9df 100644 --- a/internal/backend/object.go +++ b/internal/backend/object.go @@ -18,6 +18,7 @@ type ObjectAttrs struct { BucketName string `json:"-"` Name string `json:"-"` Size int64 `json:"-"` + StorageClass string ContentType string ContentEncoding string ContentDisposition string diff --git a/internal/grpc/server.go b/internal/grpc/server.go index 6538666bc7..48a4534e2c 100644 --- a/internal/grpc/server.go +++ b/internal/grpc/server.go @@ -110,6 +110,7 @@ func (g *Server) GetObject(ctx context.Context, req *pb.GetObjectRequest) (*pb.O return &pb.Object{ Name: obj.ObjectAttrs.Name, Bucket: obj.ObjectAttrs.BucketName, + StorageClass: obj.ObjectAttrs.StorageClass, Md5Hash: obj.ObjectAttrs.Md5Hash, Generation: obj.ObjectAttrs.Generation, ContentType: obj.ObjectAttrs.ContentType,