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 ResponseWriter
- type Stack
- func (s *Stack) Concat(st *Stack) *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 Swapper
- 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 Swapper, replaces the value of the same type
// Set may be run on the same Contexter concurrently
Set(Swapper)
// Get a given Swapper. If there is a Swapper of this type
// inside the Contexter, the given Swappers Swap method is called with the stored value and true is returned.
// If no Swapper of the same type could be found, false is returned
// Get may be run on the same Contexter concurrently
Get(Swapper) (has bool)
// Del deletes a value of the given type.
// Del may be run on the same Contexter concurrently
Del(Swapper)
// 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
// Swap replaces the value of m with the value of val
func (m *Val) Swap(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 ResponseWriter ¶
type ResponseWriter struct {
http.ResponseWriter
}
ResponseWriter is used to store the underlying http.ResponseWriter inside the Contexter
func (*ResponseWriter) Swap ¶
func (rw *ResponseWriter) Swap(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) 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 Swapper ¶
type Swapper interface {
// Swap must be defined on a pointer
// and changes the the value of the pointer
// to the value the replacement is pointing to
Swap(replacement interface{})
}
Swapper may swap between given value and the value inside a request context
type TransactionContexter ¶
type TransactionContexter interface {
// Set the given Swapper, replaces the value of the same type
// Set may NOT be run on the same TransactionContexter concurrently
Set(Swapper)
// Get a given Swapper. If there is a Swapper of this type
// inside the Contexter, the given Swappers Swap method is called with the stored value and true is returned.
// If no Swapper of the same type could be found, false is returned
// Get may NOT be run on the same TransactionContexter concurrently
Get(Swapper) (has bool)
// Del deletes a value of the given type.
// Del may NOT be run on the same TransactionContexter concurrently
Del(Swapper)
}
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. |
|
example
command
|
|
|
example
command
|
|
|
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. |