httprouter

package module
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Nov 19, 2019 License: BSD-3-Clause Imports: 7 Imported by: 0

README

Package httprouter

Package httprouter replaces the standard muxer provided by the standard library with a more flexible method of specifying URLs.

This package provides another method of mutliplexing request. A list of regular expressions is registered with a builder. When desired, this list is compiled into a finite state machine that can match requests to a specific target. In additional to providing more flexibility in routing requests, the regular expressions can verify the format of the URLs. Malformed requests return a 404 error.

Install

The package can be installed from the command line using the go tool. There are no dependencies beyond the standard library. Any version of Go should work, but testing only covers version 1.8 and up.

go get gitlab.com/stone.code/httprouter

Getting Started

Package documentation and examples are on godoc.

Contribute

Feedback and PRs welcome. You can also submit an issue.

Go Report Card

Scope

The goals for this project is mainly to providing a replacement for the limited multiplexer provided by the standard library. It also serves to test the unique approach of using regular expressions to building the multiplexer. Otherwise, this package is intended to work with the standard library, and use http.Handler for serving requests.

License

BSD (c) Robert Johnstone

Documentation

Overview

Package httprouter replaces the standard muxer provided by the standard library with a more flexible method of specifying URLs.

In the package net/http, the function ListenAndServe accepts a normal request handler. This interface is called to create content for requests that the server receives. Typically, a special handler is used to multiplex requests. The request multiplexer matches the URL of incoming requests against a list of registered handlers, and then dispatches that request as required.

The multiplexer provided by the standard Go library matches requests by the URLs' prefixes. This is a simple approach, but does not necessarily provide as much functionality as desired.

This package provides another method of mutliplexing request. A list of regular expressions is registered with a builder. When desired, this list is compiled into a finite state machine that can match requests to a specific target. In additional to providing more flexibility in routing requests, the regular expressions can verify the format of the URLs. Malformed requests return a 404 error.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrBuilderIsEmpty indicates that the Builder is empty, and so cannot build a ServeMux.
	ErrBuilderIsEmpty = errors.New("failed to create ServeMux because Builder is empty")
)

Functions

func PathNth

func PathNth(path string, nth int) string

PathNth returns the nth element of the path. If the element is found, it is returned without the leading or trailing slashes.

The first element has an index of zero. If the path has a leading slash, it is ignored. Therefore, the leading elements (element 0) of "/a/b/c" and "a/b/c" are both "a".

The last element in the path may contain a trailing slash, but it is not required. For example, the final elements (element 2) of "/a/b/c/" and "/a/b/c" are both "c".

Example
// An example path in a request
path := "/diary/user/2012-12-25/1"

// breakout the elements
username := PathNth(path, 1)
entrydate := PathNth(path, 2)
entryindex := PathNth(path, 3)

// show the results
fmt.Println("User:", username)
fmt.Println("Entry date:", entrydate)
fmt.Println("Entry index:", entryindex)
Output:

User: user
Entry date: 2012-12-25
Entry index: 1

func UrlNth

func UrlNth(url *url.URL, nth int) string

UrlNth returns the nth element of the URL's path. Refer to PathNth for more details.

Example
// An example path in a request
url, err := url.Parse("http://localhost/diary/user/2012-12-25/1")
if err != nil {
	panic(err)
}

// breakout the elements
username := UrlNth(url, 1)
entrydate := UrlNth(url, 2)
entryindex := UrlNth(url, 3)

// show the results
fmt.Println("User:", username)
fmt.Println("Entry date:", entrydate)
fmt.Println("Entry index:", entryindex)
Output:

User: user
Entry date: 2012-12-25
Entry index: 1

Types

type Builder

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

A Builder maintains a list of regular expressions, and the HTTP handlers that should be executed when one of those expressions matches the URL of an HTTP request. Taken together, the regular expressions describe the routing of requests to their handlers.

The Builder is not used directly. Instead, once the expressions have all been added, users should call the method NewServeMux to create a request multiplexer that can be used to serve HTTP requests.

func NewBuilder

func NewBuilder() *Builder

NewBuilder initializes a new Builder.

Example
// Create a builder to start construction of our routing policy.
b := NewBuilder()

// The login page will be special.  A get method will return an HTML
// login page, but we'll post our credentials to login.
b.MustHandleFunc("/login", GetMethod, func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<html><body>A login page.</body></html>")
})
b.MustHandleFunc("/login", PostMethod, func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<html><body>You're logged in!</body></html>")
})
// Our content will be organized by date, which will be part
// of our URL.
b.MustHandleFunc("/content/\\d{4}-\\d{2}-\\d{2}/?", GetMethod, func(w http.ResponseWriter, r *http.Request) {
	date := r.URL.Path[9:19] // A string of the form YYYY-MM-DD
	fmt.Fprintf(w, "<html><body>Some content for %s.</body></html>", date)
})

// Construct a ServeMux.  This will construct the DFA based on the
// requested patterns that can be used for routing.
mux, err := b.NewServeMux()
if err != nil {
	// If you have conflicting routes, you will find out here
	panic(err)
}

// Start serving content.
_ = http.ListenAndServe(":8000", mux)
Output:

Example (Conflict)
// Create a new builder to start construction of our routing policy.
b := NewBuilder()

// Our first route will be a fixed login page.
b.MustHandleFunc("/login", GetMethod, func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<html><body>A login page.</body></html>")
})
// Our second route will match all routes that start with "log".
b.MustHandleFunc("/log.+", GetMethod, func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<html><body>A login page.</body></html>")
})

// Construct a ServeMux.  Unfortunately, ou routes conflict since there are
// paths that match multiple routes.
_, err := b.NewServeMux()
fmt.Println("error:", err)
Output:

error: httprouter: conflict in an accept state: "/log.+" and "/login"

func (*Builder) Handle

func (n *Builder) Handle(pattern string, method Method, requestHandler http.Handler) error

Handle registers the handler for the given method and the given regular expression. If the regular expression already exists, the handlers for those methods specified by the parameter method are overwritten.

The pattern is a regular expression conforming to the syntax of the package regexp. The expression must be valid. If it fails to compile, this method will panic.

func (*Builder) HandleFunc

func (n *Builder) HandleFunc(pattern string, method Method, handler func(http.ResponseWriter, *http.Request)) error

HandleFunc registers the handler function for the given method and the given regular expression. See the method Handle for futher details.

func (*Builder) MustHandle

func (n *Builder) MustHandle(pattern string, method Method, requestHandler http.Handler)

MustHandle is like the method Handle, but panics if the pattern cannot be parsed. It simplifies safe initialization of variables holding known regular expressions.

func (*Builder) MustHandleFunc

func (n *Builder) MustHandleFunc(pattern string, method Method, handler func(http.ResponseWriter, *http.Request))

MustHandleFunc is like the method HandleFunc, but panics if the pattern cannot be parsed. It simplifies safe initialization of variables holding known regular expressions.

func (*Builder) NewServeMux

func (n *Builder) NewServeMux() (mux *ServeMux, err error)

NewServeMux compiles the list of regular expressions into a machine, and returns a new request multiplexer that will dispatch HTTP requests.

type ErrAcceptConflict

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

An ErrAcceptConflict will be returned when building the state machine if it is possible for an URL to match multiple handlers. The regular expressions must match distinct sets of string.

func (ErrAcceptConflict) Error

func (e ErrAcceptConflict) Error() string

type ErrorHandler

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

A ErrorHandler writes an error message to the HTTP response with the error code and the associated error text. Users should initialize the structure with a standard HTTP error code.

func NewErrorHandler

func NewErrorHandler(code int) *ErrorHandler

NewErrorHandler creates a new ErrorHandler.

func (*ErrorHandler) ServeHTTP

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

ServeHTTP write reply headers for the error code, and creates a short response with text that describes the error.

type Method

type Method int

A Method specifies the method for an HTTP request. Note that when used to specify the methods for a handler, the values can be combined.

const (
	GetMethod Method = (1 << iota)
	PostMethod
	PutMethod
	DeleteMethod
	AllMethods Method = GetMethod | PostMethod | PutMethod | DeleteMethod
)

The following constants are used to set which HTTP methods a handler will respond to.

type ServeMux

type ServeMux struct {

	// NotFoundHandler is called to write error messages for 404 code
	// errors.
	NotFoundHandler http.Handler
	// MethodNotAllowedHandler is called to write error messages for 405
	// code errors.
	MethodNotAllowedHandler http.Handler
	// contains filtered or unexported fields
}

A ServeMux is a request multiplexer. Incoming HTTP requests are matches against a list of regular expressions, and the request is dispatched to the appropriate handler.

The multiplexer contains two special handler for handling errors. These are otherwise normal handlers, but users should not that the HTTP headers have already been sent when they are called.

func (*ServeMux) ServeHTTP

func (m *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request)

Jump to

Keyboard shortcuts

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