mirror of
https://github.com/adnanh/webhook.git
synced 2025-05-14 09:34:43 +00:00
For 3rd parties building binary packages, and for build consistency in general, it is very helpful to have the same set of dependencies at any time the product is built. See [tools/godep](https://github.com/tools/godep) for further details.
169 lines
5.2 KiB
Go
169 lines
5.2 KiB
Go
package negroni
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
const (
|
|
// DefaultAddress is used if no other is specified.
|
|
DefaultAddress = ":8080"
|
|
)
|
|
|
|
// Handler handler is an interface that objects can implement to be registered to serve as middleware
|
|
// in the Negroni middleware stack.
|
|
// ServeHTTP should yield to the next middleware in the chain by invoking the next http.HandlerFunc
|
|
// passed in.
|
|
//
|
|
// If the Handler writes to the ResponseWriter, the next http.HandlerFunc should not be invoked.
|
|
type Handler interface {
|
|
ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
|
|
}
|
|
|
|
// HandlerFunc is an adapter to allow the use of ordinary functions as Negroni handlers.
|
|
// If f is a function with the appropriate signature, HandlerFunc(f) is a Handler object that calls f.
|
|
type HandlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
|
|
|
|
func (h HandlerFunc) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
h(rw, r, next)
|
|
}
|
|
|
|
type middleware struct {
|
|
handler Handler
|
|
next *middleware
|
|
}
|
|
|
|
func (m middleware) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|
m.handler.ServeHTTP(rw, r, m.next.ServeHTTP)
|
|
}
|
|
|
|
// Wrap converts a http.Handler into a negroni.Handler so it can be used as a Negroni
|
|
// middleware. The next http.HandlerFunc is automatically called after the Handler
|
|
// is executed.
|
|
func Wrap(handler http.Handler) Handler {
|
|
return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
handler.ServeHTTP(rw, r)
|
|
next(rw, r)
|
|
})
|
|
}
|
|
|
|
// WrapFunc converts a http.HandlerFunc into a negroni.Handler so it can be used as a Negroni
|
|
// middleware. The next http.HandlerFunc is automatically called after the Handler
|
|
// is executed.
|
|
func WrapFunc(handlerFunc http.HandlerFunc) Handler {
|
|
return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
handlerFunc(rw, r)
|
|
next(rw, r)
|
|
})
|
|
}
|
|
|
|
// Negroni is a stack of Middleware Handlers that can be invoked as an http.Handler.
|
|
// Negroni middleware is evaluated in the order that they are added to the stack using
|
|
// the Use and UseHandler methods.
|
|
type Negroni struct {
|
|
middleware middleware
|
|
handlers []Handler
|
|
}
|
|
|
|
// New returns a new Negroni instance with no middleware preconfigured.
|
|
func New(handlers ...Handler) *Negroni {
|
|
return &Negroni{
|
|
handlers: handlers,
|
|
middleware: build(handlers),
|
|
}
|
|
}
|
|
|
|
// With returns a new Negroni instance that is a combination of the negroni
|
|
// receiver's handlers and the provided handlers.
|
|
func (n *Negroni) With(handlers ...Handler) *Negroni {
|
|
return New(
|
|
append(n.handlers, handlers...)...,
|
|
)
|
|
}
|
|
|
|
// Classic returns a new Negroni instance with the default middleware already
|
|
// in the stack.
|
|
//
|
|
// Recovery - Panic Recovery Middleware
|
|
// Logger - Request/Response Logging
|
|
// Static - Static File Serving
|
|
func Classic() *Negroni {
|
|
return New(NewRecovery(), NewLogger(), NewStatic(http.Dir("public")))
|
|
}
|
|
|
|
func (n *Negroni) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|
n.middleware.ServeHTTP(NewResponseWriter(rw), r)
|
|
}
|
|
|
|
// Use adds a Handler onto the middleware stack. Handlers are invoked in the order they are added to a Negroni.
|
|
func (n *Negroni) Use(handler Handler) {
|
|
if handler == nil {
|
|
panic("handler cannot be nil")
|
|
}
|
|
|
|
n.handlers = append(n.handlers, handler)
|
|
n.middleware = build(n.handlers)
|
|
}
|
|
|
|
// UseFunc adds a Negroni-style handler function onto the middleware stack.
|
|
func (n *Negroni) UseFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)) {
|
|
n.Use(HandlerFunc(handlerFunc))
|
|
}
|
|
|
|
// UseHandler adds a http.Handler onto the middleware stack. Handlers are invoked in the order they are added to a Negroni.
|
|
func (n *Negroni) UseHandler(handler http.Handler) {
|
|
n.Use(Wrap(handler))
|
|
}
|
|
|
|
// UseHandlerFunc adds a http.HandlerFunc-style handler function onto the middleware stack.
|
|
func (n *Negroni) UseHandlerFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request)) {
|
|
n.UseHandler(http.HandlerFunc(handlerFunc))
|
|
}
|
|
|
|
// Run is a convenience function that runs the negroni stack as an HTTP
|
|
// server. The addr string, if provided, takes the same format as http.ListenAndServe.
|
|
// If no address is provided but the PORT environment variable is set, the PORT value is used.
|
|
// If neither is provided, the address' value will equal the DefaultAddress constant.
|
|
func (n *Negroni) Run(addr ...string) {
|
|
l := log.New(os.Stdout, "[negroni] ", 0)
|
|
finalAddr := detectAddress(addr...)
|
|
l.Printf("listening on %s", finalAddr)
|
|
l.Fatal(http.ListenAndServe(finalAddr, n))
|
|
}
|
|
|
|
func detectAddress(addr ...string) string {
|
|
if len(addr) > 0 {
|
|
return addr[0]
|
|
}
|
|
if port := os.Getenv("PORT"); port != "" {
|
|
return ":" + port
|
|
}
|
|
return DefaultAddress
|
|
}
|
|
|
|
// Returns a list of all the handlers in the current Negroni middleware chain.
|
|
func (n *Negroni) Handlers() []Handler {
|
|
return n.handlers
|
|
}
|
|
|
|
func build(handlers []Handler) middleware {
|
|
var next middleware
|
|
|
|
if len(handlers) == 0 {
|
|
return voidMiddleware()
|
|
} else if len(handlers) > 1 {
|
|
next = build(handlers[1:])
|
|
} else {
|
|
next = voidMiddleware()
|
|
}
|
|
|
|
return middleware{handlers[0], &next}
|
|
}
|
|
|
|
func voidMiddleware() middleware {
|
|
return middleware{
|
|
HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {}),
|
|
&middleware{},
|
|
}
|
|
}
|