gogomux

package module
v0.0.0-...-bdc2a62 Latest Latest
Warning

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

Go to latest
Published: May 12, 2016 License: BSD-3-Clause Imports: 13 Imported by: 0

README

#GoGoMux - A Fash HTTP Request Router

license

GoGoMux is a high performance HTTP request router (also called multiplexer or just mux for short) for Go.

In contrast to the default mux of Go's net/http package, this router supports variables in the routing pattern and matches against the request method. It has near linear scaling.

Definition: Go-Go

According to my dictionary, "Aggressivly Dynamic".

Why a replacements router

I have been using Gorilla Mux for some time. I just can't live with the slow routing performance. I tried HttpRouter. It claims to be the fastest router available and it is wikid fast. However it lacks support for a variety of routing patterns that I already have in production. This router is as fast (in my use case faster) than HttpRouter.

I will be adding to this to make it a near drop-in replacement for Gorilla Mux.

Not ready yet.

Update: Thu Aug 27 17:20:03 MDT 2015 -- I have been using it for 10 months now and most of the defects seem to have been flushed out.

This is the initial check-in and the router with benchmarks and compatibility tests is not ready yet. In other words - at some point you just have to take the working code, check it in and start validating things like git, website links etc.

How GoGoMux came to be

Like most things, necessity is the mother of invention. My problem was performance. On a reasonably large set of routes I was seeing between 10 and 15 pages served per second. This truly horrified me. The serve was in Go and I was expecting to see several hundred per second. Some testing quickly lead to the conclusion that over half of the time was being used up by Gorilla Mux and its processing.

I have been tuning and improving the performance of software for a long time (I started programming on paper punch cards). My first rule of improving performance is you always start with the biggest time using item. In this case it was figuring out what was going on with Gorilla Mux and why it was taking so much time. A search in the code lead me to the fact that it appears to use a linear search algorithm with a set of regular expressions. Since I had over 100 routes and many of them used regular expressions this was an important finding. My first move was to take the route that was most common and move it to the top of the search. This one change improved my results from the 10 to 15 range to 80 to 100 per second. This change also gave me the breathing room and time to look into the problem.

A quick search on the web revealed that HttpRouter was a lot faster. Many thousands of tiems faster than Gorilla Mux. Now was the time for a quick code switch. It used a significantly different interface than Gorilla. This added many hundreds of lines of code. That took a few hours to get changed. And... And...

HttpRouter only allows for unique routes. My client code (some of witch I did not write and did not want to change) uses some non-unique routes. My frustration level was going back up! I went and looked at the benchmarks that HttpRouter had in its documentation. They clearly implied that HttpRouter covered all routes for sites like GitHub. Then I dug into the code and the author had commented out about 10% of the GitHub routes so that the remaining 90% where unique.

I could now stick with HttpRoute and make major changes to my server to add in a post-route disambiguation phase - or - I could dig into the problem of implementing a fast router that was as close to Gorilla Mux as possible.

I chose to implement a new router. At the time I did not have a clear understating of what the routing problem really involved. It seems so simple. You just take a URL and map that string to a function call. I implemented that. It was fast. Not as fast as HttpRoute but a lot faster than Gorilla Mux. Then I really dug into the test cases and discovered that my first router would not cut it. It was not even close. So a massive amount of changes and a new version. Then version 3, 4, 5. Version 5 worked. The code after 5 rounds of slash and burn without a clear understanding of the problem was so ugly it was guaranteed to cause nightmares. But it worked and it was as fast as HttpRouter.

The current version is my 6th attempt at getting this all to work. It is reasonably close to what Gorilla Mux implements. There are still some missing features that I am working on. Without calls to middleware it is close to as fast as HttpRouter. Testing the original Gorilla Mux code and my latest version of GoGoMux on an set of 5000 routes from my production server indicates that GoGoMux is around 120,000 times as fast as Gorilla Mux. I will pull together a set of benchmarks that clearly shows this and also modify the very comprehensive HttpRouter benchmarks to include GoGoMux.

GoGoMux still needs some work. I have started to use it in my production server. In a couple of weeks, with a bunch more tests and some clean up it should be ready for prime time.

Documentation

Overview

Package gorilla/mux implements a request router and dispatcher.

The name mux stands for "HTTP request multiplexer". Like the standard http.ServeMux, mux.Router matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are:

  • Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
  • URL hosts and paths can have variables with an optional regular expression.
  • Registered URLs can be built, or "reversed", which helps maintaining references to resources.
  • Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching.
  • It implements the http.Handler interface so it is compatible with the standard http.ServeMux.

Let's start registering a couple of URL paths and handlers:

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/products", ProductsHandler)
	r.HandleFunc("/articles", ArticlesHandler)
	http.Handle("/", r)
}

Here we register three routes mapping URL paths to handlers. This is equivalent to how http.HandleFunc() works: if an incoming request URL matches one of the paths, the corresponding handler is called passing (http.ResponseWriter, *http.Request) as parameters.

Paths can have variables. They are defined using the format {name} or {name:pattern}. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. For example:

r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

The names are used to create a map of route variables which can be retrieved calling mux.Vars():

vars := mux.Vars(request)
category := vars["category"]

And this is all you need to know about the basic usage. More advanced options are explained below.

Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:

r := mux.NewRouter()
// Only matches if domain is "www.domain.com".
r.Host("www.domain.com")
// Matches a dynamic subdomain.
r.Host("{subdomain:[a-z]+}.domain.com")

There are several other matchers that can be added. To match path prefixes:

r.PathPrefix("/products/")

...or HTTP methods:

r.Methods("GET", "POST")

...or URL schemes:

r.Schemes("https")

...or header values:

r.Headers("X-Requested-With", "XMLHttpRequest")

...or query values:

r.Queries("key", "value")

...or to use a custom matcher function:

	r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
		return r.ProtoMajor == 0
    })

...and finally, it is possible to combine several matchers in a single route:

r.HandleFunc("/products", ProductsHandler).
  Host("www.domain.com").
  Methods("GET").
  Schemes("http")

Setting the same matching conditions again and again can be boring, so we have a way to group several routes that share the same requirements. We call it "subrouting".

For example, let's say we have several URLs that should only match when the host is "www.domain.com". Create a route for that host and get a "subrouter" from it:

r := mux.NewRouter()
s := r.Host("www.domain.com").Subrouter()

Then register routes in the subrouter:

s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)

The three URL paths we registered above will only be tested if the domain is "www.domain.com", because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route.

Subrouters can be used to create domain or path "namespaces": you define subrouters in a central place and then parts of the app can register its paths relatively to a given subrouter.

There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths:

r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()
// "/products/"
s.HandleFunc("/", ProductsHandler)
// "/products/{key}/"
s.HandleFunc("/{key}/", ProductHandler)
// "/products/{key}/details"
s.HandleFunc("/{key}/details", ProductDetailsHandler)

Now let's see how to build registered URLs.

Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling Name() on a route. For example:

r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Name("article")

To build a URL, get the route and call the URL() method, passing a sequence of key/value pairs for the route variables. For the previous route, we would do:

url, err := r.Get("article").URL("category", "technology", "id", "42")

...and the result will be a url.URL with the following path:

"/articles/technology/42"

This also works for host variables:

r := mux.NewRouter()
r.Host("{subdomain}.domain.com").
  Path("/articles/{category}/{id:[0-9]+}").
  HandlerFunc(ArticleHandler).
  Name("article")

// url.String() will be "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
								 "category", "technology",
								 "id", "42")

All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match.

There's also a way to build only the URL host or path for a route: use the methods URLHost() or URLPath() instead. For the previous route, we would do:

// "http://news.domain.com/"
host, err := r.Get("article").URLHost("subdomain", "news")

// "/articles/technology/42"
path, err := r.Get("article").URLPath("category", "technology", "id", "42")

And if you use subrouters, host and path defined separately can be built as well:

r := mux.NewRouter()
s := r.Host("{subdomain}.domain.com").Subrouter()
s.Path("/articles/{category}/{id:[0-9]+}").
  HandlerFunc(ArticleHandler).
  Name("article")

// "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
								 "category", "technology",
								 "id", "42")

Index

Constants

View Source
const (
	ReMatch       MatchItRankType = 1 << iota // Not used anymore
	HeaderMatch                   = 1 << iota // Has a match on the HTTP Headers
	QueryMatch                    = 1 << iota // Has a match on the query - stuff after question mark
	TLSMatch                      = 1 << iota // Matches "https" v.s. "http"
	PortMatch                     = 1 << iota // Has a match on the Port
	HostMatch                     = 1 << iota // Has a match on the Host
	PortHostMatch                 = 1 << iota // Matches both Host and Port
	ProtocalMatch                 = 1 << iota // Has a match on prococal, http/1.0, http/1.1, http/2.0
	User0Match                    = 1 << iota // Reserved for User Functions
	User1Match                    = 1 << iota // Reserved for User Functions
	User2Match                    = 1 << iota // Reserved for User Functions
	User3Match                    = 1 << iota // Reserved for User Functions
	User4Match                    = 1 << iota // Reserved for User Functions
)
View Source
const (
	HashNewM Where = iota
	Before         = iota
	After          = iota
)
View Source
const (
	IsWord    colType = 1 << iota
	MultiUrl          = 1 << iota
	SingleUrl         = 1 << iota
	Dummy             = 1 << iota
)
View Source
const ApacheFormatPattern = "%s %v %s %s %s %v %d %v\n"
View Source
const MaxParams = 200
View Source
const MaxSlashInUrl = 20

-------------------------------------------------------------------------------------------------

Variables

View Source
var ApacheLogFile *os.File

-------------------------------------------------------------------------------------------------

Functions

func AddValueToParams

func AddValueToParams(Name string, Value string, Type ParamType, From FromType, ps *Params) (k int)

-------------------------------------------------------------------------------------------------

func ApacheLogingAfter

func ApacheLogingAfter(w *MyResponseWriter, req *http.Request, ps *Params) int

func ApacheLogingBefore

func ApacheLogingBefore(w *MyResponseWriter, req *http.Request, ps *Params) int

func FixPath

func FixPath(pth string, rv []string, max int) int

Parse a path and make corrections to it. Remove double slash, "//". Remove all "./". Convert "name/../" to empty string. Return the number of used elements in the 'rv' slice, and place one token from the path in each of the elements of the 'rv' slice. If the path is a hard path (Starts from /) then the 0th element of the rv slice will be "/". The rv slice is assumed to be long enough to hold all the elements of the path. max is the maximum number of elements that will be used in 'rv'.

func FromTypeToString

func FromTypeToString(ff FromType) string

func GetCurTime

func GetCurTime() (s string)

func InitParams

func InitParams(p *Params)

func IsMapStringBoolEmpty

func IsMapStringBoolEmpty(v map[string]bool) bool

func LastIndexOfChar

func LastIndexOfChar(s string, ch uint8) int

Find the last index of the character 'ch' in 's'. Example

n := LastIndexOfChar( "[123:456]:80", ':' )

will return 9 -1 is returned if not found.

func LineFile

func LineFile(d ...int) (string, int)

Return the line number and file name. A single depth paramter 'd' can be supplied. 1 is the routien that called LineFile, 2 is the caller of the routine that called LineFile etc.

func MethodParam

func MethodParam(w *MyResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func MethodParamReg

func MethodParamReg(www http.ResponseWriter, req *http.Request, ps *Params) int

func MethodToCode

func MethodToCode(Method string, AddM int) int

func OrderedBy

func OrderedBy(less ...lessFunc) *multiSorter

OrderedBy returns a Sorter that sorts using the less functions, in order. Call its Sort method to sort the data.

func OrderedByPat

func OrderedByPat(less ...lessFuncPat) *multiSorterPat

OrderedBy returns a Sorter that sorts using the less functions, in order. Call its Sort method to sort the data.

func ParseBodyAsParams

func ParseBodyAsParams(w *MyResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func ParseBodyAsParamsReg

func ParseBodyAsParamsReg(www http.ResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func ParseCookiesAsParams

func ParseCookiesAsParams(w *MyResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func ParseCookiesAsParamsReg

func ParseCookiesAsParamsReg(www http.ResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func ParseQueryParams

func ParseQueryParams(www *MyResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func ParseQueryParamsReg

func ParseQueryParamsReg(www http.ResponseWriter, req *http.Request, ps *Params) int

func PrefixWith

func PrefixWith(w *MyResponseWriter, req *http.Request, ps *Params) int

-------------------------------------------------------------------------------------------------

func RenameReservedItems

func RenameReservedItems(www http.ResponseWriter, req *http.Request, ps *Params, ri map[string]bool)

func ServeHTTP

func ServeHTTP(fx func(w http.ResponseWriter, r *http.Request)) (rv func(res http.ResponseWriter, req *http.Request, ps Params))

func SetCurTime

func SetCurTime(s string)

Types

type ARoute

type ARoute struct {
	DId            int                    // Used for testing
	DName          string                 // Used to identify a route by name
	DPath          string                 // Set by Handler("/path",Fx), Path(), PathPrefix()
	DPathPrefix    string                 // -- Concatenated on front of path --
	DHandlerFunc   HandleFunc             //
	DHeaders       []string               // Set by Headers()
	DHost          string                 // Set by Host()
	DPort          string                 // Set by Port()
	DHostPort      string                 // Set by HostPort()
	DMethods       []string               // Set by Methods()	List of methods, GET, POST etc.
	DSchemes       []string               // Set by Schemes()	https, http etc.
	DQueries       []string               // Set by Queries()
	DProtocal      map[string]bool        // Set by Protocal() https == TLS on, http == no TLS, both is no-check(default)
	DUser          map[string]interface{} // Can be set by user to data needed in matches.
	HeaderMatchMap map[string]string      // Map constructed form pairs of DHeaders
	QueryMatchMap  map[string]string      // Map constructed form pairs of DQueries
	FileName       string                 // Line no && File name where this was defined
	LineNo         int                    //
	// contains filtered or unexported fields
}

func (*ARoute) AppendFileName

func (r *ARoute) AppendFileName(p string) *ARoute

---------------------------------------------------------------------------- Manpiulate LineNo/FileName in ARoute data. ----------------------------------------------------------------------------

func (*ARoute) HandleFunc

func (r *ARoute) HandleFunc(path string, f HandleFunc) *ARoute

HandleFunc registers a new route with a matcher for the URL path.

func (*ARoute) Headers

func (r *ARoute) Headers(pairs ...string) *ARoute

Headers registers a new route with a matcher for request header values.

func (*ARoute) Host

func (r *ARoute) Host(h string) *ARoute

Host registers a new route with a matcher for the URL host.

func (*ARoute) HostPort

func (r *ARoute) HostPort(h string) *ARoute

Host:Port registers a new route with a matcher for the URL host and port.

func (*ARoute) Id

func (r *ARoute) Id(n int) *ARoute

Id sets the name for this route. This is not used for matching the route. This is used in testing.

func (*ARoute) Methods

func (r *ARoute) Methods(methods ...string) *ARoute

Methods registers a new route with a matcher for HTTP methods.

func (*ARoute) Name

func (r *ARoute) Name(n string) *ARoute

Name sets the name for this route. This is not use for matching the route.

func (*ARoute) Path

func (r *ARoute) Path(p string) *ARoute

Path registers a new route with a matcher for the URL path.

func (*ARoute) PathPrefix

func (r *ARoute) PathPrefix(p string) *ARoute

PathPrefix registers a new route with a matcher for the URL path prefix.

func (*ARoute) Port

func (r *ARoute) Port(p string) *ARoute

Port sets the port or this route. This is a string like "80" or "8000" xyzzy xyzzy - ports are numbers ? validate!

func (*ARoute) Protocal

func (r *ARoute) Protocal(p ...string) *ARoute

Protocal sets the HTTP Protocal http/1.0, http/1.1, http/2.0

func (*ARoute) Queries

func (r *ARoute) Queries(q ...string) *ARoute

func (*ARoute) Schemes

func (r *ARoute) Schemes(schemes ...string) *ARoute

Schemes registers a new route with a matcher for URL schemes.

type Collision2

type Collision2 struct {
	Url        string     // /path/:v1/:v2/whatever
	NSL        int        // number of / in the URL/Route
	CleanUrl   string     // /path/:/:/whatever
	Hdlr       int        // User specified int, mostly for testing
	Fx         HandleFunc // Function to call to handle this request
	TPat       string     // T::T
	ArgNames   []string   //
	ArgPattern string     // T::T dup?? not used
	LineNo     int        // Location this was created
	FileName   string     // Location this was created
	HasRe      []ReList   // Set of RE that is required to match this Collision2
	MatchIt    []Match    // If additional matching criteria are used

	Multi map[string]Collision2 // if (cType&MultiUrl)!=0, then use string to disambiguate collisions
	// contains filtered or unexported fields
}

type FromType

type FromType int
const (
	FromURL FromType = iota
	FromParams
	FromCookie
	FromBody
	FromBodyJson
	FromInject
	FromHeader
	FromOther
	FromDefault
	FromAuth
)

func (FromType) String

func (ff FromType) String() string

type GoGoWidgetFunc

type GoGoWidgetFunc func(*MyResponseWriter, *http.Request, *Params) int

type GoGoWidgetFunc func(http.ResponseWriter, *http.Request, *Params, *GoGoData, int) int

type GoGoWidgetMatchFunc

type GoGoWidgetMatchFunc func(http.ResponseWriter, *http.Request, Params, *int, int, *[]string) bool

type GoGoWidgetSet

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

type GoGoWidgetSetMatch

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

type Handle

type Handle func(w http.ResponseWriter, req *http.Request, ps Params)

Handle is a function that can be registered to a route to handle HTTP requests. Like http.HandlerFunc, but has a third parameter for the values of parameters. Parameters can be from the URL or from other sources.

type HandleFunc

type HandleFunc Handle

I will use this type (synonomous with Handle) as HandleFunc is a unique string and Handle is just a word. type HandleFunc func(w http.ResponseWriter, req *http.Request, ps Params)

type Match

type Match struct {
	MatchFunc MatchFunc
}

type MatchFunc

type MatchFunc func(req *http.Request, r *MuxRouter, route_i int) bool

type MatchItRankType

type MatchItRankType uint32

type MuxRouter

type MuxRouter struct {
	NotFoundHandler http.Handler // Configurable Handler to be used when no route matches.

	UseRedirect bool // PJS

	AllHostPortFlag bool
	AllHostPort     map[string]int

	// ------------------------------------------------------------------------------------------------------
	// The hash of paths/URLs
	// HashItems []HashItem
	Hash2Test []int

	// ------------------------------------------------------------------------------------------------------
	// Info used during processing of a URL
	CurUrl string                 // The current URL being processed.
	Hash   [MaxSlashInUrl]int     // The set of hash keys in the current operation.
	Slash  [MaxSlashInUrl + 1]int // Array of locaitons for the '/' in the url.  For /abc/def, it would be [ 0, 4, 8 ]
	NSl    int                    // Number of slashes in the URL for /abc/def it would be 2
	// allParam [MaxParams]Param       // The parameters for the current operation // PJS Sun Nov 15 13:02:59 MST 2015
	AllParam Params // Slice that pints into allParam
	UsePat   string // The used T::T pattern for matching - at URL time.

	MaxSlash int // Maximum number of slashes found in any route

	// ------------------------------------------------------------------------------------------------------
	// User settable handler called when no match is found.  Type: http.HandlerFunc.
	// If not set then http.NotFound will be called.
	NotFound http.HandlerFunc

	// ------------------------------------------------------------------------------------------------------
	// 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.
	PanicHandler func(http.ResponseWriter, *http.Request, interface{})

	// ------------------------------------------------------------------------------------------------------
	HasBeenCompiled bool //	Flag, set to true when the routes are compiled.

	LookupResults []Collision2
	// contains filtered or unexported fields
}

MuxRouter registers routes to be matched and dispatches a handler.

// xyzzy - change this comment to be accurate It implements the http.Handler interface, so it can be registered to serve requests:

var router = mux.NewRouter()

func main() {
    http.Handle("/", router)
}

Or, for Google App Engine, register it in a init() function:

func init() {
    http.Handle("/", router)
}

This will send all incoming requests to the router.

func NewRouter

func NewRouter() *MuxRouter

NewRouter returns a new router instance.

func (*MuxRouter) AttachWidget

func (r *MuxRouter) AttachWidget(w Where, fx GoGoWidgetFunc)

Attach middlewhare widget to the handler.

func (*MuxRouter) CmpUrlToCleanRoute

func (r *MuxRouter) CmpUrlToCleanRoute(UsePat string, CleanUrl string) (rv bool)

compate r.CurUrl to a Pattern

func (*MuxRouter) CompileRoutes

func (r *MuxRouter) CompileRoutes()

func (*MuxRouter) FixBadUrl

func (r *MuxRouter) FixBadUrl(Url string) (rv string, fixed bool)

With a known bad URL, that has //, /./, or /../ in it, fix the URL.

func (*MuxRouter) GetArgs3

func (r *MuxRouter) GetArgs3(Url string, _ string, names []string, _ int)

------------------------------------------------------------------------------------------------- Extract arguments from the URL.

func (*MuxRouter) HandleFunc

func (r *MuxRouter) HandleFunc(path string, f HandleFunc) *ARoute

HandleFunc registers a new route with a matcher for the URL path.

func (*MuxRouter) Headers

func (r *MuxRouter) Headers(pairs ...string) *ARoute

Headers registers a new route with a matcher for request header values.

func (*MuxRouter) Host

func (r *MuxRouter) Host(h string) *ARoute

Host registers a new route with a matcher for the URL host.

func (*MuxRouter) HostPort

func (r *MuxRouter) HostPort(h string) *ARoute

Host:Port registers a new route with a matcher for the URL host and port.

func (*MuxRouter) HostPort_AllRoutes

func (r *MuxRouter) HostPort_AllRoutes(hp ...string) *MuxRouter

Set/Append to list of valid host/ports for all routes by this router

func (*MuxRouter) Id

func (r *MuxRouter) Id(n int) *ARoute

Id sets the name for this route. This is not used for matching the route. This is used in testing.

func (*MuxRouter) ListRoutes

func (r *MuxRouter) ListRoutes() []*ARoute

Just return the data for the routes that are built

func (*MuxRouter) Lookup

func (r *MuxRouter) Lookup(method, path string) (HandleFunc, Params, bool)

Lookup allows the manual lookup of a method + path combo. This is e.g. useful to build a framework around this router.

func (*MuxRouter) LookupUrlViaHash2

func (r *MuxRouter) LookupUrlViaHash2(w http.ResponseWriter, req *http.Request, m *int) (found bool, ln int, rv Collision2)

func (*MuxRouter) MatchAndServeHTTP

func (r *MuxRouter) MatchAndServeHTTP(www http.ResponseWriter, req *http.Request) (Found bool)

func (*MuxRouter) Methods

func (r *MuxRouter) Methods(methods ...string) *ARoute

Methods registers a new route with a matcher for HTTP methods.

func (*MuxRouter) Name

func (r *MuxRouter) Name(n string) *ARoute

Name sets the name for this route. This is not use for matching the route.

func (*MuxRouter) NewRoute

func (r *MuxRouter) NewRoute() *ARoute

NewRoute registers an empty route.

func (*MuxRouter) Path

func (r *MuxRouter) Path(tpl string) *ARoute

Path registers a new route with a matcher for the URL path.

func (*MuxRouter) PathPrefix

func (r *MuxRouter) PathPrefix(p string) *ARoute

PathPrefix registers a new route with a matcher for the URL path prefix.

func (*MuxRouter) Port

func (r *MuxRouter) Port(p string) *ARoute

Port sets the port or this route. This is a string like "80" or "8000" xyzzy

func (*MuxRouter) Protocal

func (r *MuxRouter) Protocal(p ...string) *ARoute

Protocal sets the HTTP Protocal http/1.0, http/1.1, http/2.0

func (*MuxRouter) Queries

func (r *MuxRouter) Queries(q ...string) *ARoute

Queries registers a new route with a matcher for URL query values. xyzzy

func (*MuxRouter) Schemes

func (r *MuxRouter) Schemes(schemes ...string) *ARoute

Schemes registers a new route with a matcher for URL schemes.

func (*MuxRouter) ServeFiles

func (r *MuxRouter) ServeFiles(path string, root http.FileSystem)

ServeFiles serves files from the given file system root. The path must end with "/*filepath", files are then served from the local path /defined/root/dir/*filepath. For example if root is "/etc" and *filepath is "passwd", the local file "/etc/passwd" would be served. Internally a http.FileServer is used, therefore http.NotFound is used instead of the Router's NotFound handler. To use the operating system's file system implementation, use http.Dir:

router.ServeFiles("/src/*filepath", http.Dir("/var/www"))

func (*MuxRouter) ServeHTTP

func (r *MuxRouter) ServeHTTP(w http.ResponseWriter, req *http.Request)

-------------------------------------------------------------------------------------------------

func (*MuxRouter) SplitOnSlash3

func (r *MuxRouter) SplitOnSlash3(m int, Url string, isUrl bool)

xyzzy-hash

func (*MuxRouter) UrlToCleanRoute

func (r *MuxRouter) UrlToCleanRoute(UsePat string) (rv string)

Input: Pattern like T::T and the current URL with Slash locaiton information. So... /abc/:def/ghi is the Route, /abc/x/ghi is the ULR, Slash is [ 0, 4, 6, 10 ] The output is /abc/:/ghi - Sutiable for lookup in a map of cleanRoute

func (*MuxRouter) WidgetMatch

func (r *MuxRouter) WidgetMatch(MatchIt []Match, w http.ResponseWriter, req *http.Request, m *int, route_i int) bool

xyzzy - not take into account ReList - xyzzy - remove m *int param?? - not used xyzzy - remov eMatchIt[i].Data?? - not used

type MyResponseWriter

type MyResponseWriter struct {
	StartTime     time.Time
	Status        int
	ResponseBytes int64
	// contains filtered or unexported fields
}

func (*MyResponseWriter) Header

func (m *MyResponseWriter) Header() http.Header

func (*MyResponseWriter) Write

func (m *MyResponseWriter) Write(p []byte) (written int, err error)

func (*MyResponseWriter) WriteHeader

func (m *MyResponseWriter) WriteHeader(p int)

type Param

type Param struct {
	Name  string
	Value string
	From  FromType
	Type  ParamType
}

Param is a single URL parameter, consisting of a key and a value.

type ParamType

type ParamType uint8

func (ParamType) String

func (ff ParamType) String() string

type Params

type Params struct {
	NParam int     //
	Data   []Param // has to be assided to array
	// contains filtered or unexported fields
}

Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index.

func (*Params) ByName

func (ps *Params) ByName(name string) (rv string)

ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.

func (*Params) ByNameDflt

func (ps *Params) ByNameDflt(name string, dflt string) (rv string)

func (*Params) ByPostion

func (ps *Params) ByPostion(pos int) (name string, val string, outRange bool)

func (*Params) CreateSearch

func (ps *Params) CreateSearch()

func (*Params) DumpParam

func (ps *Params) DumpParam() (rv string)

func (*Params) DumpParamDB

func (ps *Params) DumpParamDB() (rv string)

func (*Params) DumpParamTable

func (ps *Params) DumpParamTable() (rv string)

func (*Params) GetByName

func (ps *Params) GetByName(name string) (rv string, found bool)

func (*Params) GetByNameAndType

func (ps *Params) GetByNameAndType(name string, ft FromType) (rv string, found bool)

func (*Params) HasName

func (ps *Params) HasName(name string) (rv bool)

func (*Params) MakeStringMap

func (ps *Params) MakeStringMap(mdata map[string]string)

func (*Params) PositionOf

func (ps *Params) PositionOf(name string) (rv int)

func (*Params) SetValue

func (ps *Params) SetValue(name string, val string)

type Re

type Re struct {
	Pos int
	Re  string

	Name string
	// contains filtered or unexported fields
}

type ReList

type ReList struct {
	Hdlr     int        // User specified int, mostly for testing
	Fx       HandleFunc // Function to call to handle this request
	ArgNames []string   //
	ReSet    []Re
	MatchIt  []Match
	// contains filtered or unexported fields
}

type RouteData

type RouteData struct {
	Method      string          // GET, PUT ...
	Route       string          // Route Pattern /abc/:def/ghi
	Hdlr        int             // User supplied integer returned on finding route
	NFxNo       int             // Index into []ARoute on what function to use
	Ns          int             //
	MatchIt     []Match         // Array of potential matches with regular expressions
	MatchItRank MatchItRankType //
}

type UrlAPat

type UrlAPat struct {
	Pat  string
	Star bool
}

type UrlPat

type UrlPat struct {
	PatList []UrlAPat
	// Pat    []string
	// Star   []bool
	PatOcc map[string]int
}

type Where

type Where int

Directories

Path Synopsis
Package context stores values shared during a request lifetime.
Package context stores values shared during a request lifetime.

Jump to

Keyboard shortcuts

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