From 53190e1210a0c2f15da105e45dc8cef4b2ff8eb4 Mon Sep 17 00:00:00 2001 From: "Frederick F. Kautz IV" Date: Tue, 20 Jan 2015 16:08:14 -0800 Subject: [PATCH] Initial work for xml list objects --- pkg/httpserver/httpserver.go | 10 ++--- pkg/server/server.go | 2 +- pkg/storage/storage.go | 10 +++-- pkg/webapi/minioapi/definitions.go | 29 +++++++++++++ pkg/webapi/minioapi/minioapi.go | 62 ++++++++++++++++++++++++++++ pkg/webapi/minioapi/minioapi_test.go | 45 ++++++++++++++++++++ 6 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 pkg/webapi/minioapi/definitions.go create mode 100644 pkg/webapi/minioapi/minioapi_test.go diff --git a/pkg/httpserver/httpserver.go b/pkg/httpserver/httpserver.go index 6ede37a99..5919cc5b0 100644 --- a/pkg/httpserver/httpserver.go +++ b/pkg/httpserver/httpserver.go @@ -5,16 +5,16 @@ import ( "net/http" ) -func Start(handler http.Handler) (chan<- string, <-chan error) { +func Start(handler http.Handler, address string) (chan<- string, <-chan error) { ctrlChannel := make(chan string) errorChannel := make(chan error) - go start(ctrlChannel, errorChannel, handler) + go start(ctrlChannel, errorChannel, handler, address) return ctrlChannel, errorChannel } -func start(ctrlChannel <-chan string, errorChannel chan<- error, router http.Handler) { - log.Println("Starting HTTP Server") - err := http.ListenAndServe(":8080", router) +func start(ctrlChannel <-chan string, errorChannel chan<- error, router http.Handler, address string) { + log.Println("Starting HTTP Server on " + address) + err := http.ListenAndServe(address, router) errorChannel <- err close(errorChannel) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 77dda7814..dc4a0cd26 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -17,7 +17,7 @@ func Start() { ctrlChans = append(ctrlChans, ctrlChan) statusChans = append(statusChans, statusChan) - ctrlChan, statusChan = httpserver.Start(minioapi.HttpHandler(storage)) + ctrlChan, statusChan = httpserver.Start(minioapi.HttpHandler(storage), ":8080") ctrlChans = append(ctrlChans, ctrlChan) statusChans = append(statusChans, statusChan) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index aeed5100c..a4ee08c3a 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -2,7 +2,6 @@ package storage import ( "bytes" - "errors" "io" ) @@ -10,6 +9,8 @@ type Storage struct { data map[string][]byte } +type ObjectMetadata struct{} + type GenericError struct { bucket string path string @@ -42,6 +43,10 @@ func (storage *Storage) StoreObject(bucket string, object string, data io.Reader } } +func (storage *Storage) ListObjects(bucket, prefix string, count int) []ObjectMetadata { + return []ObjectMetadata{} +} + func Start() (chan<- string, <-chan error, *Storage) { ctrlChannel := make(chan string) errorChannel := make(chan error) @@ -52,8 +57,5 @@ func Start() (chan<- string, <-chan error, *Storage) { } func start(ctrlChannel <-chan string, errorChannel chan<- error) { - errorChannel <- errors.New("STORAGE MSG") - errorChannel <- errors.New("STORAGE MSG") - errorChannel <- errors.New("STORAGE MSG") close(errorChannel) } diff --git a/pkg/webapi/minioapi/definitions.go b/pkg/webapi/minioapi/definitions.go new file mode 100644 index 000000000..e03247e1e --- /dev/null +++ b/pkg/webapi/minioapi/definitions.go @@ -0,0 +1,29 @@ +package minioapi + +import ( + "encoding/xml" +) + +type ListResponse struct { + XMLName xml.Name `xml:"ListBucketResult"` + Name string `xml:"Name"` + Prefix string + Marker string + MaxKeys int32 + IsTruncated bool + Contents []Content `xml:"Contents",innerxml` +} + +type Content struct { + Key string + LastModified string + ETag string + Size uint64 + StorageClass string + Owner Owner +} + +type Owner struct { + ID string + DisplayName string +} diff --git a/pkg/webapi/minioapi/minioapi.go b/pkg/webapi/minioapi/minioapi.go index f029e1e53..f9466cf20 100644 --- a/pkg/webapi/minioapi/minioapi.go +++ b/pkg/webapi/minioapi/minioapi.go @@ -1,6 +1,8 @@ package minioapi import ( + "bytes" + "encoding/xml" "log" "net/http" @@ -17,6 +19,7 @@ func HttpHandler(storage *mstorage.Storage) http.Handler { api := minioApi{ storage: storage, } + mux.HandleFunc("/", api.listHandler).Methods("GET") mux.HandleFunc("/{bucket}/{object:.*}", api.getObjectHandler).Methods("GET") mux.HandleFunc("/{bucket}/{object:.*}", api.putObjectHandler).Methods("PUT") return mux @@ -46,9 +49,68 @@ func (server *minioApi) getObjectHandler(w http.ResponseWriter, req *http.Reques } } +func (server *minioApi) listHandler(w http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + + //delimiter, ok := vars["delimiter"] + //encodingType, ok := vars["encoding-type"] + //marker, ok := vars["marker"] + //maxKeys, ok := vars["max-keys"] + bucket := "bucket" + //bucket, ok := vars["bucket"] + //if ok == false { + // w.WriteHeader(http.StatusBadRequest) + // return + //} + prefix, ok := vars["prefix"] + if ok == false { + prefix = "" + } + + objects := server.storage.ListObjects(bucket, prefix, 1000) + response := generateListResult(objects) + + var bytesBuffer bytes.Buffer + xmlEncoder := xml.NewEncoder(&bytesBuffer) + xmlEncoder.Encode(response) + + w.Header().Set("Content-Type", "application/xml") + w.Write(bytesBuffer.Bytes()) +} + func (server *minioApi) putObjectHandler(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) bucket := vars["bucket"] object := vars["object"] server.storage.StoreObject(bucket, object, req.Body) } + +func generateListResult(objects []mstorage.ObjectMetadata) ListResponse { + owner := Owner{ + ID: "MyID", + DisplayName: "MyDisplayName", + } + contents := []Content{ + Content{ + Key: "one", + LastModified: "two", + ETag: "\"ETag\"", + Size: 1, + StorageClass: "three", + Owner: owner, + }, + Content{ + Key: "four", + LastModified: "five", + ETag: "\"ETag\"", + Size: 1, + StorageClass: "six", + Owner: owner, + }, + } + data := &ListResponse{ + Name: "name", + Contents: contents, + } + return *data +} diff --git a/pkg/webapi/minioapi/minioapi_test.go b/pkg/webapi/minioapi/minioapi_test.go new file mode 100644 index 000000000..4abbd659a --- /dev/null +++ b/pkg/webapi/minioapi/minioapi_test.go @@ -0,0 +1,45 @@ +package minioapi + +import ( + "encoding/xml" + "fmt" + "log" + "os" + "testing" +) + +func TestMinioApi(t *testing.T) { + owner := Owner{ + ID: "MyID", + DisplayName: "MyDisplayName", + } + contents := []Content{ + Content{ + Key: "one", + LastModified: "two", + ETag: "\"ETag\"", + Size: 1, + StorageClass: "three", + Owner: owner, + }, + Content{ + Key: "four", + LastModified: "five", + ETag: "\"ETag\"", + Size: 1, + StorageClass: "six", + Owner: owner, + }, + } + data := &ListResponse{ + Name: "name", + Contents: contents, + } + + xmlEncoder := xml.NewEncoder(os.Stdout) + if err := xmlEncoder.Encode(data); err != nil { + log.Println(err) + } else { + fmt.Println("") + } +}