Documentation ¶
Overview ¶
Package router provides an HTTP router.
It wraps around julienschmidt/httprouter adding support for middlewares and subrouters.
Example (CreateServer) ¶
Example_createServer demonstrates creating an HTTP server using the router package.
package main import ( "context" "fmt" "io" "math/rand" "net/http" "net/http/httptest" "go.chromium.org/luci/server/router" ) func Logger(c *router.Context, next router.Handler) { fmt.Println(c.Request.URL) next(c) } func AuthCheck(c *router.Context, next router.Handler) { var authenticated bool if !authenticated { c.Writer.WriteHeader(http.StatusUnauthorized) c.Writer.Write([]byte("Authentication failed")) return } next(c) } func GenerateSecret(c *router.Context, next router.Handler) { c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), "secret", rand.Int())) next(c) } func makeRequest(client *http.Client, url string) string { res, err := client.Get(url + "/") if err != nil { panic(err) } defer res.Body.Close() p, err := io.ReadAll(res.Body) if err != nil { panic(err) } if len(p) == 0 { return fmt.Sprintf("%d", res.StatusCode) } return fmt.Sprintf("%d %s", res.StatusCode, p) } func makeRequests(url string) { c := &http.Client{} fmt.Println(makeRequest(c, url+"/hello")) fmt.Println(makeRequest(c, url+"/hello/darknessmyoldfriend")) fmt.Println(makeRequest(c, url+"/authenticated/secret")) } // Example_createServer demonstrates creating an HTTP server using the router // package. func main() { r := router.New() r.Use(router.NewMiddlewareChain(Logger)) r.GET("/hello", nil, func(c *router.Context) { fmt.Fprintf(c.Writer, "Hello") }) r.GET("/hello/:name", nil, func(c *router.Context) { fmt.Fprintf(c.Writer, "Hello %s", c.Params.ByName("name")) }) auth := r.Subrouter("authenticated") auth.Use(router.NewMiddlewareChain(AuthCheck)) auth.GET("/secret", router.NewMiddlewareChain(GenerateSecret), func(c *router.Context) { fmt.Fprintf(c.Writer, "secret: %d", c.Request.Context().Value("secret")) }) server := httptest.NewServer(r) defer server.Close() makeRequests(server.URL) }
Output: /hello 200 Hello /hello/darknessmyoldfriend 200 Hello darknessmyoldfriend /authenticated/secret 401 Authentication failed
Index ¶
- func RunMiddleware(c *Context, mc MiddlewareChain, h Handler)
- type Context
- type Handler
- type Middleware
- type MiddlewareChain
- type Router
- func (r *Router) DELETE(path string, mc MiddlewareChain, h Handler)
- func (r *Router) GET(path string, mc MiddlewareChain, h Handler)
- func (r *Router) HEAD(path string, mc MiddlewareChain, h Handler)
- func (r *Router) Handle(method, path string, mc MiddlewareChain, h Handler)
- func (r *Router) NotFound(mc MiddlewareChain, h Handler)
- func (r *Router) OPTIONS(path string, mc MiddlewareChain, h Handler)
- func (r *Router) PATCH(path string, mc MiddlewareChain, h Handler)
- func (r *Router) POST(path string, mc MiddlewareChain, h Handler)
- func (r *Router) PUT(path string, mc MiddlewareChain, h Handler)
- func (r *Router) Params(method, path string) (httprouter.Params, bool)
- func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request)
- func (r *Router) Static(prefix string, mc MiddlewareChain, root http.FileSystem)
- func (r *Router) Subrouter(relativePath string) *Router
- func (r *Router) Use(mc MiddlewareChain)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RunMiddleware ¶
func RunMiddleware(c *Context, mc MiddlewareChain, h Handler)
RunMiddleware executes the middleware chain and the handler with the given initial context. Useful to execute a chain of functions in tests.
Types ¶
type Context ¶
type Context struct { Writer http.ResponseWriter Request *http.Request Params httprouter.Params HandlerPath string // the path with which the handler was registered }
Context contains the context, response writer, request, and params shared across Middleware and Handler functions.
TODO: Remove Context in favor of Request.Context().
type Middleware ¶
Middleware does some pre/post processing of a request.
It is a function that accepts a context carrying an http.Request and an http.ResponseWriter and the `next` function. `next` is either the final request handler or a next link in the middleware chain.
A middleware implementation must obey the following rules:
- Middleware *must* call `next` if it has not written the response itself.
- Middleware *must not* call `next` if it has written the response.
- Middleware *may* modify the context in-place before calling `next`.
Note that writing the response after `next` is called is undefined behavior. It may or may not work depending on what exact happened down the chain.
type MiddlewareChain ¶
type MiddlewareChain []Middleware
MiddlewareChain is an ordered collection of Middleware.
The first middleware is the outermost, i.e. it will be called first when processing a request.
func NewMiddlewareChain ¶
func NewMiddlewareChain(mw ...Middleware) MiddlewareChain
NewMiddlewareChain creates a new MiddlewareChain with the supplied Middleware entries.
func (MiddlewareChain) Extend ¶
func (mc MiddlewareChain) Extend(mw ...Middleware) MiddlewareChain
Extend returns a new MiddlewareChain with the supplied Middleware appended to the end.
type Router ¶
type Router struct { // BasePath is the root path to mount routes under. BasePath string // contains filtered or unexported fields }
Router is the main type for the package. To create a Router, use New.
func (*Router) DELETE ¶
func (r *Router) DELETE(path string, mc MiddlewareChain, h Handler)
DELETE is a shortcut for router.Handle("DELETE", path, mc, h).
func (*Router) GET ¶
func (r *Router) GET(path string, mc MiddlewareChain, h Handler)
GET is a shortcut for router.Handle("GET", path, mc, h).
func (*Router) HEAD ¶
func (r *Router) HEAD(path string, mc MiddlewareChain, h Handler)
HEAD is a shortcut for router.Handle("HEAD", path, mc, h).
func (*Router) Handle ¶
func (r *Router) Handle(method, path string, mc MiddlewareChain, h Handler)
Handle registers a middleware chain and a handler for the given method and path. len(mc)==0 is allowed. See https://godoc.org/github.com/julienschmidt/httprouter for documentation on how the path may be formatted.
func (*Router) NotFound ¶
func (r *Router) NotFound(mc MiddlewareChain, h Handler)
NotFound sets the handler to be called when no matching route is found.
func (*Router) OPTIONS ¶
func (r *Router) OPTIONS(path string, mc MiddlewareChain, h Handler)
OPTIONS is a shortcut for router.Handle("OPTIONS", path, mc, h).
func (*Router) PATCH ¶
func (r *Router) PATCH(path string, mc MiddlewareChain, h Handler)
PATCH is a shortcut for router.Handle("PATCH", path, mc, h).
func (*Router) POST ¶
func (r *Router) POST(path string, mc MiddlewareChain, h Handler)
POST is a shortcut for router.Handle("POST", path, mc, h).
func (*Router) PUT ¶
func (r *Router) PUT(path string, mc MiddlewareChain, h Handler)
PUT is a shortcut for router.Handle("PUT", path, mc, h).
func (*Router) Params ¶
func (r *Router) Params(method, path string) (httprouter.Params, bool)
Params parases the httprouter.Params from the supplied method and path.
If nothing is registered for method/path, Params will return false.
func (*Router) ServeHTTP ¶
func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request)
ServeHTTP makes Router implement the http.Handler interface.
func (*Router) Static ¶
func (r *Router) Static(prefix string, mc MiddlewareChain, root http.FileSystem)
Static installs handlers that serve static files.
func (*Router) Subrouter ¶
Subrouter creates a new router with an updated base path. The new router copies middleware and configuration from the router it derives from.
func (*Router) Use ¶
func (r *Router) Use(mc MiddlewareChain)
Use adds middleware chains to the group. The added middleware applies to all handlers registered on the router and to all handlers registered on routers that may be derived from the router (using Subrouter).