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
|
||||
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
|
||||
|
||||
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)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
err := s.s3.RemoveBucket(vars["bucketName"])
|
||||
|
@ -108,10 +113,12 @@ func (s *Server) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
objectName := vars["objectName"]
|
||||
|
||||
|
@ -142,4 +151,5 @@ func (s *Server) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
10
logger.go
10
logger.go
|
@ -7,9 +7,9 @@ import (
|
|||
)
|
||||
|
||||
// Logger logs HTTP requests
|
||||
func Logger() Middleware {
|
||||
return func(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
func Logger() Adapter {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
|
||||
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.
|
||||
Methods("GET").
|
||||
Path("/").
|
||||
HandlerFunc(Chain(IndexHandler, Logger()))
|
||||
Handler(Adapt(IndexHandler(), Logger()))
|
||||
router.
|
||||
Methods("GET").
|
||||
Path("/buckets").
|
||||
HandlerFunc(Chain(s.BucketsPageHandler, Logger()))
|
||||
Handler(Adapt(s.BucketsPageHandler(), Logger()))
|
||||
router.
|
||||
Methods("GET").
|
||||
Path("/buckets/{bucketName}").
|
||||
HandlerFunc(Chain(s.BucketPageHandler, Logger()))
|
||||
Handler(Adapt(s.BucketPageHandler(), Logger()))
|
||||
|
||||
api := router.PathPrefix("/api").Subrouter()
|
||||
|
||||
|
@ -45,23 +45,23 @@ func main() {
|
|||
buckets.
|
||||
Methods("POST").
|
||||
Path("").
|
||||
HandlerFunc(Chain(s.CreateBucketHandler, Logger()))
|
||||
Handler(Adapt(s.CreateBucketHandler(), Logger()))
|
||||
buckets.
|
||||
Methods("DELETE").
|
||||
Path("/{bucketName}").
|
||||
HandlerFunc(Chain(s.DeleteBucketHandler, Logger()))
|
||||
Handler(Adapt(s.DeleteBucketHandler(), Logger()))
|
||||
buckets.
|
||||
Methods("POST").
|
||||
Path("/{bucketName}/objects").
|
||||
HandlerFunc(Chain(s.CreateObjectHandler, Logger()))
|
||||
Handler(Adapt(s.CreateObjectHandler(), Logger()))
|
||||
buckets.
|
||||
Methods("GET").
|
||||
Path("/{bucketName}/objects/{objectName}").
|
||||
HandlerFunc(Chain(s.GetObjectHandler, Logger()))
|
||||
Handler(Adapt(s.GetObjectHandler(), Logger()))
|
||||
buckets.
|
||||
Methods("DELETE").
|
||||
Path("/{bucketName}/objects/{objectName}").
|
||||
HandlerFunc(Chain(s.DeleteObjectHandler, Logger()))
|
||||
Handler(Adapt(s.DeleteObjectHandler(), Logger()))
|
||||
|
||||
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
|
||||
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"]
|
||||
var objects []ObjectWithIcon
|
||||
|
||||
|
@ -57,10 +58,12 @@ func (s *Server) BucketPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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")
|
||||
ip := path.Join("templates", "index.html")
|
||||
|
||||
|
@ -81,11 +84,14 @@ func (s *Server) BucketsPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
})
|
||||
}
|
||||
|
||||
// icon returns an icon for a file type
|
||||
|
|
Loading…
Reference in a new issue