Documentation ¶
Overview ¶
Package stack creates a fast and flexible middleware stack for http.Handlers.
Accepted middleware ¶
See UseXXX methods of Stack ¶
Batteries included ¶
Middleware can be found in the sub package stack/middleware and stack/thirdparty.
Credits ¶
Initial inspiration came from Christian Neukirchen's rack for ruby some years ago.
Adapters come from carbocation/interpose (https://github.com/carbocation/interpose/blob/master/adaptors)
Index ¶
- func CloseNotify(rw http.ResponseWriter) (ch <-chan bool, ok bool)
- func Flush(rw http.ResponseWriter) (ok bool)
- func Hijack(rw http.ResponseWriter) (c net.Conn, brw *bufio.ReadWriter, err error, ok bool)
- func ReclaimResponseWriter(rw http.ResponseWriter) http.ResponseWriter
- type ContextHandler
- type ContextHandlerFunc
- type ContextMiddleware
- type Contexter
- type Middleware
- type Recoverer
- type ResponseWriter
- type Stack
- func (s *Stack) Concat(st *Stack) *Stack
- func (s *Stack) ConcatWithHandler(h http.Handler) *Stack
- func (s *Stack) Handler() http.Handler
- func (s *Stack) HandlerWithContext() http.Handler
- func (s *Stack) Use(mw Middleware) *Stack
- func (s *Stack) UseFunc(fn func(wr http.ResponseWriter, req *http.Request, next http.Handler)) *Stack
- func (s *Stack) UseFuncWithContext(...) *Stack
- func (s *Stack) UseHandler(mw http.Handler) *Stack
- func (s *Stack) UseHandlerFunc(fn func(wr http.ResponseWriter, req *http.Request)) *Stack
- func (s *Stack) UseHandlerFuncWithContext(fn func(c Contexter, w http.ResponseWriter, r *http.Request)) *Stack
- func (s *Stack) UseHandlerWithContext(mw ContextHandler) *Stack
- func (s *Stack) UseWithContext(mw ContextMiddleware) *Stack
- func (s *Stack) UseWrapper(mw Wrapper) *Stack
- func (s *Stack) UseWrapperFunc(mw func(http.Handler) http.Handler) *Stack
- func (s *Stack) Wrap(next http.Handler) http.Handler
- func (s *Stack) WrapFunc(fn func(wr http.ResponseWriter, req *http.Request)) http.Handler
- func (s *Stack) WrapFuncWithContext(fn func(ctx Contexter, wr http.ResponseWriter, req *http.Request)) http.Handler
- func (s *Stack) WrapWithContext(app ContextHandler) http.Handler
- type TransactionContexter
- type Wrapper
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseNotify ¶
func CloseNotify(rw http.ResponseWriter) (ch <-chan bool, ok bool)
CloseNotify is the same for http.CloseNotifier as Flush is for http.Flusher ok tells if it was a CloseNotifier
func Flush ¶
func Flush(rw http.ResponseWriter) (ok bool)
Flush is a helper that flushes the buffer in the underlying response writer if it is a http.Flusher. The http.ResponseWriter might also be a Contexter if it allows the retrieval of the underlying ResponseWriter. Ok returns if the underlying ResponseWriter was a http.Flusher
func Hijack ¶
func Hijack(rw http.ResponseWriter) (c net.Conn, brw *bufio.ReadWriter, err error, ok bool)
Hijack is the same for http.Hijacker as Flush is for http.Flusher ok tells if it was a Hijacker
func ReclaimResponseWriter ¶
func ReclaimResponseWriter(rw http.ResponseWriter) http.ResponseWriter
ReclaimResponseWriter is a helper that expects the given http.ResponseWriter to either be the original http.ResponseWriter or a Contexter which has saved a wrack.ResponseWriter. In either case it returns the underlying http.ResponseWriter
Types ¶
type ContextHandler ¶
type ContextHandler interface {
ServeHTTP(ctx Contexter, wr http.ResponseWriter, req *http.Request)
}
ContextHandler is like a http.Handler that needs to be able to store and retrieve context bound to the request
func HandlerToContextHandler ¶
func HandlerToContextHandler(h http.Handler) ContextHandler
type ContextHandlerFunc ¶
type ContextHandlerFunc func(ctx Contexter, wr http.ResponseWriter, req *http.Request)
func (ContextHandlerFunc) ServeHTTP ¶
func (c ContextHandlerFunc) ServeHTTP(wr http.ResponseWriter, req *http.Request)
type ContextMiddleware ¶
type ContextMiddleware interface {
ServeHTTP(ctx Contexter, wr http.ResponseWriter, req *http.Request, next http.Handler)
}
ContextMiddleware is like Middleware that needs to be able to store and retrieve context bound to the request
type Contexter ¶
type Contexter interface { // Set the given Recoverer, replaces the value of the same type // Set may be run on the same Contexter concurrently Set(Recoverer) // Get a given Recoverer. If there is a Recoverer of this type // inside the Contexter, the given Recoverers Recover method is called with the stored value and true is returned. // If no Recoverer of the same type could be found, false is returned // Get may be run on the same Contexter concurrently Get(Recoverer) (has bool) // Del deletes a value of the given type. // Del may be run on the same Contexter concurrently Del(Recoverer) // Transaction runs the given function inside a transaction. A TransactionContexter is passed to the // given function that might be used to call the Set, Get and Del methods inside the transaction. // However that methods must not be used concurrently Transaction(func(TransactionContexter)) }
Contexter stores and retrieves per request data. Only one value per type can be stored.
Example ¶
//go:build go1.1 // +build go1.1 package main import ( "fmt" "github.com/go-on/stack" "net/http" ) type Val string // Recover replaces the value of m with the value of val func (m *Val) Recover(val interface{}) { *m = *(val.(*Val)) // will never panic } func setVal(ctx stack.Contexter, rw http.ResponseWriter, req *http.Request, next http.Handler) { var val Val = "some value" ctx.Set(&val) next.ServeHTTP(rw, req) } func writeVal(ctx stack.Contexter, rw http.ResponseWriter, req *http.Request, next http.Handler) { var val Val found := ctx.Get(&val) if !found { fmt.Println("no value found") } else { fmt.Printf("value: %s\n", string(val)) } next.ServeHTTP(rw, req) } func main() { var s stack.Stack s.UseFuncWithContext(writeVal) s.UseFuncWithContext(setVal) s.UseFuncWithContext(writeVal) r, _ := http.NewRequest("GET", "/", nil) s.HandlerWithContext().ServeHTTP(nil, r) }
Output: no value found value: some value
type Middleware ¶
type Middleware interface { // ServeHTTP serves the request and may write to the given writer. Also may invoke the next handler ServeHTTP(writer http.ResponseWriter, request *http.Request, next http.Handler) }
Middleware is like a http.Handler that is part of a chain of handlers handling the request
type Recoverer ¶
type Recoverer interface { // Recover must be defined on a pointer // and changes the the value of the pointer // to the value the replacement is pointing to // Example // // type S string // func (s *S) Recover(valPtr interface{}) { // *s = *(valPtr.(*S)) // } Recover(valPtr interface{}) }
Recoverer recovers its value from a given value inside a request context
type ResponseWriter ¶
type ResponseWriter struct {
http.ResponseWriter
}
ResponseWriter is used to store the underlying http.ResponseWriter inside the Contexter
func (*ResponseWriter) Recover ¶
func (rw *ResponseWriter) Recover(repl interface{})
type Stack ¶
Stack is a stack of middlewares that handle http requests
Example ¶
//go:build go1.1 // +build go1.1 package main import ( "fmt" "net/http" "github.com/go-on/stack" ) /* This example illustrates 3 ways to write and use middleware. For sharing context, look at example_context_test.go. */ type print1 string func (p print1) ServeHTTP(wr http.ResponseWriter, req *http.Request, next http.Handler) { fmt.Print(p) next.ServeHTTP(wr, req) } type print2 string func (p print2) Wrap(next http.Handler) http.Handler { var f http.HandlerFunc f = func(rw http.ResponseWriter, req *http.Request) { fmt.Print(p) next.ServeHTTP(rw, req) } return f } type print3 string func (p print3) ServeHTTP(wr http.ResponseWriter, req *http.Request) { fmt.Println(p) } func main() { var s stack.Stack s.Use(print1("ready...")) s.UseWrapper(print2("steady...")) s.UseHandler(print3("go!")) r, _ := http.NewRequest("GET", "/", nil) s.Handler().ServeHTTP(nil, r) }
Output: ready...steady...go!
func (*Stack) Concat ¶
Concat returns a new stack that has the middleware of the current stack concatenated with the middleware of the given stack
func (*Stack) ConcatWithHandler ¶
ConcatWithHandler returns a new stack that has the middleware concatenated with a handler
func (*Stack) HandlerWithContext ¶
func (*Stack) Use ¶
func (s *Stack) Use(mw Middleware) *Stack
Use adds the given middleware to the middleware stack
func (*Stack) UseFunc ¶
func (s *Stack) UseFunc(fn func(wr http.ResponseWriter, req *http.Request, next http.Handler)) *Stack
UseFunc adds the given function to the middleware stack
func (*Stack) UseFuncWithContext ¶
func (s *Stack) UseFuncWithContext(fn func(ctx Contexter, wr http.ResponseWriter, req *http.Request, next http.Handler)) *Stack
UseFuncWithContext adds the given function to the middleware stack
func (*Stack) UseHandler ¶
UseHandler adds the given handler as middleware to the stack. the handler will be called before the next middleware
func (*Stack) UseHandlerFunc ¶
UseHandlerFunc is like UseHandler but for http.HandlerFunc
func (*Stack) UseHandlerFuncWithContext ¶
func (s *Stack) UseHandlerFuncWithContext(fn func(c Contexter, w http.ResponseWriter, r *http.Request)) *Stack
UseHandlerFuncWithContext adds the given function as middleware to the stack. the handler will be called before the next middleware
func (*Stack) UseHandlerWithContext ¶
func (s *Stack) UseHandlerWithContext(mw ContextHandler) *Stack
UseHandlerWithContext adds the given context handler as middleware to the stack. the handler will be called before the next middleware
func (*Stack) UseWithContext ¶
func (s *Stack) UseWithContext(mw ContextMiddleware) *Stack
UseWithContext adds the context middleware to the middleware stack
func (*Stack) UseWrapper ¶
UseWrapper adds the given wrapper to the middleware stack
func (*Stack) UseWrapperFunc ¶
UseWrapperFunc adds the given function to the middleware stack
func (*Stack) WrapFuncWithContext ¶
func (*Stack) WrapWithContext ¶
func (s *Stack) WrapWithContext(app ContextHandler) http.Handler
WrapWithContext wraps the stack around the given app and returns a handler to run the stack that adds context to the http.ResponseWriter. It should be used instead of Wrap for the outermost stack and only there
type TransactionContexter ¶
type TransactionContexter interface { // Set the given Recoverer, replaces the value of the same type // Set may NOT be run on the same TransactionContexter concurrently Set(Recoverer) // Get a given Recoverer. If there is a Recoverer of this type // inside the Contexter, the given Recoverers Recover method is called with the stored value and true is returned. // If no Recoverer of the same type could be found, false is returned // Get may NOT be run on the same TransactionContexter concurrently Get(Recoverer) (has bool) // Del deletes a value of the given type. // Del may NOT be run on the same TransactionContexter concurrently Del(Recoverer) }
TransactionContexter stores and retrieves per request data via a hidden Contexter. It is meant to be used in the Transaction method of a Contexter. Only one TransactionContexter might be used at the same time for the same Contexter. No method of a TransactionContexter might be used concurrently
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package adapter_martini is an adapter for martini middleware to be used with github.com/go-on/stack.
|
Package adapter_martini is an adapter for martini middleware to be used with github.com/go-on/stack. |
Package adapter_negroni is an adapter for negroni middleware to be used with github.com/go-on/stack.
|
Package adapter_negroni is an adapter for negroni middleware to be used with github.com/go-on/stack. |
Package mw provides middleware for the github.com/go-on/stack package
|
Package mw provides middleware for the github.com/go-on/stack package |
Package responsewriter provides some ResponseWriter wrappers that help with development of middleware and also support context sharing via embedding of a stack.Contexter if it is available.
|
Package responsewriter provides some ResponseWriter wrappers that help with development of middleware and also support context sharing via embedding of a stack.Contexter if it is available. |
Package rest provides a simple and opinionated rest rest Principles 1.
|
Package rest provides a simple and opinionated rest rest Principles 1. |
third-party
|
|
stackhttpauth
Package stackhttpauth provides wrappers based on the github.com/abbot/go-http-auth package.
|
Package stackhttpauth provides wrappers based on the github.com/abbot/go-http-auth package. |
stacknosurf
Package stacknosurf provides wrappers based on the github.com/justinas/nosurf package.
|
Package stacknosurf provides wrappers based on the github.com/justinas/nosurf package. |
stacksession
Package stacksession provides wrappers based on the github.com/gorilla/sessions.
|
Package stacksession provides wrappers based on the github.com/gorilla/sessions. |