From a031b83a09a8628435317a03f199cdc18b78262f Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 1 Nov 2017 11:24:59 -0400 Subject: Initial checkin from CRI-O repo Signed-off-by: Matthew Heon --- vendor/github.com/go-zoo/bone/LICENSE | 22 +++ vendor/github.com/go-zoo/bone/README.md | 81 ++++++++++ vendor/github.com/go-zoo/bone/bone.go | 74 +++++++++ vendor/github.com/go-zoo/bone/helper.go | 169 ++++++++++++++++++++ vendor/github.com/go-zoo/bone/helper_15.go | 45 ++++++ vendor/github.com/go-zoo/bone/helper_17.go | 39 +++++ vendor/github.com/go-zoo/bone/mux.go | 137 ++++++++++++++++ vendor/github.com/go-zoo/bone/route.go | 245 +++++++++++++++++++++++++++++ 8 files changed, 812 insertions(+) create mode 100644 vendor/github.com/go-zoo/bone/LICENSE create mode 100644 vendor/github.com/go-zoo/bone/README.md create mode 100644 vendor/github.com/go-zoo/bone/bone.go create mode 100644 vendor/github.com/go-zoo/bone/helper.go create mode 100644 vendor/github.com/go-zoo/bone/helper_15.go create mode 100644 vendor/github.com/go-zoo/bone/helper_17.go create mode 100644 vendor/github.com/go-zoo/bone/mux.go create mode 100644 vendor/github.com/go-zoo/bone/route.go (limited to 'vendor/github.com/go-zoo/bone') diff --git a/vendor/github.com/go-zoo/bone/LICENSE b/vendor/github.com/go-zoo/bone/LICENSE new file mode 100644 index 000000000..652583b76 --- /dev/null +++ b/vendor/github.com/go-zoo/bone/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 CodingFerret + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, Subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or Substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/go-zoo/bone/README.md b/vendor/github.com/go-zoo/bone/README.md new file mode 100644 index 000000000..29ea5f6de --- /dev/null +++ b/vendor/github.com/go-zoo/bone/README.md @@ -0,0 +1,81 @@ +bone [![GoDoc](https://godoc.org/github.com/squiidz/bone?status.png)](http://godoc.org/github.com/go-zoo/bone) [![Build Status](https://travis-ci.org/go-zoo/bone.svg)](https://travis-ci.org/go-zoo/bone) [![Go Report Card](https://goreportcard.com/badge/go-zoo/bone)](https://goreportcard.com/report/go-zoo/bone) [![Sourcegraph](https://sourcegraph.com/github.com/go-zoo/bone/-/badge.svg)](https://sourcegraph.com/github.com/go-zoo/bone?badge) +======= + +## What is bone ? + +Bone is a lightweight and lightning fast HTTP Multiplexer for Golang. It support : + +- URL Parameters +- REGEX Parameters +- Wildcard routes +- Router Prefix +- Sub Router, `mux.SubRoute()`, support most standard router (bone, gorilla/mux, httpRouter etc...) +- Http method declaration +- Support for `http.Handler` and `http.HandlerFunc` +- Custom NotFound handler +- Respect the Go standard `http.Handler` interface + +![alt tag](https://c2.staticflickr.com/2/1070/540747396_5542b42cca_z.jpg) + +## Speed + +``` +- BenchmarkBoneMux 10000000 118 ns/op +- BenchmarkZeusMux 100000 144 ns/op +- BenchmarkHttpRouterMux 10000000 134 ns/op +- BenchmarkNetHttpMux 3000000 580 ns/op +- BenchmarkGorillaMux 300000 3333 ns/op +- BenchmarkGorillaPatMux 1000000 1889 ns/op +``` + + These test are just for fun, all these router are great and really efficient. + Bone do not pretend to be the fastest router for every job. + +## Example + +``` go + +package main + +import( + "net/http" + + "github.com/go-zoo/bone" +) + +func main () { + mux := bone.New() + + // mux.Get, Post, etc ... takes http.Handler + mux.Get("/home/:id", http.HandlerFunc(HomeHandler)) + mux.Get("/profil/:id/:var", http.HandlerFunc(ProfilHandler)) + mux.Post("/data", http.HandlerFunc(DataHandler)) + + // Support REGEX Route params + mux.Get("/index/#id^[0-9]$", http.HandlerFunc(IndexHandler)) + + // Handle take http.Handler + mux.Handle("/", http.HandlerFunc(RootHandler)) + + // GetFunc, PostFunc etc ... takes http.HandlerFunc + mux.GetFunc("/test", Handler) + + http.ListenAndServe(":8080", mux) +} + +func Handler(rw http.ResponseWriter, req *http.Request) { + // Get the value of the "id" parameters. + val := bone.GetValue(req, "id") + + rw.Write([]byte(val)) +} + +``` + +## Blog Posts +- http://www.peterbe.com/plog/my-favorite-go-multiplexer +- https://harshladha.xyz/my-first-library-in-go-language-hasty-791b8e2b9e69 + +## Libs +- Errors dump for Go : [Trash](https://github.com/go-zoo/trash) +- Middleware Chaining module : [Claw](https://github.com/go-zoo/claw) diff --git a/vendor/github.com/go-zoo/bone/bone.go b/vendor/github.com/go-zoo/bone/bone.go new file mode 100644 index 000000000..d00a0b083 --- /dev/null +++ b/vendor/github.com/go-zoo/bone/bone.go @@ -0,0 +1,74 @@ +/******************************** +*** Multiplexer for Go *** +*** Bone is under MIT license *** +*** Code by CodingFerret *** +*** github.com/go-zoo *** +*********************************/ + +package bone + +import ( + "net/http" + "strings" +) + +// Mux have routes and a notFound handler +// Route: all the registred route +// notFound: 404 handler, default http.NotFound if not provided +type Mux struct { + Routes map[string][]*Route + prefix string + notFound http.Handler + Serve func(rw http.ResponseWriter, req *http.Request) + CaseSensitive bool +} + +var ( + static = "static" + method = []string{"GET", "POST", "PUT", "DELETE", "HEAD", "PATCH", "OPTIONS"} +) + +type adapter func(*Mux) *Mux + +// New create a pointer to a Mux instance +func New(adapters ...adapter) *Mux { + m := &Mux{Routes: make(map[string][]*Route), Serve: nil, CaseSensitive: true} + for _, adap := range adapters { + adap(m) + } + if m.Serve == nil { + m.Serve = m.DefaultServe + } + return m +} + +// Prefix set a default prefix for all routes registred on the router +func (m *Mux) Prefix(p string) *Mux { + m.prefix = strings.TrimSuffix(p, "/") + return m +} + +// DefaultServe is the default http request handler +func (m *Mux) DefaultServe(rw http.ResponseWriter, req *http.Request) { + // Check if a route match + if !m.parse(rw, req) { + // Check if it's a static ressource + if !m.staticRoute(rw, req) { + // Check if the request path doesn't end with / + if !m.validate(rw, req) { + // Check if same route exists for another HTTP method + if !m.otherMethods(rw, req) { + m.HandleNotFound(rw, req) + } + } + } + } +} + +// ServeHTTP pass the request to the serve method of Mux +func (m *Mux) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if !m.CaseSensitive { + req.URL.Path = strings.ToLower(req.URL.Path) + } + m.Serve(rw, req) +} diff --git a/vendor/github.com/go-zoo/bone/helper.go b/vendor/github.com/go-zoo/bone/helper.go new file mode 100644 index 000000000..bd7b45e95 --- /dev/null +++ b/vendor/github.com/go-zoo/bone/helper.go @@ -0,0 +1,169 @@ +/******************************** +*** Multiplexer for Go *** +*** Bone is under MIT license *** +*** Code by CodingFerret *** +*** github.com/go-zoo *** +*********************************/ + +package bone + +import ( + "net/http" + "net/url" + "strings" +) + +func (m *Mux) ListenAndServe(port string) error { + return http.ListenAndServe(port, m) +} + +func (m *Mux) parse(rw http.ResponseWriter, req *http.Request) bool { + for _, r := range m.Routes[req.Method] { + ok := r.parse(rw, req) + if ok { + return true + } + } + // If no HEAD method, default to GET + if req.Method == "HEAD" { + for _, r := range m.Routes["GET"] { + ok := r.parse(rw, req) + if ok { + return true + } + } + } + return false +} + +// StaticRoute check if the request path is for Static route +func (m *Mux) staticRoute(rw http.ResponseWriter, req *http.Request) bool { + for _, s := range m.Routes[static] { + if len(req.URL.Path) >= s.Size { + if req.URL.Path[:s.Size] == s.Path { + s.Handler.ServeHTTP(rw, req) + return true + } + } + } + return false +} + +// HandleNotFound handle when a request does not match a registered handler. +func (m *Mux) HandleNotFound(rw http.ResponseWriter, req *http.Request) { + if m.notFound != nil { + m.notFound.ServeHTTP(rw, req) + } else { + http.NotFound(rw, req) + } +} + +// Check if the path don't end with a / +func (m *Mux) validate(rw http.ResponseWriter, req *http.Request) bool { + plen := len(req.URL.Path) + if plen > 1 && req.URL.Path[plen-1:] == "/" { + cleanURL(&req.URL.Path) + rw.Header().Set("Location", req.URL.String()) + rw.WriteHeader(http.StatusFound) + return true + } + // Retry to find a route that match + return m.parse(rw, req) +} + +func valid(path string) bool { + plen := len(path) + if plen > 1 && path[plen-1:] == "/" { + return false + } + return true +} + +// Clean url path +func cleanURL(url *string) { + ulen := len((*url)) + if ulen > 1 { + if (*url)[ulen-1:] == "/" { + *url = (*url)[:ulen-1] + cleanURL(url) + } + } +} + +// GetValue return the key value, of the current *http.Request +func GetValue(req *http.Request, key string) string { + return GetAllValues(req)[key] +} + +// GetRequestRoute returns the route of given Request +func (m *Mux) GetRequestRoute(req *http.Request) string { + cleanURL(&req.URL.Path) + for _, r := range m.Routes[req.Method] { + if r.Atts != 0 { + if r.Atts&SUB != 0 { + return r.Handler.(*Mux).GetRequestRoute(req) + } + if r.Match(req) { + return r.Path + } + } + if req.URL.Path == r.Path { + return r.Path + } + } + + for _, s := range m.Routes[static] { + if len(req.URL.Path) >= s.Size { + if req.URL.Path[:s.Size] == s.Path { + return s.Path + } + } + } + + return "NotFound" +} + +// GetQuery return the key value, of the current *http.Request query +func GetQuery(req *http.Request, key string) []string { + if ok, value := extractQueries(req); ok { + return value[key] + } + return nil +} + +// GetAllQueries return all queries of the current *http.Request +func GetAllQueries(req *http.Request) map[string][]string { + if ok, values := extractQueries(req); ok { + return values + } + return nil +} + +func extractQueries(req *http.Request) (bool, map[string][]string) { + if q, err := url.ParseQuery(req.URL.RawQuery); err == nil { + var queries = make(map[string][]string) + for k, v := range q { + for _, item := range v { + values := strings.Split(item, ",") + queries[k] = append(queries[k], values...) + } + } + return true, queries + } + return false, nil +} + +func (m *Mux) otherMethods(rw http.ResponseWriter, req *http.Request) bool { + for _, met := range method { + if met != req.Method { + for _, r := range m.Routes[met] { + ok := r.exists(rw, req) + if ok { + rw.WriteHeader(http.StatusMethodNotAllowed) + return true + } + } + } + } + return false +} diff --git a/vendor/github.com/go-zoo/bone/helper_15.go b/vendor/github.com/go-zoo/bone/helper_15.go new file mode 100644 index 000000000..068ce18e0 --- /dev/null +++ b/vendor/github.com/go-zoo/bone/helper_15.go @@ -0,0 +1,45 @@ +// +build !go1.7 + +/******************************** +*** Multiplexer for Go *** +*** Bone is under MIT license *** +*** Code by CodingFerret *** +*** github.com/go-zoo *** +*********************************/ + +package bone + +import ( + "net/http" + "sync" +) + +var globalVars = struct { + sync.RWMutex + v map[*http.Request]map[string]string +}{v: make(map[*http.Request]map[string]string)} + +// GetAllValues return the req PARAMs +func GetAllValues(req *http.Request) map[string]string { + globalVars.RLock() + values := globalVars.v[req] + globalVars.RUnlock() + return values +} + +// serveMatchedRequest is an extension point for Route which allows us to conditionally compile for +// go1.7 and = 1 { + switch s[:1] { + case ":": + if r.Pattern == nil { + r.Pattern = make(map[int]string) + } + r.Pattern[i] = s[1:] + r.Atts |= PARAM + case "#": + if r.Compile == nil { + r.Compile = make(map[int]*regexp.Regexp) + r.Tag = make(map[int]string) + } + tmp := strings.Split(s, "^") + r.Tag[i] = tmp[0][1:] + r.Compile[i] = regexp.MustCompile("^" + tmp[1][:len(tmp[1])-1]) + r.Atts |= REGEX + case "*": + r.wildPos = i + r.Atts |= WC + default: + r.Token.raw = append(r.Token.raw, i) + } + } + r.Token.Size++ + } +} + +// Match check if the request match the route Pattern +func (r *Route) Match(req *http.Request) bool { + ok, _ := r.matchAndParse(req) + return ok +} + +// matchAndParse check if the request matches the route Pattern and returns a map of the parsed +// variables if it matches +func (r *Route) matchAndParse(req *http.Request) (bool, map[string]string) { + ss := strings.Split(req.URL.EscapedPath(), "/") + if r.matchRawTokens(&ss) { + if len(ss) == r.Token.Size || r.Atts&WC != 0 { + totalSize := len(r.Pattern) + if r.Atts®EX != 0 { + totalSize += len(r.Compile) + } + + vars := make(map[string]string, totalSize) + for k, v := range r.Pattern { + vars[v] = ss[k] + } + + if r.Atts®EX != 0 { + for k, v := range r.Compile { + if !v.MatchString(ss[k]) { + return false, nil + } + vars[r.Tag[k]] = ss[k] + } + } + + return true, vars + } + } + + return false, nil +} + +func (r *Route) parse(rw http.ResponseWriter, req *http.Request) bool { + if r.Atts != 0 { + if r.Atts&SUB != 0 { + if len(req.URL.Path) >= r.Size { + if req.URL.Path[:r.Size] == r.Path { + req.URL.Path = req.URL.Path[r.Size:] + r.Handler.ServeHTTP(rw, req) + return true + } + } + } + + if ok, vars := r.matchAndParse(req); ok { + r.serveMatchedRequest(rw, req, vars) + return true + } + } + if req.URL.Path == r.Path { + r.Handler.ServeHTTP(rw, req) + return true + } + return false +} + +func (r *Route) matchRawTokens(ss *[]string) bool { + if len(*ss) >= r.Token.Size { + for i, v := range r.Token.raw { + if (*ss)[v] != r.Token.Tokens[v] { + if r.Atts&WC != 0 && r.wildPos == i { + return true + } + return false + } + } + return true + } + return false +} + +func (r *Route) exists(rw http.ResponseWriter, req *http.Request) bool { + if r.Atts != 0 { + if r.Atts&SUB != 0 { + if len(req.URL.Path) >= r.Size { + if req.URL.Path[:r.Size] == r.Path { + return true + } + } + } + + if ok, _ := r.matchAndParse(req); ok { + return true + } + } + if req.URL.Path == r.Path { + return true + } + return false +} + +// Get set the route method to Get +func (r *Route) Get() *Route { + r.Method = "GET" + return r +} + +// Post set the route method to Post +func (r *Route) Post() *Route { + r.Method = "POST" + return r +} + +// Put set the route method to Put +func (r *Route) Put() *Route { + r.Method = "PUT" + return r +} + +// Delete set the route method to Delete +func (r *Route) Delete() *Route { + r.Method = "DELETE" + return r +} + +// Head set the route method to Head +func (r *Route) Head() *Route { + r.Method = "HEAD" + return r +} + +// Patch set the route method to Patch +func (r *Route) Patch() *Route { + r.Method = "PATCH" + return r +} + +// Options set the route method to Options +func (r *Route) Options() *Route { + r.Method = "OPTIONS" + return r +} + +func (r *Route) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if r.Method != "" { + if req.Method == r.Method { + r.Handler.ServeHTTP(rw, req) + return + } + http.NotFound(rw, req) + return + } + r.Handler.ServeHTTP(rw, req) +} -- cgit v1.2.3-54-g00ecf