mux

package module
v0.0.0-...-36d5619 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2019 License: LGPL-3.0 Imports: 8 Imported by: 0

README

gitlab.com/gopherburrow/mux

GoDoc pipeline status coverage report

Gopher Burrow Logo

gitlab.com/gopherburrow/mux Implements an URL mutiplexing matcher and dispatcher. It receives an HTTP request then it compares it with a pre-configured table and dispatch it to an http.Handler.

It meant to be simple and small and is made to fit perfectly in a multitenancy web project, where only an HTTP method and an absolute, complete and canonical URL is needed to match a request and dispatch it to a Handler.

For a general use mux, I recommend the amazing Gorilla Webkit Mux (https://github.com/gorilla/mux) that has much more advanced mutiplexing/routing/dispatch capabilities. Specifically, I do not use it in Riot Emergence because it is a bit overkill for my project needs.

Features:

  • Complete URL matching using only a HTTP Method (GET, POST...) and a simple URL pattern;
  • Capable of matching based on the protocol scheme (http, https...), host, port, path, query parameters names and values;
  • Capable of extracting path parameters values.

Table of Contents


Install

Within a Go workspace:

go get -u gitlab.com/gopherburrow/mux

Usage

Import:

import (
	"gitlab.com/gopherburrow/mux"
)

Create a Mux:

m = &mux.Mux{}

Register some handlers:

m.Handle(http.MethodGet, "http://localhost:8080/{path}", YourHandler)
//or
m.HandleFunc(http.MethodGet, "http://localhost:8080/{path}", YourHandlerFunc)

Start a server passing a Mux as a handler:

log.Fatal(http.ListenAndServe(":8080", m))

Extract some path variables:

v := m.PathVars(r)
path := v["path"]

Example

Write and build the folowing lines:

package main

import (
	"fmt"
	"log"
	"net/http"

	"gitlab.com/gopherburrow/mux"
)

var m *mux.Mux

func main() {
	m = &mux.Mux{}
	// Mux routes consist of a HTTP method, an URL and a handler function.
	m.HandleFunc(http.MethodGet, "http://localhost:8080/fixedpath/{dynamicPath}?has-parameter&fixed-parameter=fixed-value", YourHandler)

	// Bind to a port and pass to mux
	log.Fatal(http.ListenAndServe(":8080", m))
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
	v := m.PathVars(r) // ... map[string]string returned
	fmt.Fprint(w, "Riot Emergence Mux Hello World "+v["dynamicPath"])
}

And load on the browser:

http://localhost:8080/fixedpath/Hello%20World?has-parameter&fixed-parameter=fixed-value

Documentation

Overview

Package mux contains an URL mutiplexing matcher and dispatcher.

It stores a routing table comprised of URL Patterns on one side and a set of `http.Handler` on the other.

And when it receive a HTTP request, matches it against the pre-configured routing table and dispatch it to the apropriate `http.Handler`.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	//ErrHandlerMustBeNotNil is returned by Handle method when the handler parameter is nil.
	ErrHandlerMustBeNotNil = errors.New("mux: Handler must be not nil")
	//ErrMethodMustBeValid is returned by Handle and RemoveHandler methods when the httpMethod parameter is invalid.
	//Valid values are: http.MethodPut, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPost, http.MethodPatch, http.MethodDelete, http.MethodConnect and http.MethodTrace.
	ErrMethodMustBeValid = errors.New("mux: Invalid HTTP method")
	//ErrRequestMustHaveContext is returned by Get method when an context is not found.
	ErrRequestMustHaveContext = errors.New("mux: context not found (request must came from a mux Handler)")
	//ErrRouteMustExist is returned by RemoveHandler method when the route is not found.
	ErrRouteMustExist = errors.New("mux: route not found")
	//ErrRouteMustNotConflict is returned by Handle method when a conflicting route is found.
	ErrRouteMustNotConflict = errors.New("mux: route conflicting with a pre existing route")
	//ErrURLPatternInvalidQueryRoute is returned by Handle and RemoveHandler methods when an invalid query routing is found in urlPattern parameter.
	ErrURLPatternInvalidQueryRoute = errors.New("mux: invalid URL pattern query routing (query parameter presence tests or value tests are mutually exclusive)")
	//ErrURLPatternInvalidPathVar is returned by Handle and RemoveHandler methods when an invalid path variable is found in urlPattern parameter.
	ErrURLPatternInvalidPathVar = errors.New("mux: invalid URL pattern path variables")
	//ErrURLPatternMustBeValid is returned by Handle and RemoveHandler methods when the urlPattern parameter is invalid.
	//Valid schemes are https and http.
	ErrURLPatternMustBeValid = errors.New("mux: invalid URL pattern")
)

Errors returned by methods.

Functions

This section is empty.

Types

type Mux

type Mux struct {
	//NotFoundHandler specifies an optional `http.Handler` when a route match from request is not found.
	//If nil, the Mux will use the default http.NotFound handler.
	NotFoundHandler http.Handler
	// contains filtered or unexported fields
}

Mux implements an URL mutiplexing matcher and dispatcher.

Example
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"

	"gitlab.com/gopherburrow/mux"
)

func main() {
	m := &mux.Mux{}
	m.Handle(http.MethodGet, "http://localhost/{var}/{*}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		w.Header().Set("X-Content-Type-Options", "nosniff")
		mx, err := mux.Get(r)
		if err != nil {
			http.Error(w, "Server Error", http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, "Hello World %q %q\n", mx.PathVars(r)["var"], mx.PathVars(r)["*"])
	}))

	// On real world we would use:
	//  http.ListenAndServe(":8080", m)

	// On tests world we use:
	req := httptest.NewRequest(http.MethodGet, "http://localhost/gopher/burrow/mux", nil)
	rr := httptest.NewRecorder()
	m.ServeHTTP(rr, req)
	fmt.Print(rr.Body.String())

}
Output:

Hello World "gopher" "burrow/mux"

func Get

func Get(r *http.Request) (*Mux, error)

Get retrieves the mux used in dispatch, So it can be used to extract path variables throught PathVars method.

Possible error returns:

• mux.ErrRequestMustHaveContext

func (*Mux) Handle

func (m *Mux) Handle(httpMethod string, urlPattern string, handler http.Handler) error

Handle creates a routing entry in routing table and assigns a `http.Handler` to be dispatched when ServeHTTP receives a request that matches the route.

This method does not allow routes patterns (method+url) conflicts and will return an error.

Parameters

• httpMethod: a string containing a HTTP method (Eg: GET)

• urlPattern: an URL containing necessarily a scheme and host, and optionally a port, a path segments (static or dynamic) and query strings.

Check the `mux.Mux.ServeHTTP` method to check how this urlPattern is compared with the actual `http.Request` being served.

• handler: a `http.Handler` that will be called when the request matches the route.

Variable Paths

Dynamic paths and path variables can be defined using a name inside a pair of open and closed braces on a path segment. Eg: The GET http://localhost/{path-var} route can be matched on a request GET http://localhost/hello-world and the `path-var` variable can be extracted as the value "hello-world" using PathVars method.

Path variables can be also used to match a complete sub path using the keyword {*}. Eg: The GET http://localhost/some-path/{*} will match a request like GET http://localhost/some-path/sub1/sub2 . The PathVar "*" will be valued "sub1/sub2".

Query Strings Routing

Query routing rules uses two types of testing: Presence test (Eg: http://localhost/path?param) and Value test (Eg: http://localhost/path?param=value). Only one type of testing per parameter name is allowed. The tests follow an alfabetic order,

Errors

• mux.ErrHandlerMustBeNotNil

• mux.ErrMethodMustBeValid

• mux.ErrRouteMustNotConflict

• mux.ErrURLPatternInvalidQueryRoute

• mux.ErrURLPatternInvalidPathVar

• mux.ErrURLPatternMustBeValid

func (*Mux) PathValues

func (m *Mux) PathValues(r *http.Request) []string

PathValues extract all the variable path segments values as a slice from a request that was handled by a Mux.

It returns a slice with all variables found in path during the Handle(...) call.

Only path segments can be extracted using PathValues. There is no scheme, host, port or query values extraction mechanisms in Mux, they can be extracted throught the usual methods in the http.Request parameter.

func (*Mux) PathVars

func (m *Mux) PathVars(r *http.Request) map[string]string

PathVars extract all the variable path segments values as a map from a request that was handled by a Mux.

It returns a map with all variables found in path during the Handle(...) call.

Only path segments can be extracted using PathVars. There is no scheme, host, port or query values extraction mechanisms in Mux, they can be extracted throught the usual methods in the http.Request parameter.

func (*Mux) RemoveHandler

func (m *Mux) RemoveHandler(httpMethod, urlPattern string) error

RemoveHandler removes a handler from an existing route.

Errors

• mux.ErrMethodMustBeValid

• mux.ErrRouteMustExist

• mux.ErrURLPatternInvalidQueryRoute

• mux.ErrURLPatternInvalidPathVar

• mux.ErrURLPatternMustBeValid

func (*Mux) ServeHTTP

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

ServeHTTP dispatches requests according to routing rules to pre configured `http.Handler` added by `Handle` or `HandleFunc` methods.

This methods implies that the requests are being served directly, not behind a reverse proxy. The values are extracted from *http.Request in the following way:

• The scheme value (http or https) is based in the `*http.Request.TLS` field. If it is not `nil` the "https" value will be used, otherwise "http" will be used.

• The host is extracted from `*http.Request.Host`.

If the requests are being served behind a reverse proxy, adjust the values before handler is called. This is achieved normally by creating a intermediate delegating http.Handler that translate the requests.

func (*Mux) String

func (m *Mux) String() string

String shows a sorted list of registered routes.

Jump to

Keyboard shortcuts

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