httpmux

package module
v0.0.0-...-9e95425 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2016 License: BSD-3-Clause Imports: 6 Imported by: 46

README

httpmux

GoDoc GoReportCard

httpmux is an http request multiplexer for Go built on top of the popular httprouter, with modern features.

The main motivation is to bring http handlers back to their original Handler interface as defined by net/http but leverage the speed and features of httprouter, such as dispatching handlers by method and handling HTTP 405 automatically.

Another important aspect of httpmux is that it provides request context for arbitrary data, such as httprouter's URL parameters. Seasoned gophers migth immediately think this is an overlap of gorilla's context package, however, their implementation rely on global variables and mutexes that can cause contention on heavily loaded systems. We use a different approach, which was stolen from httpway, that hijacks the http.Request's Body field and replace it with an object that is an io.ReadCloser but also carries a net/context object. This works well for middleware that wants to store arbitrary data in the request, serial, and once it hits your handler, the context can be passed around to goroutines. It is automatically cleared at the end of the middleware chain.

There's been discussions for adding net/context to the standard library but most options require changing or creating a new interface and/or function signature for http handlers. In httpmux we remain close to net/http aiming at being more pluggable and composable with existing code in the wild, and if the Request type ends up getting a Context field, will be an easy change in httpmux.

To make contexts more useful, httpmux provides the ability to register and chain wrapper handlers, middleware. Our implementation is based on blogs and especially chi, but much smaller.

Last but not least, httpmux offers two more features for improving composability. First, is to configure a global prefix for all handlers in the multiplexer. This is for cases when you have to run your API behind a proxy, or mixed with other services, and have to be able to parse and understand the prefix in your handlers. Second, is to allow subtrees like gin's groups, but in a more composable way. Think of cases where your code is an independent package that provides an http handler, that is tested and run isolated, but can be added to a larger API at run time. In chi, this is equivalent to the Mount function in their router.

Documentation

Overview

Package httpmux provides an http request multiplexer.

Example
package main

import (
	"fmt"
	"io"
	"net/http"

	"golang.org/x/net/context"

	"github.com/go-web/httpmux"
)

func authHandler(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		u, p, ok := r.BasicAuth()
		if ok && u == "foobar" && p == "foobared" {
			ctx := httpmux.Context(r)
			ctx = context.WithValue(ctx, "user", u)
			httpmux.SetContext(ctx, r)
			next(w, r)
			return
		}
		w.Header().Set("WWW-Authenticate", `realm="restricted"`)
		w.WriteHeader(http.StatusUnauthorized)
	}
}

func main() {
	// curl -i localhost:8080
	// curl -i -XPOST --basic -u foobar:foobared localhost:8080/auth/login
	root := httpmux.New()
	root.GET("/", func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "hello, world\n")
	})
	auth := httpmux.New()
	{
		auth.UseFunc(authHandler)
		auth.POST("/login", func(w http.ResponseWriter, r *http.Request) {
			u := httpmux.Context(r).Value("user")
			fmt.Fprintln(w, "hello,", u)
		})
	}
	root.Append("/auth", auth)
	http.ListenAndServe(":8080", root)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultConfig = Config{
	RedirectTrailingSlash:  true,
	RedirectFixedPath:      true,
	HandleMethodNotAllowed: true,
}

DefaultConfig is the default Handler configuration used by New.

Functions

func Context

func Context(r *http.Request) context.Context

Context returns the context from the given request, or a new context.Background if it doesn't exist.

func Params

func Params(r *http.Request) httprouter.Params

Params returns the httprouter.Params from the request context.

func SetContext

func SetContext(ctx context.Context, r *http.Request)

SetContext updates the given context in the request if the request has been previously instrumented by httpmux.

Types

type Config

type Config struct {
	// Prefix is the prefix for all paths in the handler.
	// Empty value is allowed and defaults to "/".
	Prefix string

	// Middleware is the initial list of middlewares to be
	// automatically assigned to all handlers.
	//
	// Note that middleware for the configurable handlers
	// such as NotFound and MethodNotAllowed can only be
	// configured here.
	Middleware []Middleware

	// Enables automatic redirection if the current route can't be matched but a
	// handler for the path with (without) the trailing slash exists.
	// For example if /foo/ is requested but a route only exists for /foo, the
	// client is redirected to /foo with http status code 301 for GET requests
	// and 307 for all other request methods.
	RedirectTrailingSlash bool

	// If enabled, the router tries to fix the current request path, if no
	// handle is registered for it.
	// First superfluous path elements like ../ or // are removed.
	// Afterwards the router does a case-insensitive lookup of the cleaned path.
	// If a handle can be found for this route, the router makes a redirection
	// to the corrected path with status code 301 for GET requests and 307 for
	// all other request methods.
	// For example /FOO and /..//Foo could be redirected to /foo.
	// RedirectTrailingSlash is independent of this option.
	RedirectFixedPath bool

	// If enabled, the router checks if another method is allowed for the
	// current route, if the current request can not be routed.
	// If this is the case, the request is answered with 'Method Not Allowed'
	// and HTTP status code 405.
	// If no other Method is allowed, the request is delegated to the NotFound
	// handler.
	HandleMethodNotAllowed bool

	// Configurable http.Handler which is called when no matching route is
	// found. If it is not set, http.NotFound is used.
	NotFound http.Handler

	// Configurable http.Handler which is called when a request
	// cannot be routed and HandleMethodNotAllowed is true.
	// If it is not set, http.Error with http.StatusMethodNotAllowed is used.
	MethodNotAllowed http.Handler

	// Function to handle panics recovered from http handlers.
	// It should be used to generate a error page and return the http error code
	// 500 (Internal Server Error).
	// The handler can be used to keep your server from crashing because of
	// unrecovered panics.
	//
	// No middleware is applied to the PanicHandler.
	PanicHandler func(http.ResponseWriter, *http.Request, interface{})
}

Config is the Handler configuration.

func (*Config) Use

func (c *Config) Use(mw ...Middleware)

Use appends f to the list of middlewares.

func (*Config) UseFunc

func (c *Config) UseFunc(mw ...MiddlewareFunc)

UseFunc appends f to the list of middlewares.

type ConfigOption

type ConfigOption interface {
	Set(c *Config)
}

ConfigOption is the interface for updating config options.

func WithHandleMethodNotAllowed

func WithHandleMethodNotAllowed(v bool) ConfigOption

WithHandleMethodNotAllowed returns a ConfigOption that uptates the Config.

func WithMethodNotAllowed

func WithMethodNotAllowed(f http.Handler) ConfigOption

WithMethodNotAllowed returns a ConfigOption that uptates the Config.

func WithMiddleware

func WithMiddleware(mw ...Middleware) ConfigOption

WithMiddleware returns a ConfigOption that uptates the Config.

func WithMiddlewareFunc

func WithMiddlewareFunc(mw ...MiddlewareFunc) ConfigOption

WithMiddlewareFunc returns a ConfigOption that uptates the Config.

func WithNotFound

func WithNotFound(f http.Handler) ConfigOption

WithNotFound returns a ConfigOption that uptates the Config.

func WithPanicHandler

func WithPanicHandler(f func(http.ResponseWriter, *http.Request, interface{})) ConfigOption

WithPanicHandler returns a ConfigOption that uptates the Config.

func WithPrefix

func WithPrefix(prefix string) ConfigOption

WithPrefix returns a ConfigOption that uptates the Config.

func WithRedirectFixedPath

func WithRedirectFixedPath(v bool) ConfigOption

WithRedirectFixedPath returns a ConfigOption that uptates the Config.

func WithRedirectTrailingSlash

func WithRedirectTrailingSlash(v bool) ConfigOption

WithRedirectTrailingSlash returns a ConfigOption that uptates the Config.

type ConfigOptionFunc

type ConfigOptionFunc func(c *Config)

ConfigOptionFunc is an adapter for config option functions.

func (ConfigOptionFunc) Set

func (f ConfigOptionFunc) Set(c *Config)

Set implements the ConfigOption interface.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler is the http request multiplexer backed by httprouter.Router.

func New

func New(opts ...ConfigOption) *Handler

New creates and initializes a new Handler using default settings and the given options.

func NewHandler

func NewHandler(c *Config) *Handler

NewHandler creates and initializes a new Handler with the given config.

func (*Handler) Append

func (h *Handler) Append(pattern string, subtree *Handler)

Append appends a handler to this handler, under the given pattern. All middleware from the root tree propagates to the subtree. However, the subtree's configuration such as prefix and fallback handlers, like NotFound and MethodNotAllowed, are ignored by the root tree in favor of its own configuration.

func (*Handler) DELETE

func (h *Handler) DELETE(pattern string, f http.HandlerFunc)

DELETE is a shortcut for mux.Handle("DELETE", path, handle)

func (*Handler) GET

func (h *Handler) GET(pattern string, f http.HandlerFunc)

GET is a shortcut for mux.Handle("GET", path, handle)

func (*Handler) HEAD

func (h *Handler) HEAD(pattern string, f http.HandlerFunc)

HEAD is a shortcut for mux.Handle("HEAD", path, handle)

func (*Handler) Handle

func (h *Handler) Handle(method, pattern string, f http.Handler)

Handle registers a new request handler with the given method and pattern.

func (*Handler) HandleFunc

func (h *Handler) HandleFunc(method, pattern string, f http.HandlerFunc)

HandleFunc registers a new request handler with the given method and pattern.

func (*Handler) OPTIONS

func (h *Handler) OPTIONS(pattern string, f http.HandlerFunc)

OPTIONS is a shortcut for mux.Handle("OPTIONS", path, handle)

func (*Handler) PATCH

func (h *Handler) PATCH(pattern string, f http.HandlerFunc)

PATCH is a shortcut for mux.Handle("PATCH", path, handle)

func (*Handler) POST

func (h *Handler) POST(pattern string, f http.HandlerFunc)

POST is a shortcut for mux.Handle("POST", path, handle)

func (*Handler) PUT

func (h *Handler) PUT(pattern string, f http.HandlerFunc)

PUT is a shortcut for mux.Handle("PUT", path, handle)

func (*Handler) ServeFiles

func (h *Handler) ServeFiles(pattern string, root http.FileSystem)

ServeFiles serves files from the given file system root.

The pattern must end with "/*filepath" to have files served from the local path /path/to/dir/*filepath.

For example, if root is "/etc" and *filepath is "passwd", the local file "/etc/passwd" is served. Because an http.FileServer is used internally it's possible that http.NotFound is called instead of httpmux's NotFound handler.

To use the operating system's file system implementation, use http.Dir: mux.ServeFiles("/src/*filepath", http.Dir("/var/www")).

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface.

func (*Handler) Use

func (h *Handler) Use(mw ...Middleware)

Use appends the given middlewares to the internal chain.

func (*Handler) UseFunc

func (h *Handler) UseFunc(mw ...MiddlewareFunc)

UseFunc appends the given middlewares to the internal chain.

type Middleware

type Middleware func(next http.Handler) http.Handler

Middleware is an http handler that can optionally call the next handler in the chain based on the request or any other conditions.

type MiddlewareFunc

type MiddlewareFunc func(next http.HandlerFunc) http.HandlerFunc

MiddlewareFunc is an adapter for Middleware that takes handler functions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL