123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- 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{},
- }
- }
|