Add MD5 support for fsStorage, also re-purpose GetObjectMetadata for ListObjects

master
Harshavardhana 10 years ago
parent 0658889d33
commit 4751ed0e30
  1. 90
      pkg/storage/fs/fs.go

@ -19,6 +19,9 @@ package fs
import (
"bufio"
"bytes"
"crypto/md5"
"encoding/gob"
"encoding/hex"
"encoding/json"
"io"
"io/ioutil"
@ -39,8 +42,9 @@ type Storage struct {
lock *sync.Mutex
}
// SerializedMetadata - carries content type
type SerializedMetadata struct {
// Metadata - carries metadata about object
type Metadata struct {
Md5sum []byte
ContentType string
}
@ -248,6 +252,7 @@ func (storage *Storage) CopyObjectToWriter(w io.Writer, bucket string, object st
if err != nil {
return 0, mstorage.EmbedError(bucket, object, err)
}
count, err := io.Copy(w, file)
if err != nil {
return count, mstorage.EmbedError(bucket, object, err)
@ -256,7 +261,7 @@ func (storage *Storage) CopyObjectToWriter(w io.Writer, bucket string, object st
}
// GetObjectMetadata - HEAD object
func (storage *Storage) GetObjectMetadata(bucket string, object string) (mstorage.ObjectMetadata, error) {
func (storage *Storage) GetObjectMetadata(bucket, object string) (mstorage.ObjectMetadata, error) {
if mstorage.IsValidBucket(bucket) == false {
return mstorage.ObjectMetadata{}, mstorage.BucketNameInvalid{Bucket: bucket}
}
@ -283,13 +288,10 @@ func (storage *Storage) GetObjectMetadata(bucket string, object string) (mstorag
return mstorage.ObjectMetadata{}, mstorage.EmbedError(bucket, object, err)
}
metadataBuffer, err := ioutil.ReadAll(file)
if err != nil {
return mstorage.ObjectMetadata{}, mstorage.EmbedError(bucket, object, err)
}
var deserializedMetadata Metadata
decoder := gob.NewDecoder(file)
err = decoder.Decode(&deserializedMetadata)
var deserializedMetadata SerializedMetadata
err = json.Unmarshal(metadataBuffer, &deserializedMetadata)
if err != nil {
return mstorage.ObjectMetadata{}, mstorage.EmbedError(bucket, object, err)
}
@ -300,12 +302,16 @@ func (storage *Storage) GetObjectMetadata(bucket string, object string) (mstorag
}
contentType = strings.TrimSpace(contentType)
etag := bucket + "#" + path.Base(object)
if len(deserializedMetadata.Md5sum) != 0 {
etag = hex.EncodeToString(deserializedMetadata.Md5sum)
}
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: object,
Key: path.Base(object),
Created: stat.ModTime(),
Size: stat.Size(),
ETag: bucket + "#" + object,
ETag: etag,
ContentType: contentType,
}
@ -389,21 +395,15 @@ func (storage *Storage) ListObjects(bucket string, resources mstorage.BucketReso
delimitedName := delimiter(name, resources.Delimiter)
switch true {
case delimitedName == "":
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: name,
Created: file.ModTime(),
Size: file.Size(),
ETag: bucket + "#" + file.Name(),
metadata, err := storage.GetObjectMetadata(bucket, name)
if err != nil {
return []mstorage.ObjectMetadata{}, resources, mstorage.EmbedError(bucket, "", err)
}
metadataList = append(metadataList, metadata)
case delimitedName == file.Name():
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: name,
Created: file.ModTime(),
Size: file.Size(),
ETag: bucket + "#" + file.Name(),
metadata, err := storage.GetObjectMetadata(bucket, name)
if err != nil {
return []mstorage.ObjectMetadata{}, resources, mstorage.EmbedError(bucket, "", err)
}
metadataList = append(metadataList, metadata)
case delimitedName != "":
@ -414,21 +414,15 @@ func (storage *Storage) ListObjects(bucket string, resources mstorage.BucketReso
delimitedName := delimiter(trimmedName, resources.Delimiter)
switch true {
case name == resources.Prefix:
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: file.Name(),
Created: file.ModTime(),
Size: file.Size(),
ETag: bucket + "#" + file.Name(),
metadata, err := storage.GetObjectMetadata(bucket, name)
if err != nil {
return []mstorage.ObjectMetadata{}, resources, mstorage.EmbedError(bucket, "", err)
}
metadataList = append(metadataList, metadata)
case delimitedName == file.Name():
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: trimmedName,
Created: file.ModTime(),
Size: file.Size(),
ETag: bucket + "#" + file.Name(),
metadata, err := storage.GetObjectMetadata(bucket, name)
if err != nil {
return []mstorage.ObjectMetadata{}, resources, mstorage.EmbedError(bucket, "", err)
}
metadataList = append(metadataList, metadata)
case delimitedName != "":
@ -439,12 +433,9 @@ func (storage *Storage) ListObjects(bucket string, resources mstorage.BucketReso
}
}
case strings.HasPrefix(name, resources.Prefix):
metadata := mstorage.ObjectMetadata{
Bucket: bucket,
Key: name,
Created: file.ModTime(),
Size: file.Size(),
ETag: bucket + "#" + name,
metadata, err := storage.GetObjectMetadata(bucket, name)
if err != nil {
return []mstorage.ObjectMetadata{}, resources, mstorage.EmbedError(bucket, "", err)
}
metadataList = append(metadataList, metadata)
}
@ -507,14 +498,10 @@ func (storage *Storage) StoreObject(bucket, key, contentType string, data io.Rea
return mstorage.EmbedError(bucket, key, err)
}
_, err = io.Copy(file, data)
if err != nil {
return mstorage.EmbedError(bucket, key, err)
}
// serialize metadata to json
h := md5.New()
mw := io.MultiWriter(file, h)
metadataBuffer, err := json.Marshal(SerializedMetadata{ContentType: contentType})
_, err = io.Copy(mw, data)
if err != nil {
return mstorage.EmbedError(bucket, key, err)
}
@ -526,7 +513,12 @@ func (storage *Storage) StoreObject(bucket, key, contentType string, data io.Rea
return mstorage.EmbedError(bucket, key, err)
}
_, err = io.Copy(file, bytes.NewBuffer(metadataBuffer))
// serialize metadata to gob
encoder := gob.NewEncoder(file)
err = encoder.Encode(&Metadata{
ContentType: contentType,
Md5sum: h.Sum(nil),
})
if err != nil {
return mstorage.EmbedError(bucket, key, err)
}

Loading…
Cancel
Save