Documentation ¶
Overview ¶
Package srvutil provides abstraction on top http.Server and mux.Router to make composable HTTP servers
Index ¶
- Constants
- Variables
- func BuildContext(r *http.Request) (context.Context, string)
- func EnvVarHeaderMiddleware(vars map[string]string) func(http.Handler) http.Handler
- func LogErrorBody(statusCode int) bool
- func NewRequestMetricsMiddleware(c *RequestMetricsMiddlewareConfig) func(http.Handler) http.Handler
- func RealIPMiddleware() func(http.Handler) http.Handler
- func RequestContextMiddleware(next http.Handler) http.Handler
- func SecurityHeaderMiddleware(options ...SecurityHeaderOption) func(http.Handler) http.Handler
- type BodyLogPredicateFunc
- type DefaultRequestObserver
- type HTTPRecorder
- type InlineServlet
- type RequestMetricsMiddlewareConfig
- type RequestObserver
- type SecurityHeaderOption
- type Server
- type ServerFactory
- type Servlet
Examples ¶
Constants ¶
const ( UserEmailHeaderKey = "x-galaxy-user-email" UserEmailKey = "email" UUIDHeaderKey = "x-request-id" PathKey = "path" RouteKey = "route" )
const RealIPHeaderKey = "X-Real-IP"
Variables ¶
var RequestMetricsMiddleware = NewRequestMetricsMiddleware(&RequestMetricsMiddlewareConfig{})
RequestMetricsMiddleware is here for backwards compatibility.
Functions ¶
func EnvVarHeaderMiddleware ¶
EnvVarHeaderMiddleware will expose environment variables as HTTP response headers. It can be used with github.com/gorilla/mux:Router.Use or wrapping a Handler.
Example ¶
package main import ( "log" "os" "github.com/gorilla/mux" "github.com/Shopify/goose/srvutil" ) func main() { if os.Getenv("HOSTNAME") == "" { // Not all systems set the HOSTNAME env var hostname, err := os.Hostname() if err != nil { log.Fatal(err) } err = os.Setenv("HOSTNAME", hostname) if err != nil { log.Fatal(err) } } r := mux.NewRouter() r.Use(srvutil.EnvVarHeaderMiddleware(map[string]string{ "HOSTNAME": "X-Hostname", })) }
Output:
func LogErrorBody ¶
func NewRequestMetricsMiddleware ¶
func NewRequestMetricsMiddleware(c *RequestMetricsMiddlewareConfig) func(http.Handler) http.Handler
NewRequestMetricsMiddleware records the time taken to serve a request, and logs request and response data. Example tags: statusClass:2xx, statusCode:200 Should be added as a middleware after RequestContextMiddleware to benefit from its tags
func RealIPMiddleware ¶
Example ¶
package main import ( "github.com/gorilla/mux" "github.com/Shopify/goose/srvutil" ) func main() { r := mux.NewRouter() r.Use(srvutil.RealIPMiddleware()) }
Output:
func RequestContextMiddleware ¶
RequestContextMiddleware can be used with github.com/gorilla/mux:Router.Use or wrapping a Handler
func SecurityHeaderMiddleware ¶
func SecurityHeaderMiddleware(options ...SecurityHeaderOption) func(http.Handler) http.Handler
SecurityHeaderMiddleware set default security headers.
Types ¶
type BodyLogPredicateFunc ¶
type DefaultRequestObserver ¶
type DefaultRequestObserver struct{}
func (*DefaultRequestObserver) AfterRequest ¶
func (o *DefaultRequestObserver) AfterRequest(r *http.Request, recorder HTTPRecorder, requestDuration time.Duration)
func (*DefaultRequestObserver) BeforeRequest ¶
func (o *DefaultRequestObserver) BeforeRequest(r *http.Request)
type HTTPRecorder ¶
type HTTPRecorder interface { http.ResponseWriter StatusCode() int ResponseBody() *string }
type InlineServlet ¶
func (InlineServlet) RegisterRouting ¶
func (m InlineServlet) RegisterRouting(r *mux.Router)
type RequestMetricsMiddlewareConfig ¶
type RequestMetricsMiddlewareConfig struct { BodyLogPredicate BodyLogPredicateFunc Observer RequestObserver }
type RequestObserver ¶
type SecurityHeaderOption ¶
type Server ¶
Server wraps an http.Server to make it runnable and stoppable If its tomb dies, the server will be stopped
func NewServer ¶
Example ¶
tb := &tomb.Tomb{} sl := FuncServlet("/hello/{name}", func(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] fmt.Fprintf(w, "hello %s", name) }) sl = UseServlet(sl, // Should be first to properly add tags and logging fields to the context RequestContextMiddleware, NewRequestMetricsMiddleware(&RequestMetricsMiddlewareConfig{BodyLogPredicate: LogErrorBody}), safely.Middleware, ) s := NewServer(tb, "127.0.0.1:0", sl) defer s.Tomb().Kill(nil) safely.Run(s) u := httpScheme + s.Addr().String() + "/hello/world" res, _ := http.Get(u) io.Copy(os.Stdout, res.Body)
Output: hello world
func NewServerFromFactory ¶
func NewServerFromFactory(t *tomb.Tomb, servlet Servlet, factory ServerFactory) Server
type Servlet ¶
Servlet represents a component that can handle HTTP requests It it responsible for registering on the Router.
Simple Servlets can be created with FuncServlet or HandlerServlet, but a common pattern is to have a complex struct that will initialize dependencies.
Servlets can also be modified and modified using PrefixServlet, UseServlet, and CombineServlets.
See examples.
func CombineServlets ¶
CombineServlets combines all Servlets into one, without other modifications. Great for splitting the dependency managements into smaller servlets.
func FuncServlet ¶
func FuncServlet(path string, handler http.HandlerFunc) Servlet
FuncServlet creates a Servlet from a function.
func HandlerServlet ¶
HandlerServlet creates a Servlet from a Handler, which implements ServeHTTP.
Example ¶
// Actually create a database connection var conn dbConn statsServlet := NewStatsPage(conn) // Apply a middleware to a whole servlet. var authMiddleware mux.MiddlewareFunc statsServlet = UseServlet(statsServlet, authMiddleware) // Register a whole Servlet under a path prefix. statsServlet = PrefixServlet(statsServlet, "/debug") // Combine all servlets together (if multiple) servlet := CombineServlets( // NewHomePage(conn), statsServlet, ) t := &tomb.Tomb{} server := NewServer(t, "127.0.0.1:80", servlet) safely.Run(server)
Output:
func PrefixServlet ¶
PrefixServlet registers a whole Servlet under a path prefix.
func UseServlet ¶
func UseServlet(s Servlet, mwf ...mux.MiddlewareFunc) Servlet
UseServlet applies a middleware to a whole Servlet. Great for applying authentication layers.