diff options
Diffstat (limited to 'vendor/_nuts/github.com/go-martini/martini/martini.go')
| -rw-r--r-- | vendor/_nuts/github.com/go-martini/martini/martini.go | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/vendor/_nuts/github.com/go-martini/martini/martini.go b/vendor/_nuts/github.com/go-martini/martini/martini.go new file mode 100644 index 0000000..104d98c --- /dev/null +++ b/vendor/_nuts/github.com/go-martini/martini/martini.go @@ -0,0 +1,183 @@ +// Package martini is a powerful package for quickly writing modular web applications/services in Golang. +// +// For a full guide visit http://github.com/go-martini/martini +// +// package main +// +// import "github.com/go-martini/martini" +// +// func main() { +// m := martini.Classic() +// +// m.Get("/", func() string { +// return "Hello world!" +// }) +// +// m.Run() +// } +package martini + +import ( + "log" + "net/http" + "os" + "reflect" + + "com.teddywing/new-house-on-the-block/vendor/_nuts/github.com/codegangsta/inject" +) + +// Martini represents the top level web application. inject.Injector methods can be invoked to map services on a global level. +type Martini struct { + inject.Injector + handlers []Handler + action Handler + logger *log.Logger +} + +// New creates a bare bones Martini instance. Use this method if you want to have full control over the middleware that is used. +func New() *Martini { + m := &Martini{Injector: inject.New(), action: func() {}, logger: log.New(os.Stdout, "[martini] ", 0)} + m.Map(m.logger) + m.Map(defaultReturnHandler()) + return m +} + +// Handlers sets the entire middleware stack with the given Handlers. This will clear any current middleware handlers. +// Will panic if any of the handlers is not a callable function +func (m *Martini) Handlers(handlers ...Handler) { + m.handlers = make([]Handler, 0) + for _, handler := range handlers { + m.Use(handler) + } +} + +// Action sets the handler that will be called after all the middleware has been invoked. This is set to martini.Router in a martini.Classic(). +func (m *Martini) Action(handler Handler) { + validateHandler(handler) + m.action = handler +} + +// Use adds a middleware Handler to the stack. Will panic if the handler is not a callable func. Middleware Handlers are invoked in the order that they are added. +func (m *Martini) Use(handler Handler) { + validateHandler(handler) + + m.handlers = append(m.handlers, handler) +} + +// ServeHTTP is the HTTP Entry point for a Martini instance. Useful if you want to control your own HTTP server. +func (m *Martini) ServeHTTP(res http.ResponseWriter, req *http.Request) { + m.createContext(res, req).run() +} + +// Run the http server on a given host and port. +func (m *Martini) RunOnAddr(addr string) { + // TODO: Should probably be implemented using a new instance of http.Server in place of + // calling http.ListenAndServer directly, so that it could be stored in the martini struct for later use. + // This would also allow to improve testing when a custom host and port are passed. + + logger := m.Injector.Get(reflect.TypeOf(m.logger)).Interface().(*log.Logger) + logger.Printf("listening on %s (%s)\n", addr, Env) + logger.Fatalln(http.ListenAndServe(addr, m)) +} + +// Run the http server. Listening on os.GetEnv("PORT") or 3000 by default. +func (m *Martini) Run() { + port := os.Getenv("PORT") + if len(port) == 0 { + port = "3000" + } + + host := os.Getenv("HOST") + + m.RunOnAddr(host + ":" + port) +} + +func (m *Martini) createContext(res http.ResponseWriter, req *http.Request) *context { + c := &context{inject.New(), m.handlers, m.action, NewResponseWriter(res), 0} + c.SetParent(m) + c.MapTo(c, (*Context)(nil)) + c.MapTo(c.rw, (*http.ResponseWriter)(nil)) + c.Map(req) + return c +} + +// ClassicMartini represents a Martini with some reasonable defaults. Embeds the router functions for convenience. +type ClassicMartini struct { + *Martini + Router +} + +// Classic creates a classic Martini with some basic default middleware - martini.Logger, martini.Recovery and martini.Static. +// Classic also maps martini.Routes as a service. +func Classic() *ClassicMartini { + r := NewRouter() + m := New() + m.Use(Logger()) + m.Use(Recovery()) + m.Use(Static("public")) + m.MapTo(r, (*Routes)(nil)) + m.Action(r.Handle) + return &ClassicMartini{m, r} +} + +// Handler can be any callable function. Martini attempts to inject services into the handler's argument list. +// Martini will panic if an argument could not be fullfilled via dependency injection. +type Handler interface{} + +func validateHandler(handler Handler) { + if reflect.TypeOf(handler).Kind() != reflect.Func { + panic("martini handler must be a callable func") + } +} + +// Context represents a request context. Services can be mapped on the request level from this interface. +type Context interface { + inject.Injector + // Next is an optional function that Middleware Handlers can call to yield the until after + // the other Handlers have been executed. This works really well for any operations that must + // happen after an http request + Next() + // Written returns whether or not the response for this context has been written. + Written() bool +} + +type context struct { + inject.Injector + handlers []Handler + action Handler + rw ResponseWriter + index int +} + +func (c *context) handler() Handler { + if c.index < len(c.handlers) { + return c.handlers[c.index] + } + if c.index == len(c.handlers) { + return c.action + } + panic("invalid index for context handler") +} + +func (c *context) Next() { + c.index += 1 + c.run() +} + +func (c *context) Written() bool { + return c.rw.Written() +} + +func (c *context) run() { + for c.index <= len(c.handlers) { + _, err := c.Invoke(c.handler()) + if err != nil { + panic(err) + } + c.index += 1 + + if c.Written() { + return + } + } +} |
