소스 검색

vendor update

fatedier 6 년 전
부모
커밋
ee0df07a3c

+ 0 - 19
vendor/github.com/gorilla/context/.travis.yml

@@ -1,19 +0,0 @@
-language: go
-sudo: false
-
-matrix:
-  include:
-    - go: 1.3
-    - go: 1.4
-    - go: 1.5
-    - go: 1.6
-    - go: 1.7
-    - go: tip
-  allow_failures:
-    - go: tip
-
-script:
-  - go get -t -v ./...
-  - diff -u <(echo -n) <(gofmt -d .)
-  - go vet $(go list ./... | grep -v /vendor/)
-  - go test -v -race ./...

+ 0 - 27
vendor/github.com/gorilla/context/LICENSE

@@ -1,27 +0,0 @@
-Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-	 * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-	 * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-	 * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 10
vendor/github.com/gorilla/context/README.md

@@ -1,10 +0,0 @@
-context
-=======
-[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)
-
-gorilla/context is a general purpose registry for global request variables.
-
-> Note: gorilla/context, having been born well before `context.Context` existed, does not play well
-> with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.
-
-Read the full documentation here: http://www.gorillatoolkit.org/pkg/context

+ 0 - 143
vendor/github.com/gorilla/context/context.go

@@ -1,143 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package context
-
-import (
-	"net/http"
-	"sync"
-	"time"
-)
-
-var (
-	mutex sync.RWMutex
-	data  = make(map[*http.Request]map[interface{}]interface{})
-	datat = make(map[*http.Request]int64)
-)
-
-// Set stores a value for a given key in a given request.
-func Set(r *http.Request, key, val interface{}) {
-	mutex.Lock()
-	if data[r] == nil {
-		data[r] = make(map[interface{}]interface{})
-		datat[r] = time.Now().Unix()
-	}
-	data[r][key] = val
-	mutex.Unlock()
-}
-
-// Get returns a value stored for a given key in a given request.
-func Get(r *http.Request, key interface{}) interface{} {
-	mutex.RLock()
-	if ctx := data[r]; ctx != nil {
-		value := ctx[key]
-		mutex.RUnlock()
-		return value
-	}
-	mutex.RUnlock()
-	return nil
-}
-
-// GetOk returns stored value and presence state like multi-value return of map access.
-func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
-	mutex.RLock()
-	if _, ok := data[r]; ok {
-		value, ok := data[r][key]
-		mutex.RUnlock()
-		return value, ok
-	}
-	mutex.RUnlock()
-	return nil, false
-}
-
-// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
-func GetAll(r *http.Request) map[interface{}]interface{} {
-	mutex.RLock()
-	if context, ok := data[r]; ok {
-		result := make(map[interface{}]interface{}, len(context))
-		for k, v := range context {
-			result[k] = v
-		}
-		mutex.RUnlock()
-		return result
-	}
-	mutex.RUnlock()
-	return nil
-}
-
-// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
-// the request was registered.
-func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
-	mutex.RLock()
-	context, ok := data[r]
-	result := make(map[interface{}]interface{}, len(context))
-	for k, v := range context {
-		result[k] = v
-	}
-	mutex.RUnlock()
-	return result, ok
-}
-
-// Delete removes a value stored for a given key in a given request.
-func Delete(r *http.Request, key interface{}) {
-	mutex.Lock()
-	if data[r] != nil {
-		delete(data[r], key)
-	}
-	mutex.Unlock()
-}
-
-// Clear removes all values stored for a given request.
-//
-// This is usually called by a handler wrapper to clean up request
-// variables at the end of a request lifetime. See ClearHandler().
-func Clear(r *http.Request) {
-	mutex.Lock()
-	clear(r)
-	mutex.Unlock()
-}
-
-// clear is Clear without the lock.
-func clear(r *http.Request) {
-	delete(data, r)
-	delete(datat, r)
-}
-
-// Purge removes request data stored for longer than maxAge, in seconds.
-// It returns the amount of requests removed.
-//
-// If maxAge <= 0, all request data is removed.
-//
-// This is only used for sanity check: in case context cleaning was not
-// properly set some request data can be kept forever, consuming an increasing
-// amount of memory. In case this is detected, Purge() must be called
-// periodically until the problem is fixed.
-func Purge(maxAge int) int {
-	mutex.Lock()
-	count := 0
-	if maxAge <= 0 {
-		count = len(data)
-		data = make(map[*http.Request]map[interface{}]interface{})
-		datat = make(map[*http.Request]int64)
-	} else {
-		min := time.Now().Unix() - int64(maxAge)
-		for r := range data {
-			if datat[r] < min {
-				clear(r)
-				count++
-			}
-		}
-	}
-	mutex.Unlock()
-	return count
-}
-
-// ClearHandler wraps an http.Handler and clears request values at the end
-// of a request lifetime.
-func ClearHandler(h http.Handler) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		defer Clear(r)
-		h.ServeHTTP(w, r)
-	})
-}

+ 0 - 88
vendor/github.com/gorilla/context/doc.go

@@ -1,88 +0,0 @@
-// Copyright 2012 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package context stores values shared during a request lifetime.
-
-Note: gorilla/context, having been born well before `context.Context` existed,
-does not play well > with the shallow copying of the request that
-[`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext)
-(added to net/http Go 1.7 onwards) performs. You should either use *just*
-gorilla/context, or moving forward, the new `http.Request.Context()`.
-
-For example, a router can set variables extracted from the URL and later
-application handlers can access those values, or it can be used to store
-sessions values to be saved at the end of a request. There are several
-others common uses.
-
-The idea was posted by Brad Fitzpatrick to the go-nuts mailing list:
-
-	http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53
-
-Here's the basic usage: first define the keys that you will need. The key
-type is interface{} so a key can be of any type that supports equality.
-Here we define a key using a custom int type to avoid name collisions:
-
-	package foo
-
-	import (
-		"github.com/gorilla/context"
-	)
-
-	type key int
-
-	const MyKey key = 0
-
-Then set a variable. Variables are bound to an http.Request object, so you
-need a request instance to set a value:
-
-	context.Set(r, MyKey, "bar")
-
-The application can later access the variable using the same key you provided:
-
-	func MyHandler(w http.ResponseWriter, r *http.Request) {
-		// val is "bar".
-		val := context.Get(r, foo.MyKey)
-
-		// returns ("bar", true)
-		val, ok := context.GetOk(r, foo.MyKey)
-		// ...
-	}
-
-And that's all about the basic usage. We discuss some other ideas below.
-
-Any type can be stored in the context. To enforce a given type, make the key
-private and wrap Get() and Set() to accept and return values of a specific
-type:
-
-	type key int
-
-	const mykey key = 0
-
-	// GetMyKey returns a value for this package from the request values.
-	func GetMyKey(r *http.Request) SomeType {
-		if rv := context.Get(r, mykey); rv != nil {
-			return rv.(SomeType)
-		}
-		return nil
-	}
-
-	// SetMyKey sets a value for this package in the request values.
-	func SetMyKey(r *http.Request, val SomeType) {
-		context.Set(r, mykey, val)
-	}
-
-Variables must be cleared at the end of a request, to remove all values
-that were stored. This can be done in an http.Handler, after a request was
-served. Just call Clear() passing the request:
-
-	context.Clear(r)
-
-...or use ClearHandler(), which conveniently wraps an http.Handler to clear
-variables at the end of a request lifetime.
-
-The Routers from the packages gorilla/mux and gorilla/pat call Clear()
-so if you are using either of them you don't need to clear the context manually.
-*/
-package context

+ 0 - 23
vendor/github.com/gorilla/mux/.travis.yml

@@ -1,23 +0,0 @@
-language: go
-sudo: false
-
-matrix:
-  include:
-    - go: 1.5.x
-    - go: 1.6.x
-    - go: 1.7.x
-    - go: 1.8.x
-    - go: 1.9.x
-    - go: 1.10.x
-    - go: tip
-  allow_failures:
-    - go: tip
-
-install:
-  - # Skip
-
-script:
-  - go get -t -v ./...
-  - diff -u <(echo -n) <(gofmt -d .)
-  - go tool vet .
-  - go test -v -race ./...

+ 8 - 0
vendor/github.com/gorilla/mux/AUTHORS

@@ -0,0 +1,8 @@
+# This is the official list of gorilla/mux authors for copyright purposes.
+#
+# Please keep the list sorted.
+
+Google LLC (https://opensource.google.com/)
+Kamil Kisielk <kamil@kamilkisiel.net>
+Matt Silverlock <matt@eatsleeprepeat.net>
+Rodrigo Moraes (https://github.com/moraes)

+ 0 - 11
vendor/github.com/gorilla/mux/ISSUE_TEMPLATE.md

@@ -1,11 +0,0 @@
-**What version of Go are you running?** (Paste the output of `go version`)
-
-
-**What version of gorilla/mux are you at?** (Paste the output of `git rev-parse HEAD` inside `$GOPATH/src/github.com/gorilla/mux`)
-
-
-**Describe your problem** (and what you have tried so far)
-
-
-**Paste a minimal, runnable, reproduction of your issue below** (use backticks to format it)
-

+ 1 - 1
vendor/github.com/gorilla/mux/LICENSE

@@ -1,4 +1,4 @@
-Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
+Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are

+ 77 - 8
vendor/github.com/gorilla/mux/README.md

@@ -2,11 +2,12 @@
 
 [![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
 [![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
+[![CircleCI](https://circleci.com/gh/gorilla/mux.svg?style=svg)](https://circleci.com/gh/gorilla/mux)
 [![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)
 
 ![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
 
-http://www.gorillatoolkit.org/pkg/mux
+https://www.gorillatoolkit.org/pkg/mux
 
 Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
 their respective handler.
@@ -29,6 +30,7 @@ The name mux stands for "HTTP request multiplexer". Like the standard `http.Serv
 * [Walking Routes](#walking-routes)
 * [Graceful Shutdown](#graceful-shutdown)
 * [Middleware](#middleware)
+* [Handling CORS Requests](#handling-cors-requests)
 * [Testing Handlers](#testing-handlers)
 * [Full Example](#full-example)
 
@@ -88,7 +90,7 @@ r := mux.NewRouter()
 // Only matches if domain is "www.example.com".
 r.Host("www.example.com")
 // Matches a dynamic subdomain.
-r.Host("{subdomain:[a-z]+}.domain.com")
+r.Host("{subdomain:[a-z]+}.example.com")
 ```
 
 There are several other matchers that can be added. To match path prefixes:
@@ -238,13 +240,13 @@ This also works for host and query value variables:
 
 ```go
 r := mux.NewRouter()
-r.Host("{subdomain}.domain.com").
+r.Host("{subdomain}.example.com").
   Path("/articles/{category}/{id:[0-9]+}").
   Queries("filter", "{filter}").
   HandlerFunc(ArticleHandler).
   Name("article")
 
-// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
+// url.String() will be "http://news.example.com/articles/technology/42?filter=gorilla"
 url, err := r.Get("article").URL("subdomain", "news",
                                  "category", "technology",
                                  "id", "42",
@@ -264,7 +266,7 @@ r.HeadersRegexp("Content-Type", "application/(text|json)")
 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:
 
 ```go
-// "http://news.domain.com/"
+// "http://news.example.com/"
 host, err := r.Get("article").URLHost("subdomain", "news")
 
 // "/articles/technology/42"
@@ -275,12 +277,12 @@ And if you use subrouters, host and path defined separately can be built as well
 
 ```go
 r := mux.NewRouter()
-s := r.Host("{subdomain}.domain.com").Subrouter()
+s := r.Host("{subdomain}.example.com").Subrouter()
 s.Path("/articles/{category}/{id:[0-9]+}").
   HandlerFunc(ArticleHandler).
   Name("article")
 
-// "http://news.domain.com/articles/technology/42"
+// "http://news.example.com/articles/technology/42"
 url, err := r.Get("article").URL("subdomain", "news",
                                  "category", "technology",
                                  "id", "42")
@@ -491,6 +493,73 @@ r.Use(amw.Middleware)
 
 Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it.
 
+### Handling CORS Requests
+
+[CORSMethodMiddleware](https://godoc.org/github.com/gorilla/mux#CORSMethodMiddleware) intends to make it easier to strictly set the `Access-Control-Allow-Methods` response header.
+
+* You will still need to use your own CORS handler to set the other CORS headers such as `Access-Control-Allow-Origin`
+* The middleware will set the `Access-Control-Allow-Methods` header to all the method matchers (e.g. `r.Methods(http.MethodGet, http.MethodPut, http.MethodOptions)` -> `Access-Control-Allow-Methods: GET,PUT,OPTIONS`) on a route
+* If you do not specify any methods, then:
+> _Important_: there must be an `OPTIONS` method matcher for the middleware to set the headers.
+
+Here is an example of using `CORSMethodMiddleware` along with a custom `OPTIONS` handler to set all the required CORS headers:
+
+```go
+package main
+
+import (
+	"net/http"
+	"github.com/gorilla/mux"
+)
+
+func main() {
+    r := mux.NewRouter()
+
+    // IMPORTANT: you must specify an OPTIONS method matcher for the middleware to set CORS headers
+    r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions)
+    r.Use(mux.CORSMethodMiddleware(r))
+    
+    http.ListenAndServe(":8080", r)
+}
+
+func fooHandler(w http.ResponseWriter, r *http.Request) {
+    w.Header().Set("Access-Control-Allow-Origin", "*")
+    if r.Method == http.MethodOptions {
+        return
+    }
+
+    w.Write([]byte("foo"))
+}
+```
+
+And an request to `/foo` using something like:
+
+```bash
+curl localhost:8080/foo -v
+```
+
+Would look like:
+
+```bash
+*   Trying ::1...
+* TCP_NODELAY set
+* Connected to localhost (::1) port 8080 (#0)
+> GET /foo HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.59.0
+> Accept: */*
+> 
+< HTTP/1.1 200 OK
+< Access-Control-Allow-Methods: GET,PUT,PATCH,OPTIONS
+< Access-Control-Allow-Origin: *
+< Date: Fri, 28 Jun 2019 20:13:30 GMT
+< Content-Length: 3
+< Content-Type: text/plain; charset=utf-8
+< 
+* Connection #0 to host localhost left intact
+foo
+```
+
 ### Testing Handlers
 
 Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_.
@@ -503,8 +572,8 @@ package main
 
 func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
     // A very simple health check.
-    w.WriteHeader(http.StatusOK)
     w.Header().Set("Content-Type", "application/json")
+    w.WriteHeader(http.StatusOK)
 
     // In the future we could report back on the status of our DB, or our cache
     // (e.g. Redis) by performing a simple PING, and include them in the response.

+ 0 - 6
vendor/github.com/gorilla/mux/context_native.go → vendor/github.com/gorilla/mux/context.go

@@ -1,5 +1,3 @@
-// +build go1.7
-
 package mux
 
 import (
@@ -18,7 +16,3 @@ func contextSet(r *http.Request, key, val interface{}) *http.Request {
 
 	return r.WithContext(context.WithValue(r.Context(), key, val))
 }
-
-func contextClear(r *http.Request) {
-	return
-}

+ 0 - 26
vendor/github.com/gorilla/mux/context_gorilla.go

@@ -1,26 +0,0 @@
-// +build !go1.7
-
-package mux
-
-import (
-	"net/http"
-
-	"github.com/gorilla/context"
-)
-
-func contextGet(r *http.Request, key interface{}) interface{} {
-	return context.Get(r, key)
-}
-
-func contextSet(r *http.Request, key, val interface{}) *http.Request {
-	if val == nil {
-		return r
-	}
-
-	context.Set(r, key, val)
-	return r
-}
-
-func contextClear(r *http.Request) {
-	context.Clear(r)
-}

+ 1 - 1
vendor/github.com/gorilla/mux/doc.go

@@ -295,7 +295,7 @@ A more complex authentication middleware, which maps session token to users, cou
 	r := mux.NewRouter()
 	r.HandleFunc("/", handler)
 
-	amw := authenticationMiddleware{}
+	amw := authenticationMiddleware{tokenUsers: make(map[string]string)}
 	amw.Populate()
 
 	r.Use(amw.Middleware)

+ 1 - 0
vendor/github.com/gorilla/mux/go.mod

@@ -0,0 +1 @@
+module github.com/gorilla/mux

+ 34 - 27
vendor/github.com/gorilla/mux/middleware.go

@@ -32,37 +32,19 @@ func (r *Router) useInterface(mw middleware) {
 	r.middlewares = append(r.middlewares, mw)
 }
 
-// CORSMethodMiddleware sets the Access-Control-Allow-Methods response header
-// on a request, by matching routes based only on paths. It also handles
-// OPTIONS requests, by settings Access-Control-Allow-Methods, and then
-// returning without calling the next http handler.
+// CORSMethodMiddleware automatically sets the Access-Control-Allow-Methods response header
+// on requests for routes that have an OPTIONS method matcher to all the method matchers on
+// the route. Routes that do not explicitly handle OPTIONS requests will not be processed
+// by the middleware. See examples for usage.
 func CORSMethodMiddleware(r *Router) MiddlewareFunc {
 	return func(next http.Handler) http.Handler {
 		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
-			var allMethods []string
-
-			err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
-				for _, m := range route.matchers {
-					if _, ok := m.(*routeRegexp); ok {
-						if m.Match(req, &RouteMatch{}) {
-							methods, err := route.GetMethods()
-							if err != nil {
-								return err
-							}
-
-							allMethods = append(allMethods, methods...)
-						}
-						break
-					}
-				}
-				return nil
-			})
-
+			allMethods, err := getAllMethodsForRoute(r, req)
 			if err == nil {
-				w.Header().Set("Access-Control-Allow-Methods", strings.Join(append(allMethods, "OPTIONS"), ","))
-
-				if req.Method == "OPTIONS" {
-					return
+				for _, v := range allMethods {
+					if v == http.MethodOptions {
+						w.Header().Set("Access-Control-Allow-Methods", strings.Join(allMethods, ","))
+					}
 				}
 			}
 
@@ -70,3 +52,28 @@ func CORSMethodMiddleware(r *Router) MiddlewareFunc {
 		})
 	}
 }
+
+// getAllMethodsForRoute returns all the methods from method matchers matching a given
+// request.
+func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, error) {
+	var allMethods []string
+
+	err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
+		for _, m := range route.matchers {
+			if _, ok := m.(*routeRegexp); ok {
+				if m.Match(req, &RouteMatch{}) {
+					methods, err := route.GetMethods()
+					if err != nil {
+						return err
+					}
+
+					allMethods = append(allMethods, methods...)
+				}
+				break
+			}
+		}
+		return nil
+	})
+
+	return allMethods, err
+}

+ 74 - 55
vendor/github.com/gorilla/mux/mux.go

@@ -22,7 +22,7 @@ var (
 
 // NewRouter returns a new router instance.
 func NewRouter() *Router {
-	return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
+	return &Router{namedRoutes: make(map[string]*Route)}
 }
 
 // Router registers routes to be matched and dispatches a handler.
@@ -50,24 +50,78 @@ type Router struct {
 	// Configurable Handler to be used when the request method does not match the route.
 	MethodNotAllowedHandler http.Handler
 
-	// Parent route, if this is a subrouter.
-	parent parentRoute
 	// Routes to be matched, in order.
 	routes []*Route
+
 	// Routes by name for URL building.
 	namedRoutes map[string]*Route
-	// See Router.StrictSlash(). This defines the flag for new routes.
-	strictSlash bool
-	// See Router.SkipClean(). This defines the flag for new routes.
-	skipClean bool
+
 	// If true, do not clear the request context after handling the request.
-	// This has no effect when go1.7+ is used, since the context is stored
+	//
+	// Deprecated: No effect when go1.7+ is used, since the context is stored
 	// on the request itself.
 	KeepContext bool
-	// see Router.UseEncodedPath(). This defines a flag for all routes.
-	useEncodedPath bool
+
 	// Slice of middlewares to be called after a match is found
 	middlewares []middleware
+
+	// configuration shared with `Route`
+	routeConf
+}
+
+// common route configuration shared between `Router` and `Route`
+type routeConf struct {
+	// If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to"
+	useEncodedPath bool
+
+	// If true, when the path pattern is "/path/", accessing "/path" will
+	// redirect to the former and vice versa.
+	strictSlash bool
+
+	// If true, when the path pattern is "/path//to", accessing "/path//to"
+	// will not redirect
+	skipClean bool
+
+	// Manager for the variables from host and path.
+	regexp routeRegexpGroup
+
+	// List of matchers.
+	matchers []matcher
+
+	// The scheme used when building URLs.
+	buildScheme string
+
+	buildVarsFunc BuildVarsFunc
+}
+
+// returns an effective deep copy of `routeConf`
+func copyRouteConf(r routeConf) routeConf {
+	c := r
+
+	if r.regexp.path != nil {
+		c.regexp.path = copyRouteRegexp(r.regexp.path)
+	}
+
+	if r.regexp.host != nil {
+		c.regexp.host = copyRouteRegexp(r.regexp.host)
+	}
+
+	c.regexp.queries = make([]*routeRegexp, 0, len(r.regexp.queries))
+	for _, q := range r.regexp.queries {
+		c.regexp.queries = append(c.regexp.queries, copyRouteRegexp(q))
+	}
+
+	c.matchers = make([]matcher, 0, len(r.matchers))
+	for _, m := range r.matchers {
+		c.matchers = append(c.matchers, m)
+	}
+
+	return c
+}
+
+func copyRouteRegexp(r *routeRegexp) *routeRegexp {
+	c := *r
+	return &c
 }
 
 // Match attempts to match the given request against the router's registered routes.
@@ -155,22 +209,18 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 		handler = http.NotFoundHandler()
 	}
 
-	if !r.KeepContext {
-		defer contextClear(req)
-	}
-
 	handler.ServeHTTP(w, req)
 }
 
 // Get returns a route registered with the given name.
 func (r *Router) Get(name string) *Route {
-	return r.getNamedRoutes()[name]
+	return r.namedRoutes[name]
 }
 
 // GetRoute returns a route registered with the given name. This method
 // was renamed to Get() and remains here for backwards compatibility.
 func (r *Router) GetRoute(name string) *Route {
-	return r.getNamedRoutes()[name]
+	return r.namedRoutes[name]
 }
 
 // StrictSlash defines the trailing slash behavior for new routes. The initial
@@ -221,55 +271,24 @@ func (r *Router) UseEncodedPath() *Router {
 	return r
 }
 
-// ----------------------------------------------------------------------------
-// parentRoute
-// ----------------------------------------------------------------------------
-
-func (r *Router) getBuildScheme() string {
-	if r.parent != nil {
-		return r.parent.getBuildScheme()
-	}
-	return ""
-}
-
-// getNamedRoutes returns the map where named routes are registered.
-func (r *Router) getNamedRoutes() map[string]*Route {
-	if r.namedRoutes == nil {
-		if r.parent != nil {
-			r.namedRoutes = r.parent.getNamedRoutes()
-		} else {
-			r.namedRoutes = make(map[string]*Route)
-		}
-	}
-	return r.namedRoutes
-}
-
-// getRegexpGroup returns regexp definitions from the parent route, if any.
-func (r *Router) getRegexpGroup() *routeRegexpGroup {
-	if r.parent != nil {
-		return r.parent.getRegexpGroup()
-	}
-	return nil
-}
-
-func (r *Router) buildVars(m map[string]string) map[string]string {
-	if r.parent != nil {
-		m = r.parent.buildVars(m)
-	}
-	return m
-}
-
 // ----------------------------------------------------------------------------
 // Route factories
 // ----------------------------------------------------------------------------
 
 // NewRoute registers an empty route.
 func (r *Router) NewRoute() *Route {
-	route := &Route{parent: r, strictSlash: r.strictSlash, skipClean: r.skipClean, useEncodedPath: r.useEncodedPath}
+	// initialize a route with a copy of the parent router's configuration
+	route := &Route{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes}
 	r.routes = append(r.routes, route)
 	return route
 }
 
+// Name registers a new route with a name.
+// See Route.Name().
+func (r *Router) Name(name string) *Route {
+	return r.NewRoute().Name(name)
+}
+
 // Handle registers a new route with a matcher for the URL path.
 // See Route.Path() and Route.Handler().
 func (r *Router) Handle(path string, handler http.Handler) *Route {

+ 32 - 19
vendor/github.com/gorilla/mux/regexp.go

@@ -113,6 +113,13 @@ func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*ro
 	if typ != regexpTypePrefix {
 		pattern.WriteByte('$')
 	}
+
+	var wildcardHostPort bool
+	if typ == regexpTypeHost {
+		if !strings.Contains(pattern.String(), ":") {
+			wildcardHostPort = true
+		}
+	}
 	reverse.WriteString(raw)
 	if endSlash {
 		reverse.WriteByte('/')
@@ -131,13 +138,14 @@ func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*ro
 
 	// Done!
 	return &routeRegexp{
-		template:   template,
-		regexpType: typ,
-		options:    options,
-		regexp:     reg,
-		reverse:    reverse.String(),
-		varsN:      varsN,
-		varsR:      varsR,
+		template:         template,
+		regexpType:       typ,
+		options:          options,
+		regexp:           reg,
+		reverse:          reverse.String(),
+		varsN:            varsN,
+		varsR:            varsR,
+		wildcardHostPort: wildcardHostPort,
 	}, nil
 }
 
@@ -158,11 +166,22 @@ type routeRegexp struct {
 	varsN []string
 	// Variable regexps (validators).
 	varsR []*regexp.Regexp
+	// Wildcard host-port (no strict port match in hostname)
+	wildcardHostPort bool
 }
 
 // Match matches the regexp against the URL host or path.
 func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
-	if r.regexpType != regexpTypeHost {
+	if r.regexpType == regexpTypeHost {
+		host := getHost(req)
+		if r.wildcardHostPort {
+			// Don't be strict on the port match
+			if i := strings.Index(host, ":"); i != -1 {
+				host = host[:i]
+			}
+		}
+		return r.regexp.MatchString(host)
+	} else {
 		if r.regexpType == regexpTypeQuery {
 			return r.matchQueryString(req)
 		}
@@ -172,8 +191,6 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
 		}
 		return r.regexp.MatchString(path)
 	}
-
-	return r.regexp.MatchString(getHost(req))
 }
 
 // url builds a URL part using the given values.
@@ -267,7 +284,7 @@ type routeRegexpGroup struct {
 }
 
 // setMatch extracts the variables from the URL once a route matches.
-func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
+func (v routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
 	// Store host variables.
 	if v.host != nil {
 		host := getHost(req)
@@ -296,7 +313,7 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
 					} else {
 						u.Path += "/"
 					}
-					m.Handler = http.RedirectHandler(u.String(), 301)
+					m.Handler = http.RedirectHandler(u.String(), http.StatusMovedPermanently)
 				}
 			}
 		}
@@ -312,17 +329,13 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
 }
 
 // getHost tries its best to return the request host.
+// According to section 14.23 of RFC 2616 the Host header
+// can include the port number if the default value of 80 is not used.
 func getHost(r *http.Request) string {
 	if r.URL.IsAbs() {
 		return r.URL.Host
 	}
-	host := r.Host
-	// Slice off any port information.
-	if i := strings.Index(host, ":"); i != -1 {
-		host = host[:i]
-	}
-	return host
-
+	return r.Host
 }
 
 func extractVars(input string, matches []int, names []string, output map[string]string) {

+ 44 - 97
vendor/github.com/gorilla/mux/route.go

@@ -15,24 +15,8 @@ import (
 
 // Route stores information to match a request and build URLs.
 type Route struct {
-	// Parent where the route was registered (a Router).
-	parent parentRoute
 	// Request handler for the route.
 	handler http.Handler
-	// List of matchers.
-	matchers []matcher
-	// Manager for the variables from host and path.
-	regexp *routeRegexpGroup
-	// If true, when the path pattern is "/path/", accessing "/path" will
-	// redirect to the former and vice versa.
-	strictSlash bool
-	// If true, when the path pattern is "/path//to", accessing "/path//to"
-	// will not redirect
-	skipClean bool
-	// If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to"
-	useEncodedPath bool
-	// The scheme used when building URLs.
-	buildScheme string
 	// If true, this route never matches: it is only used to build URLs.
 	buildOnly bool
 	// The name used to build URLs.
@@ -40,7 +24,11 @@ type Route struct {
 	// Error resulted from building a route.
 	err error
 
-	buildVarsFunc BuildVarsFunc
+	// "global" reference to all named routes
+	namedRoutes map[string]*Route
+
+	// config possibly passed in from `Router`
+	routeConf
 }
 
 // SkipClean reports whether path cleaning is enabled for this route via
@@ -64,6 +52,18 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
 				matchErr = ErrMethodMismatch
 				continue
 			}
+
+			// Ignore ErrNotFound errors. These errors arise from match call
+			// to Subrouters.
+			//
+			// This prevents subsequent matching subrouters from failing to
+			// run middleware. If not ignored, the middleware would see a
+			// non-nil MatchErr and be skipped, even when there was a
+			// matching route.
+			if match.MatchErr == ErrNotFound {
+				match.MatchErr = nil
+			}
+
 			matchErr = nil
 			return false
 		}
@@ -93,9 +93,7 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
 	}
 
 	// Set variables.
-	if r.regexp != nil {
-		r.regexp.setMatch(req, match, r)
-	}
+	r.regexp.setMatch(req, match, r)
 	return true
 }
 
@@ -137,7 +135,7 @@ func (r *Route) GetHandler() http.Handler {
 // Name -----------------------------------------------------------------------
 
 // Name sets the name for the route, used to build URLs.
-// If the name was registered already it will be overwritten.
+// It is an error to call Name more than once on a route.
 func (r *Route) Name(name string) *Route {
 	if r.name != "" {
 		r.err = fmt.Errorf("mux: route already has name %q, can't set %q",
@@ -145,7 +143,7 @@ func (r *Route) Name(name string) *Route {
 	}
 	if r.err == nil {
 		r.name = name
-		r.getNamedRoutes()[name] = r
+		r.namedRoutes[name] = r
 	}
 	return r
 }
@@ -177,7 +175,6 @@ func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error {
 	if r.err != nil {
 		return r.err
 	}
-	r.regexp = r.getRegexpGroup()
 	if typ == regexpTypePath || typ == regexpTypePrefix {
 		if len(tpl) > 0 && tpl[0] != '/' {
 			return fmt.Errorf("mux: path must start with a slash, got %q", tpl)
@@ -386,7 +383,7 @@ func (r *Route) PathPrefix(tpl string) *Route {
 // The above route will only match if the URL contains the defined queries
 // values, e.g.: ?foo=bar&id=42.
 //
-// It the value is an empty string, it will match any value if the key is set.
+// If the value is an empty string, it will match any value if the key is set.
 //
 // Variables can define an optional regexp pattern to be matched:
 //
@@ -424,7 +421,7 @@ func (r *Route) Schemes(schemes ...string) *Route {
 	for k, v := range schemes {
 		schemes[k] = strings.ToLower(v)
 	}
-	if r.buildScheme == "" && len(schemes) > 0 {
+	if len(schemes) > 0 {
 		r.buildScheme = schemes[0]
 	}
 	return r.addMatcher(schemeMatcher(schemes))
@@ -439,7 +436,15 @@ type BuildVarsFunc func(map[string]string) map[string]string
 // BuildVarsFunc adds a custom function to be used to modify build variables
 // before a route's URL is built.
 func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
-	r.buildVarsFunc = f
+	if r.buildVarsFunc != nil {
+		// compose the old and new functions
+		old := r.buildVarsFunc
+		r.buildVarsFunc = func(m map[string]string) map[string]string {
+			return f(old(m))
+		}
+	} else {
+		r.buildVarsFunc = f
+	}
 	return r
 }
 
@@ -458,7 +463,8 @@ func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
 // Here, the routes registered in the subrouter won't be tested if the host
 // doesn't match.
 func (r *Route) Subrouter() *Router {
-	router := &Router{parent: r, strictSlash: r.strictSlash}
+	// initialize a subrouter with a copy of the parent route's configuration
+	router := &Router{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes}
 	r.addMatcher(router)
 	return router
 }
@@ -502,9 +508,6 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) {
 	if r.err != nil {
 		return nil, r.err
 	}
-	if r.regexp == nil {
-		return nil, errors.New("mux: route doesn't have a host or path")
-	}
 	values, err := r.prepareVars(pairs...)
 	if err != nil {
 		return nil, err
@@ -516,8 +519,8 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) {
 			return nil, err
 		}
 		scheme = "http"
-		if s := r.getBuildScheme(); s != "" {
-			scheme = s
+		if r.buildScheme != "" {
+			scheme = r.buildScheme
 		}
 	}
 	if r.regexp.path != nil {
@@ -547,7 +550,7 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
 	if r.err != nil {
 		return nil, r.err
 	}
-	if r.regexp == nil || r.regexp.host == nil {
+	if r.regexp.host == nil {
 		return nil, errors.New("mux: route doesn't have a host")
 	}
 	values, err := r.prepareVars(pairs...)
@@ -562,8 +565,8 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
 		Scheme: "http",
 		Host:   host,
 	}
-	if s := r.getBuildScheme(); s != "" {
-		u.Scheme = s
+	if r.buildScheme != "" {
+		u.Scheme = r.buildScheme
 	}
 	return u, nil
 }
@@ -575,7 +578,7 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
 	if r.err != nil {
 		return nil, r.err
 	}
-	if r.regexp == nil || r.regexp.path == nil {
+	if r.regexp.path == nil {
 		return nil, errors.New("mux: route doesn't have a path")
 	}
 	values, err := r.prepareVars(pairs...)
@@ -600,7 +603,7 @@ func (r *Route) GetPathTemplate() (string, error) {
 	if r.err != nil {
 		return "", r.err
 	}
-	if r.regexp == nil || r.regexp.path == nil {
+	if r.regexp.path == nil {
 		return "", errors.New("mux: route doesn't have a path")
 	}
 	return r.regexp.path.template, nil
@@ -614,7 +617,7 @@ func (r *Route) GetPathRegexp() (string, error) {
 	if r.err != nil {
 		return "", r.err
 	}
-	if r.regexp == nil || r.regexp.path == nil {
+	if r.regexp.path == nil {
 		return "", errors.New("mux: route does not have a path")
 	}
 	return r.regexp.path.regexp.String(), nil
@@ -629,7 +632,7 @@ func (r *Route) GetQueriesRegexp() ([]string, error) {
 	if r.err != nil {
 		return nil, r.err
 	}
-	if r.regexp == nil || r.regexp.queries == nil {
+	if r.regexp.queries == nil {
 		return nil, errors.New("mux: route doesn't have queries")
 	}
 	var queries []string
@@ -648,7 +651,7 @@ func (r *Route) GetQueriesTemplates() ([]string, error) {
 	if r.err != nil {
 		return nil, r.err
 	}
-	if r.regexp == nil || r.regexp.queries == nil {
+	if r.regexp.queries == nil {
 		return nil, errors.New("mux: route doesn't have queries")
 	}
 	var queries []string
@@ -683,7 +686,7 @@ func (r *Route) GetHostTemplate() (string, error) {
 	if r.err != nil {
 		return "", r.err
 	}
-	if r.regexp == nil || r.regexp.host == nil {
+	if r.regexp.host == nil {
 		return "", errors.New("mux: route doesn't have a host")
 	}
 	return r.regexp.host.template, nil
@@ -700,64 +703,8 @@ func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
 }
 
 func (r *Route) buildVars(m map[string]string) map[string]string {
-	if r.parent != nil {
-		m = r.parent.buildVars(m)
-	}
 	if r.buildVarsFunc != nil {
 		m = r.buildVarsFunc(m)
 	}
 	return m
 }
-
-// ----------------------------------------------------------------------------
-// parentRoute
-// ----------------------------------------------------------------------------
-
-// parentRoute allows routes to know about parent host and path definitions.
-type parentRoute interface {
-	getBuildScheme() string
-	getNamedRoutes() map[string]*Route
-	getRegexpGroup() *routeRegexpGroup
-	buildVars(map[string]string) map[string]string
-}
-
-func (r *Route) getBuildScheme() string {
-	if r.buildScheme != "" {
-		return r.buildScheme
-	}
-	if r.parent != nil {
-		return r.parent.getBuildScheme()
-	}
-	return ""
-}
-
-// getNamedRoutes returns the map where named routes are registered.
-func (r *Route) getNamedRoutes() map[string]*Route {
-	if r.parent == nil {
-		// During tests router is not always set.
-		r.parent = NewRouter()
-	}
-	return r.parent.getNamedRoutes()
-}
-
-// getRegexpGroup returns regexp definitions from this route.
-func (r *Route) getRegexpGroup() *routeRegexpGroup {
-	if r.regexp == nil {
-		if r.parent == nil {
-			// During tests router is not always set.
-			r.parent = NewRouter()
-		}
-		regexp := r.parent.getRegexpGroup()
-		if regexp == nil {
-			r.regexp = new(routeRegexpGroup)
-		} else {
-			// Copy.
-			r.regexp = &routeRegexpGroup{
-				host:    regexp.host,
-				path:    regexp.path,
-				queries: regexp.queries,
-			}
-		}
-	}
-	return r.regexp
-}

+ 1 - 3
vendor/modules.txt

@@ -17,9 +17,7 @@ github.com/fatedier/golib/pool
 github.com/fatedier/kcp-go
 # github.com/golang/snappy v0.0.0-20170215233205-553a64147049
 github.com/golang/snappy
-# github.com/gorilla/context v1.1.1
-github.com/gorilla/context
-# github.com/gorilla/mux v1.6.2
+# github.com/gorilla/mux v1.7.3
 github.com/gorilla/mux
 # github.com/gorilla/websocket v1.2.0
 github.com/gorilla/websocket