Add bucket to be part of object struct, reply back with BucketNotFound

for erroneous Object Put requests.

Other minor cleanups, to follow

  - https://github.com/golang/go/wiki/CodeReviewComments
master
Harshavardhana 10 years ago
parent 72179fbc84
commit 357a81e879
  1. 27
      pkg/storage/inmemory/inmemory.go
  2. 1
      pkg/storage/storage.go
  3. 14
      pkg/storage/storage_errors.go
  4. 77
      pkg/webapi/minioapi/minioapi.go

@ -5,7 +5,6 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"io" "io"
"log"
"strings" "strings"
"time" "time"
@ -43,15 +42,21 @@ func (storage *storage) CopyObjectToWriter(w io.Writer, bucket string, object st
func (storage *storage) StoreObject(bucket string, key string, data io.Reader) error { func (storage *storage) StoreObject(bucket string, key string, data io.Reader) error {
objectKey := bucket + ":" + key objectKey := bucket + ":" + key
if _, ok := storage.bucketdata[bucket]; ok == false {
return mstorage.BucketNotFound{Bucket: bucket}
}
if _, ok := storage.objectdata[objectKey]; ok == true { if _, ok := storage.objectdata[objectKey]; ok == true {
return mstorage.ObjectExists{Bucket: bucket, Key: key} return mstorage.ObjectExists{Bucket: bucket, Key: key}
} }
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
newObject := storedObject{} var newObject = storedObject{}
if _, ok := io.Copy(&bytesBuffer, data); ok == nil { if _, ok := io.Copy(&bytesBuffer, data); ok == nil {
size := bytesBuffer.Len() size := bytesBuffer.Len()
etag := fmt.Sprintf("%x", sha256.Sum256(bytesBuffer.Bytes())) etag := fmt.Sprintf("%x", sha256.Sum256(bytesBuffer.Bytes()))
newObject.metadata = mstorage.ObjectMetadata{ newObject.metadata = mstorage.ObjectMetadata{
Bucket: bucket,
Key: key, Key: key,
Created: time.Now(), Created: time.Now(),
Size: size, Size: size,
@ -71,13 +76,13 @@ func (storage *storage) StoreBucket(bucketName string) error {
if _, ok := storage.bucketdata[bucketName]; ok == true { if _, ok := storage.bucketdata[bucketName]; ok == true {
return mstorage.BucketExists{Bucket: bucketName} return mstorage.BucketExists{Bucket: bucketName}
} }
newBucket := storedBucket{}
newBucket.metadata = mstorage.BucketMetadata{ var newBucket = storedBucket{}
Name: bucketName, newBucket.metadata = mstorage.BucketMetadata{}
Created: time.Now(), newBucket.metadata.Name = bucketName
} newBucket.metadata.Created = time.Now()
log.Println(bucketName)
storage.bucketdata[bucketName] = newBucket storage.bucketdata[bucketName] = newBucket
return nil return nil
} }
@ -85,8 +90,10 @@ func (storage *storage) ListObjects(bucket, prefix string, count int) []mstorage
// TODO prefix and count handling // TODO prefix and count handling
var results []mstorage.ObjectMetadata var results []mstorage.ObjectMetadata
for key, object := range storage.objectdata { for key, object := range storage.objectdata {
if strings.HasPrefix(key, bucket+":") { if bucket == object.metadata.Bucket {
results = append(results, object.metadata) if strings.HasPrefix(key, bucket+":") {
results = append(results, object.metadata)
}
} }
} }
return results return results

@ -40,6 +40,7 @@ type BucketMetadata struct {
} }
type ObjectMetadata struct { type ObjectMetadata struct {
Bucket string
Key string Key string
Created time.Time Created time.Time
Size int Size int

@ -10,15 +10,15 @@ type ObjectExists struct {
Key string Key string
} }
type BucketNameInvalid struct { type ObjectNotFound GenericError
Bucket string
}
type BucketExists struct { type GenericBucketError struct {
Bucket string Bucket string
} }
type ObjectNotFound GenericError type BucketNameInvalid GenericBucketError
type BucketExists GenericBucketError
type BucketNotFound GenericBucketError
func (self ObjectNotFound) Error() string { func (self ObjectNotFound) Error() string {
return "Object not Found: " + self.Bucket + "#" + self.Path return "Object not Found: " + self.Bucket + "#" + self.Path
@ -35,3 +35,7 @@ func (self BucketNameInvalid) Error() string {
func (self BucketExists) Error() string { func (self BucketExists) Error() string {
return "Bucket exists: " + self.Bucket return "Bucket exists: " + self.Bucket
} }
func (self BucketNotFound) Error() string {
return "Bucket not Found: " + self.Bucket
}

@ -51,9 +51,8 @@ type encoder interface {
func HttpHandler(storage mstorage.Storage) http.Handler { func HttpHandler(storage mstorage.Storage) http.Handler {
mux := mux.NewRouter() mux := mux.NewRouter()
api := minioApi{ var api = minioApi{}
storage: storage, api.storage = storage
}
mux.HandleFunc("/", api.listBucketsHandler).Methods("GET") mux.HandleFunc("/", api.listBucketsHandler).Methods("GET")
mux.HandleFunc("/{bucket}", api.listObjectsHandler).Methods("GET") mux.HandleFunc("/{bucket}", api.listObjectsHandler).Methods("GET")
@ -62,6 +61,7 @@ func HttpHandler(storage mstorage.Storage) http.Handler {
mux.HandleFunc("/{bucket}/{object:.*}", api.getObjectHandler).Methods("GET") mux.HandleFunc("/{bucket}/{object:.*}", api.getObjectHandler).Methods("GET")
mux.HandleFunc("/{bucket}/{object:.*}", api.headObjectHandler).Methods("HEAD") mux.HandleFunc("/{bucket}/{object:.*}", api.headObjectHandler).Methods("HEAD")
mux.HandleFunc("/{bucket}/{object:.*}", api.putObjectHandler).Methods("PUT") mux.HandleFunc("/{bucket}/{object:.*}", api.putObjectHandler).Methods("PUT")
return mux return mux
} }
@ -113,9 +113,8 @@ func (server *minioApi) headObjectHandler(w http.ResponseWriter, req *http.Reque
func (server *minioApi) listBucketsHandler(w http.ResponseWriter, req *http.Request) { func (server *minioApi) listBucketsHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
var prefix string prefix, ok := vars["prefix"]
var ok bool if !ok {
if prefix, ok = vars["prefix"]; ok == false {
prefix = "" prefix = ""
} }
@ -145,7 +144,7 @@ func (server *minioApi) listObjectsHandler(w http.ResponseWriter, req *http.Requ
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
prefix, ok := vars["prefix"] prefix, ok := vars["prefix"]
if ok == false { if !ok {
prefix = "" prefix = ""
} }
@ -196,8 +195,7 @@ func (server *minioApi) putBucketHandler(w http.ResponseWriter, req *http.Reques
} }
} }
// Helpers // Write Object Header helper
func writeObjectHeaders(w http.ResponseWriter, metadata mstorage.ObjectMetadata) { func writeObjectHeaders(w http.ResponseWriter, metadata mstorage.ObjectMetadata) {
lastModified := metadata.Created.Format(time.RFC1123) lastModified := metadata.Created.Format(time.RFC1123)
w.Header().Set("ETag", metadata.ETag) w.Header().Set("ETag", metadata.ETag)
@ -206,53 +204,48 @@ func writeObjectHeaders(w http.ResponseWriter, metadata mstorage.ObjectMetadata)
w.Header().Set("Content-Type", "text/plain") w.Header().Set("Content-Type", "text/plain")
} }
func generateBucketsListResult(buckets []mstorage.BucketMetadata) (data BucketListResponse) { func generateBucketsListResult(buckets []mstorage.BucketMetadata) BucketListResponse {
var listbuckets []*Bucket var listbuckets []*Bucket
var data = BucketListResponse{}
var owner = Owner{}
owner := Owner{ owner.ID = "minio"
ID: "minio", owner.DisplayName = "minio"
DisplayName: "minio",
}
for _, bucket := range buckets { for _, bucket := range buckets {
listbucket := &Bucket{ var listbucket = &Bucket{}
Name: bucket.Name, listbucket.Name = bucket.Name
CreationDate: bucket.Created.Format(dateFormat), listbucket.CreationDate = bucket.Created.Format(dateFormat)
}
listbuckets = append(listbuckets, listbucket) listbuckets = append(listbuckets, listbucket)
} }
data = BucketListResponse{ data.Owner = owner
Owner: owner,
}
data.Buckets.Bucket = listbuckets data.Buckets.Bucket = listbuckets
return
return data
} }
func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata) (data ObjectListResponse) { func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata) ObjectListResponse {
var contents []*Item var contents []*Item
var owner = Owner{}
var data = ObjectListResponse{}
owner := Owner{ owner.ID = "minio"
ID: "minio", owner.DisplayName = "minio"
DisplayName: "minio",
}
for _, object := range objects { for _, object := range objects {
content := &Item{ var content = &Item{}
Key: object.Key, content.Key = object.Key
LastModified: object.Created.Format(dateFormat), content.LastModified = object.Created.Format(dateFormat)
ETag: object.ETag, content.ETag = object.ETag
Size: object.Size, content.Size = object.Size
StorageClass: "STANDARD", content.StorageClass = "STANDARD"
Owner: owner, content.Owner = owner
}
contents = append(contents, content) contents = append(contents, content)
} }
data = ObjectListResponse{ data.Name = bucket
Name: bucket, data.Contents = contents
Contents: contents, data.MaxKeys = MAX_OBJECT_LIST
MaxKeys: MAX_OBJECT_LIST, data.IsTruncated = false
IsTruncated: false, return data
}
return
} }

Loading…
Cancel
Save