Use adapter pattern for handlers
This commit is contained in:
parent
5466c615aa
commit
27bc86490e
6 changed files with 181 additions and 164 deletions
15
adapters.go
Normal file
15
adapters.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// Adapter is an HTTP middleware
|
||||||
|
type Adapter func(http.Handler) http.Handler
|
||||||
|
|
||||||
|
// Adapt applies adapters to an HTTP handler function
|
||||||
|
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
|
||||||
|
for i := len(adapters) - 1; i >= 0; i-- {
|
||||||
|
h = adapters[i](h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
20
api.go
20
api.go
|
@ -19,7 +19,8 @@ type CopyObjectInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateBucketHandler creates a new bucket
|
// CreateBucketHandler creates a new bucket
|
||||||
func (s *Server) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) CreateBucketHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
var bucket minio.BucketInfo
|
var bucket minio.BucketInfo
|
||||||
|
|
||||||
err := json.NewDecoder(r.Body).Decode(&bucket)
|
err := json.NewDecoder(r.Body).Decode(&bucket)
|
||||||
|
@ -42,10 +43,12 @@ func (s *Server) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateObjectHandler allows to upload a new object
|
// CreateObjectHandler allows to upload a new object
|
||||||
func (s *Server) CreateObjectHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) CreateObjectHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
if r.Header.Get("Content-Type") == "application/json" {
|
if r.Header.Get("Content-Type") == "application/json" {
|
||||||
|
@ -95,10 +98,12 @@ func (s *Server) CreateObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBucketHandler deletes a bucket
|
// DeleteBucketHandler deletes a bucket
|
||||||
func (s *Server) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) DeleteBucketHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
err := s.s3.RemoveBucket(vars["bucketName"])
|
err := s.s3.RemoveBucket(vars["bucketName"])
|
||||||
|
@ -108,10 +113,12 @@ func (s *Server) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObjectHandler deletes an object
|
// DeleteObjectHandler deletes an object
|
||||||
func (s *Server) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) DeleteObjectHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
err := s.s3.RemoveObject(vars["bucketName"], vars["objectName"])
|
err := s.s3.RemoveObject(vars["bucketName"], vars["objectName"])
|
||||||
|
@ -121,10 +128,12 @@ func (s *Server) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectHandler downloads an object to the client
|
// GetObjectHandler downloads an object to the client
|
||||||
func (s *Server) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetObjectHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
objectName := vars["objectName"]
|
objectName := vars["objectName"]
|
||||||
|
|
||||||
|
@ -142,4 +151,5 @@ func (s *Server) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
10
logger.go
10
logger.go
|
@ -7,9 +7,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger logs HTTP requests
|
// Logger logs HTTP requests
|
||||||
func Logger() Middleware {
|
func Logger() Adapter {
|
||||||
return func(next http.HandlerFunc) http.HandlerFunc {
|
return func(next http.Handler) http.Handler {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -21,7 +21,7 @@ func Logger() Middleware {
|
||||||
)
|
)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
next(w, r)
|
next.ServeHTTP(w, r)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
main.go
16
main.go
|
@ -29,15 +29,15 @@ func main() {
|
||||||
router.
|
router.
|
||||||
Methods("GET").
|
Methods("GET").
|
||||||
Path("/").
|
Path("/").
|
||||||
HandlerFunc(Chain(IndexHandler, Logger()))
|
Handler(Adapt(IndexHandler(), Logger()))
|
||||||
router.
|
router.
|
||||||
Methods("GET").
|
Methods("GET").
|
||||||
Path("/buckets").
|
Path("/buckets").
|
||||||
HandlerFunc(Chain(s.BucketsPageHandler, Logger()))
|
Handler(Adapt(s.BucketsPageHandler(), Logger()))
|
||||||
router.
|
router.
|
||||||
Methods("GET").
|
Methods("GET").
|
||||||
Path("/buckets/{bucketName}").
|
Path("/buckets/{bucketName}").
|
||||||
HandlerFunc(Chain(s.BucketPageHandler, Logger()))
|
Handler(Adapt(s.BucketPageHandler(), Logger()))
|
||||||
|
|
||||||
api := router.PathPrefix("/api").Subrouter()
|
api := router.PathPrefix("/api").Subrouter()
|
||||||
|
|
||||||
|
@ -45,23 +45,23 @@ func main() {
|
||||||
buckets.
|
buckets.
|
||||||
Methods("POST").
|
Methods("POST").
|
||||||
Path("").
|
Path("").
|
||||||
HandlerFunc(Chain(s.CreateBucketHandler, Logger()))
|
Handler(Adapt(s.CreateBucketHandler(), Logger()))
|
||||||
buckets.
|
buckets.
|
||||||
Methods("DELETE").
|
Methods("DELETE").
|
||||||
Path("/{bucketName}").
|
Path("/{bucketName}").
|
||||||
HandlerFunc(Chain(s.DeleteBucketHandler, Logger()))
|
Handler(Adapt(s.DeleteBucketHandler(), Logger()))
|
||||||
buckets.
|
buckets.
|
||||||
Methods("POST").
|
Methods("POST").
|
||||||
Path("/{bucketName}/objects").
|
Path("/{bucketName}/objects").
|
||||||
HandlerFunc(Chain(s.CreateObjectHandler, Logger()))
|
Handler(Adapt(s.CreateObjectHandler(), Logger()))
|
||||||
buckets.
|
buckets.
|
||||||
Methods("GET").
|
Methods("GET").
|
||||||
Path("/{bucketName}/objects/{objectName}").
|
Path("/{bucketName}/objects/{objectName}").
|
||||||
HandlerFunc(Chain(s.GetObjectHandler, Logger()))
|
Handler(Adapt(s.GetObjectHandler(), Logger()))
|
||||||
buckets.
|
buckets.
|
||||||
Methods("DELETE").
|
Methods("DELETE").
|
||||||
Path("/{bucketName}/objects/{objectName}").
|
Path("/{bucketName}/objects/{objectName}").
|
||||||
HandlerFunc(Chain(s.DeleteObjectHandler, Logger()))
|
Handler(Adapt(s.DeleteObjectHandler(), Logger()))
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":"+port, router))
|
log.Fatal(http.ListenAndServe(":"+port, router))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
// Middleware is an HTTP middleware
|
|
||||||
type Middleware func(http.HandlerFunc) http.HandlerFunc
|
|
||||||
|
|
||||||
// Chain applies middleware to an HTTP handler function
|
|
||||||
func Chain(f http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
|
|
||||||
for i := len(middlewares) - 1; i >= 0; i-- {
|
|
||||||
f = middlewares[i](f)
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
12
pages.go
12
pages.go
|
@ -22,7 +22,8 @@ type ObjectWithIcon struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketPageHandler shows the details page of a bucket
|
// BucketPageHandler shows the details page of a bucket
|
||||||
func (s *Server) BucketPageHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) BucketPageHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
bucketName := mux.Vars(r)["bucketName"]
|
bucketName := mux.Vars(r)["bucketName"]
|
||||||
var objects []ObjectWithIcon
|
var objects []ObjectWithIcon
|
||||||
|
|
||||||
|
@ -57,10 +58,12 @@ func (s *Server) BucketPageHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketsPageHandler shows all buckets
|
// BucketsPageHandler shows all buckets
|
||||||
func (s *Server) BucketsPageHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) BucketsPageHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
lp := path.Join("templates", "layout.html")
|
lp := path.Join("templates", "layout.html")
|
||||||
ip := path.Join("templates", "index.html")
|
ip := path.Join("templates", "index.html")
|
||||||
|
|
||||||
|
@ -81,11 +84,14 @@ func (s *Server) BucketsPageHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexHandler forwards to "/buckets"
|
// IndexHandler forwards to "/buckets"
|
||||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func IndexHandler() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect)
|
http.Redirect(w, r, "/buckets", http.StatusPermanentRedirect)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// icon returns an icon for a file type
|
// icon returns an icon for a file type
|
||||||
|
|
Loading…
Reference in a new issue