diff --git a/api.go b/api.go index 09f9697..da559b5 100644 --- a/api.go +++ b/api.go @@ -44,40 +44,6 @@ func (s *Server) CreateBucketHandler(w http.ResponseWriter, r *http.Request) { } } -// DeleteBucketHandler deletes a bucket -func (s *Server) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - err := s.s3.RemoveBucket(vars["bucketName"]) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} - -// GetObjectHandler downloads an object to the client -func (s *Server) GetObjectHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - objectName := vars["objectName"] - - object, err := s.s3.GetObject(vars["bucketName"], objectName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", objectName)) - w.Header().Set("Content-Type", "application/octet-stream") - - _, err = io.Copy(w, object) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } -} - // CreateObjectHandler allows to upload a new object func (s *Server) CreateObjectHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -131,6 +97,19 @@ func (s *Server) CreateObjectHandler(w http.ResponseWriter, r *http.Request) { } } +// DeleteBucketHandler deletes a bucket +func (s *Server) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + err := s.s3.RemoveBucket(vars["bucketName"]) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusNoContent) +} + // DeleteObjectHandler deletes an object func (s *Server) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -143,3 +122,24 @@ func (s *Server) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } + +// GetObjectHandler downloads an object to the client +func (s *Server) GetObjectHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + objectName := vars["objectName"] + + object, err := s.s3.GetObject(vars["bucketName"], objectName) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", objectName)) + w.Header().Set("Content-Type", "application/octet-stream") + + _, err = io.Copy(w, object) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } +} diff --git a/main.go b/main.go index 8d69474..81de364 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "net/http" "os" + "github.com/gorilla/mux" minio "github.com/minio/minio-go" ) @@ -19,7 +20,48 @@ func main() { port = "8080" } - router := NewRouter() + s := &Server{ + s3: NewMinioClient(), + } + + router := mux.NewRouter().StrictSlash(true) + + router. + Methods("GET"). + Path("/"). + HandlerFunc(Chain(IndexHandler, Logger())) + router. + Methods("GET"). + Path("/buckets"). + HandlerFunc(Chain(s.BucketsPageHandler, Logger())) + router. + Methods("GET"). + Path("/buckets/{bucketName}"). + HandlerFunc(Chain(s.BucketPageHandler, Logger())) + + api := router.PathPrefix("/api").Subrouter() + + buckets := api.PathPrefix("/buckets").Subrouter() + buckets. + Methods("POST"). + Path(""). + HandlerFunc(Chain(s.CreateBucketHandler, Logger())) + buckets. + Methods("DELETE"). + Path("/{bucketName}"). + HandlerFunc(Chain(s.DeleteBucketHandler, Logger())) + buckets. + Methods("POST"). + Path("/{bucketName}/objects"). + HandlerFunc(Chain(s.CreateObjectHandler, Logger())) + buckets. + Methods("GET"). + Path("/{bucketName}/objects/{objectName}"). + HandlerFunc(Chain(s.GetObjectHandler, Logger())) + buckets. + Methods("DELETE"). + Path("/{bucketName}/objects/{objectName}"). + HandlerFunc(Chain(s.DeleteObjectHandler, Logger())) log.Fatal(http.ListenAndServe(":"+port, router)) } diff --git a/pages.go b/pages.go index 33a2a7f..a4c23d3 100644 --- a/pages.go +++ b/pages.go @@ -9,45 +9,16 @@ import ( minio "github.com/minio/minio-go" ) -// ObjectWithIcon is a minio object with an added icon -type ObjectWithIcon struct { - minio.ObjectInfo - Icon string -} - // BucketPage defines the details page of a bucket type BucketPage struct { BucketName string Objects []ObjectWithIcon } -// IndexPageHandler forwards to "/buckets" -func IndexPageHandler(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect) -} - -// BucketsPageHandler shows all buckets -func (s *Server) BucketsPageHandler(w http.ResponseWriter, r *http.Request) { - lp := path.Join("templates", "layout.html") - ip := path.Join("templates", "index.html") - - t, err := template.ParseFiles(lp, ip) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - - buckets, err := s.s3.ListBuckets() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - - err = t.ExecuteTemplate(w, "layout", buckets) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } +// ObjectWithIcon is a minio object with an added icon +type ObjectWithIcon struct { + minio.ObjectInfo + Icon string } // BucketPageHandler shows the details page of a bucket @@ -88,6 +59,35 @@ func (s *Server) BucketPageHandler(w http.ResponseWriter, r *http.Request) { } } +// BucketsPageHandler shows all buckets +func (s *Server) BucketsPageHandler(w http.ResponseWriter, r *http.Request) { + lp := path.Join("templates", "layout.html") + ip := path.Join("templates", "index.html") + + t, err := template.ParseFiles(lp, ip) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + buckets, err := s.s3.ListBuckets() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + err = t.ExecuteTemplate(w, "layout", buckets) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } +} + +// IndexHandler forwards to "/buckets" +func IndexHandler(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect) +} + // icon returns an icon for a file type func icon(fileName string) string { e := path.Ext(fileName) diff --git a/router.go b/router.go deleted file mode 100644 index 629b523..0000000 --- a/router.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "github.com/gorilla/mux" -) - -// NewRouter creates a new router -func NewRouter() *mux.Router { - router := mux.NewRouter().StrictSlash(true) - - for _, route := range routes { - router. - Methods(route.Method). - Path(route.Pattern). - HandlerFunc(route.HandlerFunc) - } - - return router -} diff --git a/routes.go b/routes.go deleted file mode 100644 index 0eac95f..0000000 --- a/routes.go +++ /dev/null @@ -1,60 +0,0 @@ -package main - -import "net/http" - -// Route represents a path of the API -type Route struct { - Method string - Pattern string - HandlerFunc http.HandlerFunc -} - -// Routes is an array of routes -type Routes []Route - -var s = &Server{ - s3: NewMinioClient(), -} - -var routes = Routes{ - Route{ - "GET", - "/", - Chain(IndexPageHandler, Logger()), - }, - Route{ - "GET", - "/buckets", - Chain(s.BucketsPageHandler, Logger()), - }, - Route{ - "GET", - "/buckets/{bucketName}", - Chain(s.BucketPageHandler, Logger()), - }, - Route{ - "POST", - "/api/buckets", - Chain(s.CreateBucketHandler, Logger()), - }, - Route{ - "DELETE", - "/api/buckets/{bucketName}", - Chain(s.DeleteBucketHandler, Logger()), - }, - Route{ - "GET", - "/api/buckets/{bucketName}/objects/{objectName}", - Chain(s.GetObjectHandler, Logger()), - }, - Route{ - "POST", - "/api/buckets/{bucketName}/objects", - Chain(s.CreateObjectHandler, Logger()), - }, - Route{ - "DELETE", - "/api/buckets/{bucketName}/objects/{objectName}", - Chain(s.DeleteObjectHandler, Logger()), - }, -}