aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla')
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/LICENSE27
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/README.md7
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/context.go143
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/doc.go82
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/LICENSE27
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/README.md240
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/doc.go206
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/mux.go481
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/regexp.go317
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go595
10 files changed, 0 insertions, 2125 deletions
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/LICENSE b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/LICENSE
deleted file mode 100644
index 0e5fb87..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
1Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6
7 * Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the
12distribution.
13 * Neither the name of Google Inc. nor the names of its
14contributors may be used to endorse or promote products derived from
15this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/README.md b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/README.md
deleted file mode 100644
index c60a31b..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
1context
2=======
3[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)
4
5gorilla/context is a general purpose registry for global request variables.
6
7Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/context.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/context.go
deleted file mode 100644
index 81cb128..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/context.go
+++ /dev/null
@@ -1,143 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package context
6
7import (
8 "net/http"
9 "sync"
10 "time"
11)
12
13var (
14 mutex sync.RWMutex
15 data = make(map[*http.Request]map[interface{}]interface{})
16 datat = make(map[*http.Request]int64)
17)
18
19// Set stores a value for a given key in a given request.
20func Set(r *http.Request, key, val interface{}) {
21 mutex.Lock()
22 if data[r] == nil {
23 data[r] = make(map[interface{}]interface{})
24 datat[r] = time.Now().Unix()
25 }
26 data[r][key] = val
27 mutex.Unlock()
28}
29
30// Get returns a value stored for a given key in a given request.
31func Get(r *http.Request, key interface{}) interface{} {
32 mutex.RLock()
33 if ctx := data[r]; ctx != nil {
34 value := ctx[key]
35 mutex.RUnlock()
36 return value
37 }
38 mutex.RUnlock()
39 return nil
40}
41
42// GetOk returns stored value and presence state like multi-value return of map access.
43func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
44 mutex.RLock()
45 if _, ok := data[r]; ok {
46 value, ok := data[r][key]
47 mutex.RUnlock()
48 return value, ok
49 }
50 mutex.RUnlock()
51 return nil, false
52}
53
54// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
55func GetAll(r *http.Request) map[interface{}]interface{} {
56 mutex.RLock()
57 if context, ok := data[r]; ok {
58 result := make(map[interface{}]interface{}, len(context))
59 for k, v := range context {
60 result[k] = v
61 }
62 mutex.RUnlock()
63 return result
64 }
65 mutex.RUnlock()
66 return nil
67}
68
69// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
70// the request was registered.
71func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
72 mutex.RLock()
73 context, ok := data[r]
74 result := make(map[interface{}]interface{}, len(context))
75 for k, v := range context {
76 result[k] = v
77 }
78 mutex.RUnlock()
79 return result, ok
80}
81
82// Delete removes a value stored for a given key in a given request.
83func Delete(r *http.Request, key interface{}) {
84 mutex.Lock()
85 if data[r] != nil {
86 delete(data[r], key)
87 }
88 mutex.Unlock()
89}
90
91// Clear removes all values stored for a given request.
92//
93// This is usually called by a handler wrapper to clean up request
94// variables at the end of a request lifetime. See ClearHandler().
95func Clear(r *http.Request) {
96 mutex.Lock()
97 clear(r)
98 mutex.Unlock()
99}
100
101// clear is Clear without the lock.
102func clear(r *http.Request) {
103 delete(data, r)
104 delete(datat, r)
105}
106
107// Purge removes request data stored for longer than maxAge, in seconds.
108// It returns the amount of requests removed.
109//
110// If maxAge <= 0, all request data is removed.
111//
112// This is only used for sanity check: in case context cleaning was not
113// properly set some request data can be kept forever, consuming an increasing
114// amount of memory. In case this is detected, Purge() must be called
115// periodically until the problem is fixed.
116func Purge(maxAge int) int {
117 mutex.Lock()
118 count := 0
119 if maxAge <= 0 {
120 count = len(data)
121 data = make(map[*http.Request]map[interface{}]interface{})
122 datat = make(map[*http.Request]int64)
123 } else {
124 min := time.Now().Unix() - int64(maxAge)
125 for r := range data {
126 if datat[r] < min {
127 clear(r)
128 count++
129 }
130 }
131 }
132 mutex.Unlock()
133 return count
134}
135
136// ClearHandler wraps an http.Handler and clears request values at the end
137// of a request lifetime.
138func ClearHandler(h http.Handler) http.Handler {
139 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
140 defer Clear(r)
141 h.ServeHTTP(w, r)
142 })
143}
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/doc.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/doc.go
deleted file mode 100644
index 73c7400..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/context/doc.go
+++ /dev/null
@@ -1,82 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5/*
6Package context stores values shared during a request lifetime.
7
8For example, a router can set variables extracted from the URL and later
9application handlers can access those values, or it can be used to store
10sessions values to be saved at the end of a request. There are several
11others common uses.
12
13The idea was posted by Brad Fitzpatrick to the go-nuts mailing list:
14
15 http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53
16
17Here's the basic usage: first define the keys that you will need. The key
18type is interface{} so a key can be of any type that supports equality.
19Here we define a key using a custom int type to avoid name collisions:
20
21 package foo
22
23 import (
24 "github.com/gorilla/context"
25 )
26
27 type key int
28
29 const MyKey key = 0
30
31Then set a variable. Variables are bound to an http.Request object, so you
32need a request instance to set a value:
33
34 context.Set(r, MyKey, "bar")
35
36The application can later access the variable using the same key you provided:
37
38 func MyHandler(w http.ResponseWriter, r *http.Request) {
39 // val is "bar".
40 val := context.Get(r, foo.MyKey)
41
42 // returns ("bar", true)
43 val, ok := context.GetOk(r, foo.MyKey)
44 // ...
45 }
46
47And that's all about the basic usage. We discuss some other ideas below.
48
49Any type can be stored in the context. To enforce a given type, make the key
50private and wrap Get() and Set() to accept and return values of a specific
51type:
52
53 type key int
54
55 const mykey key = 0
56
57 // GetMyKey returns a value for this package from the request values.
58 func GetMyKey(r *http.Request) SomeType {
59 if rv := context.Get(r, mykey); rv != nil {
60 return rv.(SomeType)
61 }
62 return nil
63 }
64
65 // SetMyKey sets a value for this package in the request values.
66 func SetMyKey(r *http.Request, val SomeType) {
67 context.Set(r, mykey, val)
68 }
69
70Variables must be cleared at the end of a request, to remove all values
71that were stored. This can be done in an http.Handler, after a request was
72served. Just call Clear() passing the request:
73
74 context.Clear(r)
75
76...or use ClearHandler(), which conveniently wraps an http.Handler to clear
77variables at the end of a request lifetime.
78
79The Routers from the packages gorilla/mux and gorilla/pat call Clear()
80so if you are using either of them you don't need to clear the context manually.
81*/
82package context
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/LICENSE b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/LICENSE
deleted file mode 100644
index 0e5fb87..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
1Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6
7 * Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the
12distribution.
13 * Neither the name of Google Inc. nor the names of its
14contributors may be used to endorse or promote products derived from
15this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/README.md b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/README.md
deleted file mode 100644
index b987c9e..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/README.md
+++ /dev/null
@@ -1,240 +0,0 @@
1mux
2===
3[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
4[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
5
6Package `gorilla/mux` implements a request router and dispatcher.
7
8The 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:
9
10* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
11* URL hosts and paths can have variables with an optional regular expression.
12* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
13* 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.
14* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
15
16Let's start registering a couple of URL paths and handlers:
17
18```go
19func main() {
20 r := mux.NewRouter()
21 r.HandleFunc("/", HomeHandler)
22 r.HandleFunc("/products", ProductsHandler)
23 r.HandleFunc("/articles", ArticlesHandler)
24 http.Handle("/", r)
25}
26```
27
28Here 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.
29
30Paths 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:
31
32```go
33r := mux.NewRouter()
34r.HandleFunc("/products/{key}", ProductHandler)
35r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
36r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
37```
38
39The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`:
40
41```go
42vars := mux.Vars(request)
43category := vars["category"]
44```
45
46And this is all you need to know about the basic usage. More advanced options are explained below.
47
48Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:
49
50```go
51r := mux.NewRouter()
52// Only matches if domain is "www.example.com".
53r.Host("www.example.com")
54// Matches a dynamic subdomain.
55r.Host("{subdomain:[a-z]+}.domain.com")
56```
57
58There are several other matchers that can be added. To match path prefixes:
59
60```go
61r.PathPrefix("/products/")
62```
63
64...or HTTP methods:
65
66```go
67r.Methods("GET", "POST")
68```
69
70...or URL schemes:
71
72```go
73r.Schemes("https")
74```
75
76...or header values:
77
78```go
79r.Headers("X-Requested-With", "XMLHttpRequest")
80```
81
82...or query values:
83
84```go
85r.Queries("key", "value")
86```
87
88...or to use a custom matcher function:
89
90```go
91r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
92 return r.ProtoMajor == 0
93})
94```
95
96...and finally, it is possible to combine several matchers in a single route:
97
98```go
99r.HandleFunc("/products", ProductsHandler).
100 Host("www.example.com").
101 Methods("GET").
102 Schemes("http")
103```
104
105Setting 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".
106
107For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it:
108
109```go
110r := mux.NewRouter()
111s := r.Host("www.example.com").Subrouter()
112```
113
114Then register routes in the subrouter:
115
116```go
117s.HandleFunc("/products/", ProductsHandler)
118s.HandleFunc("/products/{key}", ProductHandler)
119s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
120```
121
122The three URL paths we registered above will only be tested if the domain is `www.example.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.
123
124Subrouters 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.
125
126There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths:
127
128```go
129r := mux.NewRouter()
130s := r.PathPrefix("/products").Subrouter()
131// "/products/"
132s.HandleFunc("/", ProductsHandler)
133// "/products/{key}/"
134s.HandleFunc("/{key}/", ProductHandler)
135// "/products/{key}/details"
136s.HandleFunc("/{key}/details", ProductDetailsHandler)
137```
138
139Now let's see how to build registered URLs.
140
141Routes 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:
142
143```go
144r := mux.NewRouter()
145r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
146 Name("article")
147```
148
149To 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:
150
151```go
152url, err := r.Get("article").URL("category", "technology", "id", "42")
153```
154
155...and the result will be a `url.URL` with the following path:
156
157```
158"/articles/technology/42"
159```
160
161This also works for host variables:
162
163```go
164r := mux.NewRouter()
165r.Host("{subdomain}.domain.com").
166 Path("/articles/{category}/{id:[0-9]+}").
167 HandlerFunc(ArticleHandler).
168 Name("article")
169
170// url.String() will be "http://news.domain.com/articles/technology/42"
171url, err := r.Get("article").URL("subdomain", "news",
172 "category", "technology",
173 "id", "42")
174```
175
176All 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.
177
178Regex support also exists for matching Headers within a route. For example, we could do:
179
180```go
181r.HeadersRegexp("Content-Type", "application/(text|json)")
182```
183
184...and the route will match both requests with a Content-Type of `application/json` as well as `application/text`
185
186There'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:
187
188```go
189// "http://news.domain.com/"
190host, err := r.Get("article").URLHost("subdomain", "news")
191
192// "/articles/technology/42"
193path, err := r.Get("article").URLPath("category", "technology", "id", "42")
194```
195
196And if you use subrouters, host and path defined separately can be built as well:
197
198```go
199r := mux.NewRouter()
200s := r.Host("{subdomain}.domain.com").Subrouter()
201s.Path("/articles/{category}/{id:[0-9]+}").
202 HandlerFunc(ArticleHandler).
203 Name("article")
204
205// "http://news.domain.com/articles/technology/42"
206url, err := r.Get("article").URL("subdomain", "news",
207 "category", "technology",
208 "id", "42")
209```
210
211## Full Example
212
213Here's a complete, runnable example of a small `mux` based server:
214
215```go
216package main
217
218import (
219 "net/http"
220
221 "github.com/gorilla/mux"
222)
223
224func YourHandler(w http.ResponseWriter, r *http.Request) {
225 w.Write([]byte("Gorilla!\n"))
226}
227
228func main() {
229 r := mux.NewRouter()
230 // Routes consist of a path and a handler function.
231 r.HandleFunc("/", YourHandler)
232
233 // Bind to a port and pass our router in
234 http.ListenAndServe(":8000", r)
235}
236```
237
238## License
239
240BSD licensed. See the LICENSE file for details.
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/doc.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/doc.go
deleted file mode 100644
index 49798cb..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/doc.go
+++ /dev/null
@@ -1,206 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5/*
6Package gorilla/mux implements a request router and dispatcher.
7
8The name mux stands for "HTTP request multiplexer". Like the standard
9http.ServeMux, mux.Router matches incoming requests against a list of
10registered routes and calls a handler for the route that matches the URL
11or other conditions. The main features are:
12
13 * Requests can be matched based on URL host, path, path prefix, schemes,
14 header and query values, HTTP methods or using custom matchers.
15 * URL hosts and paths can have variables with an optional regular
16 expression.
17 * Registered URLs can be built, or "reversed", which helps maintaining
18 references to resources.
19 * Routes can be used as subrouters: nested routes are only tested if the
20 parent route matches. This is useful to define groups of routes that
21 share common conditions like a host, a path prefix or other repeated
22 attributes. As a bonus, this optimizes request matching.
23 * It implements the http.Handler interface so it is compatible with the
24 standard http.ServeMux.
25
26Let's start registering a couple of URL paths and handlers:
27
28 func main() {
29 r := mux.NewRouter()
30 r.HandleFunc("/", HomeHandler)
31 r.HandleFunc("/products", ProductsHandler)
32 r.HandleFunc("/articles", ArticlesHandler)
33 http.Handle("/", r)
34 }
35
36Here we register three routes mapping URL paths to handlers. This is
37equivalent to how http.HandleFunc() works: if an incoming request URL matches
38one of the paths, the corresponding handler is called passing
39(http.ResponseWriter, *http.Request) as parameters.
40
41Paths can have variables. They are defined using the format {name} or
42{name:pattern}. If a regular expression pattern is not defined, the matched
43variable will be anything until the next slash. For example:
44
45 r := mux.NewRouter()
46 r.HandleFunc("/products/{key}", ProductHandler)
47 r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
48 r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
49
50The names are used to create a map of route variables which can be retrieved
51calling mux.Vars():
52
53 vars := mux.Vars(request)
54 category := vars["category"]
55
56And this is all you need to know about the basic usage. More advanced options
57are explained below.
58
59Routes can also be restricted to a domain or subdomain. Just define a host
60pattern to be matched. They can also have variables:
61
62 r := mux.NewRouter()
63 // Only matches if domain is "www.example.com".
64 r.Host("www.example.com")
65 // Matches a dynamic subdomain.
66 r.Host("{subdomain:[a-z]+}.domain.com")
67
68There are several other matchers that can be added. To match path prefixes:
69
70 r.PathPrefix("/products/")
71
72...or HTTP methods:
73
74 r.Methods("GET", "POST")
75
76...or URL schemes:
77
78 r.Schemes("https")
79
80...or header values:
81
82 r.Headers("X-Requested-With", "XMLHttpRequest")
83
84...or query values:
85
86 r.Queries("key", "value")
87
88...or to use a custom matcher function:
89
90 r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
91 return r.ProtoMajor == 0
92 })
93
94...and finally, it is possible to combine several matchers in a single route:
95
96 r.HandleFunc("/products", ProductsHandler).
97 Host("www.example.com").
98 Methods("GET").
99 Schemes("http")
100
101Setting the same matching conditions again and again can be boring, so we have
102a way to group several routes that share the same requirements.
103We call it "subrouting".
104
105For example, let's say we have several URLs that should only match when the
106host is "www.example.com". Create a route for that host and get a "subrouter"
107from it:
108
109 r := mux.NewRouter()
110 s := r.Host("www.example.com").Subrouter()
111
112Then register routes in the subrouter:
113
114 s.HandleFunc("/products/", ProductsHandler)
115 s.HandleFunc("/products/{key}", ProductHandler)
116 s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
117
118The three URL paths we registered above will only be tested if the domain is
119"www.example.com", because the subrouter is tested first. This is not
120only convenient, but also optimizes request matching. You can create
121subrouters combining any attribute matchers accepted by a route.
122
123Subrouters can be used to create domain or path "namespaces": you define
124subrouters in a central place and then parts of the app can register its
125paths relatively to a given subrouter.
126
127There's one more thing about subroutes. When a subrouter has a path prefix,
128the inner routes use it as base for their paths:
129
130 r := mux.NewRouter()
131 s := r.PathPrefix("/products").Subrouter()
132 // "/products/"
133 s.HandleFunc("/", ProductsHandler)
134 // "/products/{key}/"
135 s.HandleFunc("/{key}/", ProductHandler)
136 // "/products/{key}/details"
137 s.HandleFunc("/{key}/details", ProductDetailsHandler)
138
139Now let's see how to build registered URLs.
140
141Routes can be named. All routes that define a name can have their URLs built,
142or "reversed". We define a name calling Name() on a route. For example:
143
144 r := mux.NewRouter()
145 r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
146 Name("article")
147
148To build a URL, get the route and call the URL() method, passing a sequence of
149key/value pairs for the route variables. For the previous route, we would do:
150
151 url, err := r.Get("article").URL("category", "technology", "id", "42")
152
153...and the result will be a url.URL with the following path:
154
155 "/articles/technology/42"
156
157This also works for host variables:
158
159 r := mux.NewRouter()
160 r.Host("{subdomain}.domain.com").
161 Path("/articles/{category}/{id:[0-9]+}").
162 HandlerFunc(ArticleHandler).
163 Name("article")
164
165 // url.String() will be "http://news.domain.com/articles/technology/42"
166 url, err := r.Get("article").URL("subdomain", "news",
167 "category", "technology",
168 "id", "42")
169
170All variables defined in the route are required, and their values must
171conform to the corresponding patterns. These requirements guarantee that a
172generated URL will always match a registered route -- the only exception is
173for explicitly defined "build-only" routes which never match.
174
175Regex support also exists for matching Headers within a route. For example, we could do:
176
177 r.HeadersRegexp("Content-Type", "application/(text|json)")
178
179...and the route will match both requests with a Content-Type of `application/json` as well as
180`application/text`
181
182There's also a way to build only the URL host or path for a route:
183use the methods URLHost() or URLPath() instead. For the previous route,
184we would do:
185
186 // "http://news.domain.com/"
187 host, err := r.Get("article").URLHost("subdomain", "news")
188
189 // "/articles/technology/42"
190 path, err := r.Get("article").URLPath("category", "technology", "id", "42")
191
192And if you use subrouters, host and path defined separately can be built
193as well:
194
195 r := mux.NewRouter()
196 s := r.Host("{subdomain}.domain.com").Subrouter()
197 s.Path("/articles/{category}/{id:[0-9]+}").
198 HandlerFunc(ArticleHandler).
199 Name("article")
200
201 // "http://news.domain.com/articles/technology/42"
202 url, err := r.Get("article").URL("subdomain", "news",
203 "category", "technology",
204 "id", "42")
205*/
206package mux
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/mux.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/mux.go
deleted file mode 100644
index cb03ddf..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/mux.go
+++ /dev/null
@@ -1,481 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package mux
6
7import (
8 "errors"
9 "fmt"
10 "net/http"
11 "path"
12 "regexp"
13
14 "github.com/fsouza/go-dockerclient/external/github.com/gorilla/context"
15)
16
17// NewRouter returns a new router instance.
18func NewRouter() *Router {
19 return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
20}
21
22// Router registers routes to be matched and dispatches a handler.
23//
24// It implements the http.Handler interface, so it can be registered to serve
25// requests:
26//
27// var router = mux.NewRouter()
28//
29// func main() {
30// http.Handle("/", router)
31// }
32//
33// Or, for Google App Engine, register it in a init() function:
34//
35// func init() {
36// http.Handle("/", router)
37// }
38//
39// This will send all incoming requests to the router.
40type Router struct {
41 // Configurable Handler to be used when no route matches.
42 NotFoundHandler http.Handler
43 // Parent route, if this is a subrouter.
44 parent parentRoute
45 // Routes to be matched, in order.
46 routes []*Route
47 // Routes by name for URL building.
48 namedRoutes map[string]*Route
49 // See Router.StrictSlash(). This defines the flag for new routes.
50 strictSlash bool
51 // If true, do not clear the request context after handling the request
52 KeepContext bool
53}
54
55// Match matches registered routes against the request.
56func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
57 for _, route := range r.routes {
58 if route.Match(req, match) {
59 return true
60 }
61 }
62
63 // Closest match for a router (includes sub-routers)
64 if r.NotFoundHandler != nil {
65 match.Handler = r.NotFoundHandler
66 return true
67 }
68 return false
69}
70
71// ServeHTTP dispatches the handler registered in the matched route.
72//
73// When there is a match, the route variables can be retrieved calling
74// mux.Vars(request).
75func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
76 // Clean path to canonical form and redirect.
77 if p := cleanPath(req.URL.Path); p != req.URL.Path {
78
79 // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
80 // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
81 // http://code.google.com/p/go/issues/detail?id=5252
82 url := *req.URL
83 url.Path = p
84 p = url.String()
85
86 w.Header().Set("Location", p)
87 w.WriteHeader(http.StatusMovedPermanently)
88 return
89 }
90 var match RouteMatch
91 var handler http.Handler
92 if r.Match(req, &match) {
93 handler = match.Handler
94 setVars(req, match.Vars)
95 setCurrentRoute(req, match.Route)
96 }
97 if handler == nil {
98 handler = http.NotFoundHandler()
99 }
100 if !r.KeepContext {
101 defer context.Clear(req)
102 }
103 handler.ServeHTTP(w, req)
104}
105
106// Get returns a route registered with the given name.
107func (r *Router) Get(name string) *Route {
108 return r.getNamedRoutes()[name]
109}
110
111// GetRoute returns a route registered with the given name. This method
112// was renamed to Get() and remains here for backwards compatibility.
113func (r *Router) GetRoute(name string) *Route {
114 return r.getNamedRoutes()[name]
115}
116
117// StrictSlash defines the trailing slash behavior for new routes. The initial
118// value is false.
119//
120// When true, if the route path is "/path/", accessing "/path" will redirect
121// to the former and vice versa. In other words, your application will always
122// see the path as specified in the route.
123//
124// When false, if the route path is "/path", accessing "/path/" will not match
125// this route and vice versa.
126//
127// Special case: when a route sets a path prefix using the PathPrefix() method,
128// strict slash is ignored for that route because the redirect behavior can't
129// be determined from a prefix alone. However, any subrouters created from that
130// route inherit the original StrictSlash setting.
131func (r *Router) StrictSlash(value bool) *Router {
132 r.strictSlash = value
133 return r
134}
135
136// ----------------------------------------------------------------------------
137// parentRoute
138// ----------------------------------------------------------------------------
139
140// getNamedRoutes returns the map where named routes are registered.
141func (r *Router) getNamedRoutes() map[string]*Route {
142 if r.namedRoutes == nil {
143 if r.parent != nil {
144 r.namedRoutes = r.parent.getNamedRoutes()
145 } else {
146 r.namedRoutes = make(map[string]*Route)
147 }
148 }
149 return r.namedRoutes
150}
151
152// getRegexpGroup returns regexp definitions from the parent route, if any.
153func (r *Router) getRegexpGroup() *routeRegexpGroup {
154 if r.parent != nil {
155 return r.parent.getRegexpGroup()
156 }
157 return nil
158}
159
160func (r *Router) buildVars(m map[string]string) map[string]string {
161 if r.parent != nil {
162 m = r.parent.buildVars(m)
163 }
164 return m
165}
166
167// ----------------------------------------------------------------------------
168// Route factories
169// ----------------------------------------------------------------------------
170
171// NewRoute registers an empty route.
172func (r *Router) NewRoute() *Route {
173 route := &Route{parent: r, strictSlash: r.strictSlash}
174 r.routes = append(r.routes, route)
175 return route
176}
177
178// Handle registers a new route with a matcher for the URL path.
179// See Route.Path() and Route.Handler().
180func (r *Router) Handle(path string, handler http.Handler) *Route {
181 return r.NewRoute().Path(path).Handler(handler)
182}
183
184// HandleFunc registers a new route with a matcher for the URL path.
185// See Route.Path() and Route.HandlerFunc().
186func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
187 *http.Request)) *Route {
188 return r.NewRoute().Path(path).HandlerFunc(f)
189}
190
191// Headers registers a new route with a matcher for request header values.
192// See Route.Headers().
193func (r *Router) Headers(pairs ...string) *Route {
194 return r.NewRoute().Headers(pairs...)
195}
196
197// Host registers a new route with a matcher for the URL host.
198// See Route.Host().
199func (r *Router) Host(tpl string) *Route {
200 return r.NewRoute().Host(tpl)
201}
202
203// MatcherFunc registers a new route with a custom matcher function.
204// See Route.MatcherFunc().
205func (r *Router) MatcherFunc(f MatcherFunc) *Route {
206 return r.NewRoute().MatcherFunc(f)
207}
208
209// Methods registers a new route with a matcher for HTTP methods.
210// See Route.Methods().
211func (r *Router) Methods(methods ...string) *Route {
212 return r.NewRoute().Methods(methods...)
213}
214
215// Path registers a new route with a matcher for the URL path.
216// See Route.Path().
217func (r *Router) Path(tpl string) *Route {
218 return r.NewRoute().Path(tpl)
219}
220
221// PathPrefix registers a new route with a matcher for the URL path prefix.
222// See Route.PathPrefix().
223func (r *Router) PathPrefix(tpl string) *Route {
224 return r.NewRoute().PathPrefix(tpl)
225}
226
227// Queries registers a new route with a matcher for URL query values.
228// See Route.Queries().
229func (r *Router) Queries(pairs ...string) *Route {
230 return r.NewRoute().Queries(pairs...)
231}
232
233// Schemes registers a new route with a matcher for URL schemes.
234// See Route.Schemes().
235func (r *Router) Schemes(schemes ...string) *Route {
236 return r.NewRoute().Schemes(schemes...)
237}
238
239// BuildVars registers a new route with a custom function for modifying
240// route variables before building a URL.
241func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
242 return r.NewRoute().BuildVarsFunc(f)
243}
244
245// Walk walks the router and all its sub-routers, calling walkFn for each route
246// in the tree. The routes are walked in the order they were added. Sub-routers
247// are explored depth-first.
248func (r *Router) Walk(walkFn WalkFunc) error {
249 return r.walk(walkFn, []*Route{})
250}
251
252// SkipRouter is used as a return value from WalkFuncs to indicate that the
253// router that walk is about to descend down to should be skipped.
254var SkipRouter = errors.New("skip this router")
255
256// WalkFunc is the type of the function called for each route visited by Walk.
257// At every invocation, it is given the current route, and the current router,
258// and a list of ancestor routes that lead to the current route.
259type WalkFunc func(route *Route, router *Router, ancestors []*Route) error
260
261func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
262 for _, t := range r.routes {
263 if t.regexp == nil || t.regexp.path == nil || t.regexp.path.template == "" {
264 continue
265 }
266
267 err := walkFn(t, r, ancestors)
268 if err == SkipRouter {
269 continue
270 }
271 for _, sr := range t.matchers {
272 if h, ok := sr.(*Router); ok {
273 err := h.walk(walkFn, ancestors)
274 if err != nil {
275 return err
276 }
277 }
278 }
279 if h, ok := t.handler.(*Router); ok {
280 ancestors = append(ancestors, t)
281 err := h.walk(walkFn, ancestors)
282 if err != nil {
283 return err
284 }
285 ancestors = ancestors[:len(ancestors)-1]
286 }
287 }
288 return nil
289}
290
291// ----------------------------------------------------------------------------
292// Context
293// ----------------------------------------------------------------------------
294
295// RouteMatch stores information about a matched route.
296type RouteMatch struct {
297 Route *Route
298 Handler http.Handler
299 Vars map[string]string
300}
301
302type contextKey int
303
304const (
305 varsKey contextKey = iota
306 routeKey
307)
308
309// Vars returns the route variables for the current request, if any.
310func Vars(r *http.Request) map[string]string {
311 if rv := context.Get(r, varsKey); rv != nil {
312 return rv.(map[string]string)
313 }
314 return nil
315}
316
317// CurrentRoute returns the matched route for the current request, if any.
318// This only works when called inside the handler of the matched route
319// because the matched route is stored in the request context which is cleared
320// after the handler returns, unless the KeepContext option is set on the
321// Router.
322func CurrentRoute(r *http.Request) *Route {
323 if rv := context.Get(r, routeKey); rv != nil {
324 return rv.(*Route)
325 }
326 return nil
327}
328
329func setVars(r *http.Request, val interface{}) {
330 if val != nil {
331 context.Set(r, varsKey, val)
332 }
333}
334
335func setCurrentRoute(r *http.Request, val interface{}) {
336 if val != nil {
337 context.Set(r, routeKey, val)
338 }
339}
340
341// ----------------------------------------------------------------------------
342// Helpers
343// ----------------------------------------------------------------------------
344
345// cleanPath returns the canonical path for p, eliminating . and .. elements.
346// Borrowed from the net/http package.
347func cleanPath(p string) string {
348 if p == "" {
349 return "/"
350 }
351 if p[0] != '/' {
352 p = "/" + p
353 }
354 np := path.Clean(p)
355 // path.Clean removes trailing slash except for root;
356 // put the trailing slash back if necessary.
357 if p[len(p)-1] == '/' && np != "/" {
358 np += "/"
359 }
360 return np
361}
362
363// uniqueVars returns an error if two slices contain duplicated strings.
364func uniqueVars(s1, s2 []string) error {
365 for _, v1 := range s1 {
366 for _, v2 := range s2 {
367 if v1 == v2 {
368 return fmt.Errorf("mux: duplicated route variable %q", v2)
369 }
370 }
371 }
372 return nil
373}
374
375// checkPairs returns the count of strings passed in, and an error if
376// the count is not an even number.
377func checkPairs(pairs ...string) (int, error) {
378 length := len(pairs)
379 if length%2 != 0 {
380 return length, fmt.Errorf(
381 "mux: number of parameters must be multiple of 2, got %v", pairs)
382 }
383 return length, nil
384}
385
386// mapFromPairsToString converts variadic string parameters to a
387// string to string map.
388func mapFromPairsToString(pairs ...string) (map[string]string, error) {
389 length, err := checkPairs(pairs...)
390 if err != nil {
391 return nil, err
392 }
393 m := make(map[string]string, length/2)
394 for i := 0; i < length; i += 2 {
395 m[pairs[i]] = pairs[i+1]
396 }
397 return m, nil
398}
399
400// mapFromPairsToRegex converts variadic string paramers to a
401// string to regex map.
402func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) {
403 length, err := checkPairs(pairs...)
404 if err != nil {
405 return nil, err
406 }
407 m := make(map[string]*regexp.Regexp, length/2)
408 for i := 0; i < length; i += 2 {
409 regex, err := regexp.Compile(pairs[i+1])
410 if err != nil {
411 return nil, err
412 }
413 m[pairs[i]] = regex
414 }
415 return m, nil
416}
417
418// matchInArray returns true if the given string value is in the array.
419func matchInArray(arr []string, value string) bool {
420 for _, v := range arr {
421 if v == value {
422 return true
423 }
424 }
425 return false
426}
427
428// matchMapWithString returns true if the given key/value pairs exist in a given map.
429func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool {
430 for k, v := range toCheck {
431 // Check if key exists.
432 if canonicalKey {
433 k = http.CanonicalHeaderKey(k)
434 }
435 if values := toMatch[k]; values == nil {
436 return false
437 } else if v != "" {
438 // If value was defined as an empty string we only check that the
439 // key exists. Otherwise we also check for equality.
440 valueExists := false
441 for _, value := range values {
442 if v == value {
443 valueExists = true
444 break
445 }
446 }
447 if !valueExists {
448 return false
449 }
450 }
451 }
452 return true
453}
454
455// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against
456// the given regex
457func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool {
458 for k, v := range toCheck {
459 // Check if key exists.
460 if canonicalKey {
461 k = http.CanonicalHeaderKey(k)
462 }
463 if values := toMatch[k]; values == nil {
464 return false
465 } else if v != nil {
466 // If value was defined as an empty string we only check that the
467 // key exists. Otherwise we also check for equality.
468 valueExists := false
469 for _, value := range values {
470 if v.MatchString(value) {
471 valueExists = true
472 break
473 }
474 }
475 if !valueExists {
476 return false
477 }
478 }
479 }
480 return true
481}
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/regexp.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/regexp.go
deleted file mode 100644
index 06728dd..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/regexp.go
+++ /dev/null
@@ -1,317 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package mux
6
7import (
8 "bytes"
9 "fmt"
10 "net/http"
11 "net/url"
12 "regexp"
13 "strconv"
14 "strings"
15)
16
17// newRouteRegexp parses a route template and returns a routeRegexp,
18// used to match a host, a path or a query string.
19//
20// It will extract named variables, assemble a regexp to be matched, create
21// a "reverse" template to build URLs and compile regexps to validate variable
22// values used in URL building.
23//
24// Previously we accepted only Python-like identifiers for variable
25// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that
26// name and pattern can't be empty, and names can't contain a colon.
27func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash bool) (*routeRegexp, error) {
28 // Check if it is well-formed.
29 idxs, errBraces := braceIndices(tpl)
30 if errBraces != nil {
31 return nil, errBraces
32 }
33 // Backup the original.
34 template := tpl
35 // Now let's parse it.
36 defaultPattern := "[^/]+"
37 if matchQuery {
38 defaultPattern = "[^?&]*"
39 } else if matchHost {
40 defaultPattern = "[^.]+"
41 matchPrefix = false
42 }
43 // Only match strict slash if not matching
44 if matchPrefix || matchHost || matchQuery {
45 strictSlash = false
46 }
47 // Set a flag for strictSlash.
48 endSlash := false
49 if strictSlash && strings.HasSuffix(tpl, "/") {
50 tpl = tpl[:len(tpl)-1]
51 endSlash = true
52 }
53 varsN := make([]string, len(idxs)/2)
54 varsR := make([]*regexp.Regexp, len(idxs)/2)
55 pattern := bytes.NewBufferString("")
56 pattern.WriteByte('^')
57 reverse := bytes.NewBufferString("")
58 var end int
59 var err error
60 for i := 0; i < len(idxs); i += 2 {
61 // Set all values we are interested in.
62 raw := tpl[end:idxs[i]]
63 end = idxs[i+1]
64 parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2)
65 name := parts[0]
66 patt := defaultPattern
67 if len(parts) == 2 {
68 patt = parts[1]
69 }
70 // Name or pattern can't be empty.
71 if name == "" || patt == "" {
72 return nil, fmt.Errorf("mux: missing name or pattern in %q",
73 tpl[idxs[i]:end])
74 }
75 // Build the regexp pattern.
76 varIdx := i / 2
77 fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(varIdx), patt)
78 // Build the reverse template.
79 fmt.Fprintf(reverse, "%s%%s", raw)
80
81 // Append variable name and compiled pattern.
82 varsN[varIdx] = name
83 varsR[varIdx], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
84 if err != nil {
85 return nil, err
86 }
87 }
88 // Add the remaining.
89 raw := tpl[end:]
90 pattern.WriteString(regexp.QuoteMeta(raw))
91 if strictSlash {
92 pattern.WriteString("[/]?")
93 }
94 if matchQuery {
95 // Add the default pattern if the query value is empty
96 if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" {
97 pattern.WriteString(defaultPattern)
98 }
99 }
100 if !matchPrefix {
101 pattern.WriteByte('$')
102 }
103 reverse.WriteString(raw)
104 if endSlash {
105 reverse.WriteByte('/')
106 }
107 // Compile full regexp.
108 reg, errCompile := regexp.Compile(pattern.String())
109 if errCompile != nil {
110 return nil, errCompile
111 }
112 // Done!
113 return &routeRegexp{
114 template: template,
115 matchHost: matchHost,
116 matchQuery: matchQuery,
117 strictSlash: strictSlash,
118 regexp: reg,
119 reverse: reverse.String(),
120 varsN: varsN,
121 varsR: varsR,
122 }, nil
123}
124
125// routeRegexp stores a regexp to match a host or path and information to
126// collect and validate route variables.
127type routeRegexp struct {
128 // The unmodified template.
129 template string
130 // True for host match, false for path or query string match.
131 matchHost bool
132 // True for query string match, false for path and host match.
133 matchQuery bool
134 // The strictSlash value defined on the route, but disabled if PathPrefix was used.
135 strictSlash bool
136 // Expanded regexp.
137 regexp *regexp.Regexp
138 // Reverse template.
139 reverse string
140 // Variable names.
141 varsN []string
142 // Variable regexps (validators).
143 varsR []*regexp.Regexp
144}
145
146// Match matches the regexp against the URL host or path.
147func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
148 if !r.matchHost {
149 if r.matchQuery {
150 return r.matchQueryString(req)
151 } else {
152 return r.regexp.MatchString(req.URL.Path)
153 }
154 }
155 return r.regexp.MatchString(getHost(req))
156}
157
158// url builds a URL part using the given values.
159func (r *routeRegexp) url(values map[string]string) (string, error) {
160 urlValues := make([]interface{}, len(r.varsN))
161 for k, v := range r.varsN {
162 value, ok := values[v]
163 if !ok {
164 return "", fmt.Errorf("mux: missing route variable %q", v)
165 }
166 urlValues[k] = value
167 }
168 rv := fmt.Sprintf(r.reverse, urlValues...)
169 if !r.regexp.MatchString(rv) {
170 // The URL is checked against the full regexp, instead of checking
171 // individual variables. This is faster but to provide a good error
172 // message, we check individual regexps if the URL doesn't match.
173 for k, v := range r.varsN {
174 if !r.varsR[k].MatchString(values[v]) {
175 return "", fmt.Errorf(
176 "mux: variable %q doesn't match, expected %q", values[v],
177 r.varsR[k].String())
178 }
179 }
180 }
181 return rv, nil
182}
183
184// getUrlQuery returns a single query parameter from a request URL.
185// For a URL with foo=bar&baz=ding, we return only the relevant key
186// value pair for the routeRegexp.
187func (r *routeRegexp) getUrlQuery(req *http.Request) string {
188 if !r.matchQuery {
189 return ""
190 }
191 templateKey := strings.SplitN(r.template, "=", 2)[0]
192 for key, vals := range req.URL.Query() {
193 if key == templateKey && len(vals) > 0 {
194 return key + "=" + vals[0]
195 }
196 }
197 return ""
198}
199
200func (r *routeRegexp) matchQueryString(req *http.Request) bool {
201 return r.regexp.MatchString(r.getUrlQuery(req))
202}
203
204// braceIndices returns the first level curly brace indices from a string.
205// It returns an error in case of unbalanced braces.
206func braceIndices(s string) ([]int, error) {
207 var level, idx int
208 idxs := make([]int, 0)
209 for i := 0; i < len(s); i++ {
210 switch s[i] {
211 case '{':
212 if level++; level == 1 {
213 idx = i
214 }
215 case '}':
216 if level--; level == 0 {
217 idxs = append(idxs, idx, i+1)
218 } else if level < 0 {
219 return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
220 }
221 }
222 }
223 if level != 0 {
224 return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
225 }
226 return idxs, nil
227}
228
229// varGroupName builds a capturing group name for the indexed variable.
230func varGroupName(idx int) string {
231 return "v" + strconv.Itoa(idx)
232}
233
234// ----------------------------------------------------------------------------
235// routeRegexpGroup
236// ----------------------------------------------------------------------------
237
238// routeRegexpGroup groups the route matchers that carry variables.
239type routeRegexpGroup struct {
240 host *routeRegexp
241 path *routeRegexp
242 queries []*routeRegexp
243}
244
245// setMatch extracts the variables from the URL once a route matches.
246func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
247 // Store host variables.
248 if v.host != nil {
249 hostVars := v.host.regexp.FindStringSubmatch(getHost(req))
250 if hostVars != nil {
251 subexpNames := v.host.regexp.SubexpNames()
252 varName := 0
253 for i, name := range subexpNames[1:] {
254 if name != "" && name == varGroupName(varName) {
255 m.Vars[v.host.varsN[varName]] = hostVars[i+1]
256 varName++
257 }
258 }
259 }
260 }
261 // Store path variables.
262 if v.path != nil {
263 pathVars := v.path.regexp.FindStringSubmatch(req.URL.Path)
264 if pathVars != nil {
265 subexpNames := v.path.regexp.SubexpNames()
266 varName := 0
267 for i, name := range subexpNames[1:] {
268 if name != "" && name == varGroupName(varName) {
269 m.Vars[v.path.varsN[varName]] = pathVars[i+1]
270 varName++
271 }
272 }
273 // Check if we should redirect.
274 if v.path.strictSlash {
275 p1 := strings.HasSuffix(req.URL.Path, "/")
276 p2 := strings.HasSuffix(v.path.template, "/")
277 if p1 != p2 {
278 u, _ := url.Parse(req.URL.String())
279 if p1 {
280 u.Path = u.Path[:len(u.Path)-1]
281 } else {
282 u.Path += "/"
283 }
284 m.Handler = http.RedirectHandler(u.String(), 301)
285 }
286 }
287 }
288 }
289 // Store query string variables.
290 for _, q := range v.queries {
291 queryVars := q.regexp.FindStringSubmatch(q.getUrlQuery(req))
292 if queryVars != nil {
293 subexpNames := q.regexp.SubexpNames()
294 varName := 0
295 for i, name := range subexpNames[1:] {
296 if name != "" && name == varGroupName(varName) {
297 m.Vars[q.varsN[varName]] = queryVars[i+1]
298 varName++
299 }
300 }
301 }
302 }
303}
304
305// getHost tries its best to return the request host.
306func getHost(r *http.Request) string {
307 if r.URL.IsAbs() {
308 return r.URL.Host
309 }
310 host := r.Host
311 // Slice off any port information.
312 if i := strings.Index(host, ":"); i != -1 {
313 host = host[:i]
314 }
315 return host
316
317}
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go
deleted file mode 100644
index 913432c..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go
+++ /dev/null
@@ -1,595 +0,0 @@
1// Copyright 2012 The Gorilla Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package mux
6
7import (
8 "errors"
9 "fmt"
10 "net/http"
11 "net/url"
12 "regexp"
13 "strings"
14)
15
16// Route stores information to match a request and build URLs.
17type Route struct {
18 // Parent where the route was registered (a Router).
19 parent parentRoute
20 // Request handler for the route.
21 handler http.Handler
22 // List of matchers.
23 matchers []matcher
24 // Manager for the variables from host and path.
25 regexp *routeRegexpGroup
26 // If true, when the path pattern is "/path/", accessing "/path" will
27 // redirect to the former and vice versa.
28 strictSlash bool
29 // If true, this route never matches: it is only used to build URLs.
30 buildOnly bool
31 // The name used to build URLs.
32 name string
33 // Error resulted from building a route.
34 err error
35
36 buildVarsFunc BuildVarsFunc
37}
38
39// Match matches the route against the request.
40func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
41 if r.buildOnly || r.err != nil {
42 return false
43 }
44 // Match everything.
45 for _, m := range r.matchers {
46 if matched := m.Match(req, match); !matched {
47 return false
48 }
49 }
50 // Yay, we have a match. Let's collect some info about it.
51 if match.Route == nil {
52 match.Route = r
53 }
54 if match.Handler == nil {
55 match.Handler = r.handler
56 }
57 if match.Vars == nil {
58 match.Vars = make(map[string]string)
59 }
60 // Set variables.
61 if r.regexp != nil {
62 r.regexp.setMatch(req, match, r)
63 }
64 return true
65}
66
67// ----------------------------------------------------------------------------
68// Route attributes
69// ----------------------------------------------------------------------------
70
71// GetError returns an error resulted from building the route, if any.
72func (r *Route) GetError() error {
73 return r.err
74}
75
76// BuildOnly sets the route to never match: it is only used to build URLs.
77func (r *Route) BuildOnly() *Route {
78 r.buildOnly = true
79 return r
80}
81
82// Handler --------------------------------------------------------------------
83
84// Handler sets a handler for the route.
85func (r *Route) Handler(handler http.Handler) *Route {
86 if r.err == nil {
87 r.handler = handler
88 }
89 return r
90}
91
92// HandlerFunc sets a handler function for the route.
93func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route {
94 return r.Handler(http.HandlerFunc(f))
95}
96
97// GetHandler returns the handler for the route, if any.
98func (r *Route) GetHandler() http.Handler {
99 return r.handler
100}
101
102// Name -----------------------------------------------------------------------
103
104// Name sets the name for the route, used to build URLs.
105// If the name was registered already it will be overwritten.
106func (r *Route) Name(name string) *Route {
107 if r.name != "" {
108 r.err = fmt.Errorf("mux: route already has name %q, can't set %q",
109 r.name, name)
110 }
111 if r.err == nil {
112 r.name = name
113 r.getNamedRoutes()[name] = r
114 }
115 return r
116}
117
118// GetName returns the name for the route, if any.
119func (r *Route) GetName() string {
120 return r.name
121}
122
123// ----------------------------------------------------------------------------
124// Matchers
125// ----------------------------------------------------------------------------
126
127// matcher types try to match a request.
128type matcher interface {
129 Match(*http.Request, *RouteMatch) bool
130}
131
132// addMatcher adds a matcher to the route.
133func (r *Route) addMatcher(m matcher) *Route {
134 if r.err == nil {
135 r.matchers = append(r.matchers, m)
136 }
137 return r
138}
139
140// addRegexpMatcher adds a host or path matcher and builder to a route.
141func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error {
142 if r.err != nil {
143 return r.err
144 }
145 r.regexp = r.getRegexpGroup()
146 if !matchHost && !matchQuery {
147 if len(tpl) == 0 || tpl[0] != '/' {
148 return fmt.Errorf("mux: path must start with a slash, got %q", tpl)
149 }
150 if r.regexp.path != nil {
151 tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl
152 }
153 }
154 rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash)
155 if err != nil {
156 return err
157 }
158 for _, q := range r.regexp.queries {
159 if err = uniqueVars(rr.varsN, q.varsN); err != nil {
160 return err
161 }
162 }
163 if matchHost {
164 if r.regexp.path != nil {
165 if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil {
166 return err
167 }
168 }
169 r.regexp.host = rr
170 } else {
171 if r.regexp.host != nil {
172 if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil {
173 return err
174 }
175 }
176 if matchQuery {
177 r.regexp.queries = append(r.regexp.queries, rr)
178 } else {
179 r.regexp.path = rr
180 }
181 }
182 r.addMatcher(rr)
183 return nil
184}
185
186// Headers --------------------------------------------------------------------
187
188// headerMatcher matches the request against header values.
189type headerMatcher map[string]string
190
191func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
192 return matchMapWithString(m, r.Header, true)
193}
194
195// Headers adds a matcher for request header values.
196// It accepts a sequence of key/value pairs to be matched. For example:
197//
198// r := mux.NewRouter()
199// r.Headers("Content-Type", "application/json",
200// "X-Requested-With", "XMLHttpRequest")
201//
202// The above route will only match if both request header values match.
203// If the value is an empty string, it will match any value if the key is set.
204func (r *Route) Headers(pairs ...string) *Route {
205 if r.err == nil {
206 var headers map[string]string
207 headers, r.err = mapFromPairsToString(pairs...)
208 return r.addMatcher(headerMatcher(headers))
209 }
210 return r
211}
212
213// headerRegexMatcher matches the request against the route given a regex for the header
214type headerRegexMatcher map[string]*regexp.Regexp
215
216func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool {
217 return matchMapWithRegex(m, r.Header, true)
218}
219
220// Regular expressions can be used with headers as well.
221// It accepts a sequence of key/value pairs, where the value has regex support. For example
222// r := mux.NewRouter()
223// r.HeadersRegexp("Content-Type", "application/(text|json)",
224// "X-Requested-With", "XMLHttpRequest")
225//
226// The above route will only match if both the request header matches both regular expressions.
227// It the value is an empty string, it will match any value if the key is set.
228func (r *Route) HeadersRegexp(pairs ...string) *Route {
229 if r.err == nil {
230 var headers map[string]*regexp.Regexp
231 headers, r.err = mapFromPairsToRegex(pairs...)
232 return r.addMatcher(headerRegexMatcher(headers))
233 }
234 return r
235}
236
237// Host -----------------------------------------------------------------------
238
239// Host adds a matcher for the URL host.
240// It accepts a template with zero or more URL variables enclosed by {}.
241// Variables can define an optional regexp pattern to be matched:
242//
243// - {name} matches anything until the next dot.
244//
245// - {name:pattern} matches the given regexp pattern.
246//
247// For example:
248//
249// r := mux.NewRouter()
250// r.Host("www.example.com")
251// r.Host("{subdomain}.domain.com")
252// r.Host("{subdomain:[a-z]+}.domain.com")
253//
254// Variable names must be unique in a given route. They can be retrieved
255// calling mux.Vars(request).
256func (r *Route) Host(tpl string) *Route {
257 r.err = r.addRegexpMatcher(tpl, true, false, false)
258 return r
259}
260
261// MatcherFunc ----------------------------------------------------------------
262
263// MatcherFunc is the function signature used by custom matchers.
264type MatcherFunc func(*http.Request, *RouteMatch) bool
265
266func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
267 return m(r, match)
268}
269
270// MatcherFunc adds a custom function to be used as request matcher.
271func (r *Route) MatcherFunc(f MatcherFunc) *Route {
272 return r.addMatcher(f)
273}
274
275// Methods --------------------------------------------------------------------
276
277// methodMatcher matches the request against HTTP methods.
278type methodMatcher []string
279
280func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool {
281 return matchInArray(m, r.Method)
282}
283
284// Methods adds a matcher for HTTP methods.
285// It accepts a sequence of one or more methods to be matched, e.g.:
286// "GET", "POST", "PUT".
287func (r *Route) Methods(methods ...string) *Route {
288 for k, v := range methods {
289 methods[k] = strings.ToUpper(v)
290 }
291 return r.addMatcher(methodMatcher(methods))
292}
293
294// Path -----------------------------------------------------------------------
295
296// Path adds a matcher for the URL path.
297// It accepts a template with zero or more URL variables enclosed by {}. The
298// template must start with a "/".
299// Variables can define an optional regexp pattern to be matched:
300//
301// - {name} matches anything until the next slash.
302//
303// - {name:pattern} matches the given regexp pattern.
304//
305// For example:
306//
307// r := mux.NewRouter()
308// r.Path("/products/").Handler(ProductsHandler)
309// r.Path("/products/{key}").Handler(ProductsHandler)
310// r.Path("/articles/{category}/{id:[0-9]+}").
311// Handler(ArticleHandler)
312//
313// Variable names must be unique in a given route. They can be retrieved
314// calling mux.Vars(request).
315func (r *Route) Path(tpl string) *Route {
316 r.err = r.addRegexpMatcher(tpl, false, false, false)
317 return r
318}
319
320// PathPrefix -----------------------------------------------------------------
321
322// PathPrefix adds a matcher for the URL path prefix. This matches if the given
323// template is a prefix of the full URL path. See Route.Path() for details on
324// the tpl argument.
325//
326// Note that it does not treat slashes specially ("/foobar/" will be matched by
327// the prefix "/foo") so you may want to use a trailing slash here.
328//
329// Also note that the setting of Router.StrictSlash() has no effect on routes
330// with a PathPrefix matcher.
331func (r *Route) PathPrefix(tpl string) *Route {
332 r.err = r.addRegexpMatcher(tpl, false, true, false)
333 return r
334}
335
336// Query ----------------------------------------------------------------------
337
338// Queries adds a matcher for URL query values.
339// It accepts a sequence of key/value pairs. Values may define variables.
340// For example:
341//
342// r := mux.NewRouter()
343// r.Queries("foo", "bar", "id", "{id:[0-9]+}")
344//
345// The above route will only match if the URL contains the defined queries
346// values, e.g.: ?foo=bar&id=42.
347//
348// It the value is an empty string, it will match any value if the key is set.
349//
350// Variables can define an optional regexp pattern to be matched:
351//
352// - {name} matches anything until the next slash.
353//
354// - {name:pattern} matches the given regexp pattern.
355func (r *Route) Queries(pairs ...string) *Route {
356 length := len(pairs)
357 if length%2 != 0 {
358 r.err = fmt.Errorf(
359 "mux: number of parameters must be multiple of 2, got %v", pairs)
360 return nil
361 }
362 for i := 0; i < length; i += 2 {
363 if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil {
364 return r
365 }
366 }
367
368 return r
369}
370
371// Schemes --------------------------------------------------------------------
372
373// schemeMatcher matches the request against URL schemes.
374type schemeMatcher []string
375
376func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
377 return matchInArray(m, r.URL.Scheme)
378}
379
380// Schemes adds a matcher for URL schemes.
381// It accepts a sequence of schemes to be matched, e.g.: "http", "https".
382func (r *Route) Schemes(schemes ...string) *Route {
383 for k, v := range schemes {
384 schemes[k] = strings.ToLower(v)
385 }
386 return r.addMatcher(schemeMatcher(schemes))
387}
388
389// BuildVarsFunc --------------------------------------------------------------
390
391// BuildVarsFunc is the function signature used by custom build variable
392// functions (which can modify route variables before a route's URL is built).
393type BuildVarsFunc func(map[string]string) map[string]string
394
395// BuildVarsFunc adds a custom function to be used to modify build variables
396// before a route's URL is built.
397func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
398 r.buildVarsFunc = f
399 return r
400}
401
402// Subrouter ------------------------------------------------------------------
403
404// Subrouter creates a subrouter for the route.
405//
406// It will test the inner routes only if the parent route matched. For example:
407//
408// r := mux.NewRouter()
409// s := r.Host("www.example.com").Subrouter()
410// s.HandleFunc("/products/", ProductsHandler)
411// s.HandleFunc("/products/{key}", ProductHandler)
412// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
413//
414// Here, the routes registered in the subrouter won't be tested if the host
415// doesn't match.
416func (r *Route) Subrouter() *Router {
417 router := &Router{parent: r, strictSlash: r.strictSlash}
418 r.addMatcher(router)
419 return router
420}
421
422// ----------------------------------------------------------------------------
423// URL building
424// ----------------------------------------------------------------------------
425
426// URL builds a URL for the route.
427//
428// It accepts a sequence of key/value pairs for the route variables. For
429// example, given this route:
430//
431// r := mux.NewRouter()
432// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
433// Name("article")
434//
435// ...a URL for it can be built using:
436//
437// url, err := r.Get("article").URL("category", "technology", "id", "42")
438//
439// ...which will return an url.URL with the following path:
440//
441// "/articles/technology/42"
442//
443// This also works for host variables:
444//
445// r := mux.NewRouter()
446// r.Host("{subdomain}.domain.com").
447// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
448// Name("article")
449//
450// // url.String() will be "http://news.domain.com/articles/technology/42"
451// url, err := r.Get("article").URL("subdomain", "news",
452// "category", "technology",
453// "id", "42")
454//
455// All variables defined in the route are required, and their values must
456// conform to the corresponding patterns.
457func (r *Route) URL(pairs ...string) (*url.URL, error) {
458 if r.err != nil {
459 return nil, r.err
460 }
461 if r.regexp == nil {
462 return nil, errors.New("mux: route doesn't have a host or path")
463 }
464 values, err := r.prepareVars(pairs...)
465 if err != nil {
466 return nil, err
467 }
468 var scheme, host, path string
469 if r.regexp.host != nil {
470 // Set a default scheme.
471 scheme = "http"
472 if host, err = r.regexp.host.url(values); err != nil {
473 return nil, err
474 }
475 }
476 if r.regexp.path != nil {
477 if path, err = r.regexp.path.url(values); err != nil {
478 return nil, err
479 }
480 }
481 return &url.URL{
482 Scheme: scheme,
483 Host: host,
484 Path: path,
485 }, nil
486}
487
488// URLHost builds the host part of the URL for a route. See Route.URL().
489//
490// The route must have a host defined.
491func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
492 if r.err != nil {
493 return nil, r.err
494 }
495 if r.regexp == nil || r.regexp.host == nil {
496 return nil, errors.New("mux: route doesn't have a host")
497 }
498 values, err := r.prepareVars(pairs...)
499 if err != nil {
500 return nil, err
501 }
502 host, err := r.regexp.host.url(values)
503 if err != nil {
504 return nil, err
505 }
506 return &url.URL{
507 Scheme: "http",
508 Host: host,
509 }, nil
510}
511
512// URLPath builds the path part of the URL for a route. See Route.URL().
513//
514// The route must have a path defined.
515func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
516 if r.err != nil {
517 return nil, r.err
518 }
519 if r.regexp == nil || r.regexp.path == nil {
520 return nil, errors.New("mux: route doesn't have a path")
521 }
522 values, err := r.prepareVars(pairs...)
523 if err != nil {
524 return nil, err
525 }
526 path, err := r.regexp.path.url(values)
527 if err != nil {
528 return nil, err
529 }
530 return &url.URL{
531 Path: path,
532 }, nil
533}
534
535// prepareVars converts the route variable pairs into a map. If the route has a
536// BuildVarsFunc, it is invoked.
537func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
538 m, err := mapFromPairsToString(pairs...)
539 if err != nil {
540 return nil, err
541 }
542 return r.buildVars(m), nil
543}
544
545func (r *Route) buildVars(m map[string]string) map[string]string {
546 if r.parent != nil {
547 m = r.parent.buildVars(m)
548 }
549 if r.buildVarsFunc != nil {
550 m = r.buildVarsFunc(m)
551 }
552 return m
553}
554
555// ----------------------------------------------------------------------------
556// parentRoute
557// ----------------------------------------------------------------------------
558
559// parentRoute allows routes to know about parent host and path definitions.
560type parentRoute interface {
561 getNamedRoutes() map[string]*Route
562 getRegexpGroup() *routeRegexpGroup
563 buildVars(map[string]string) map[string]string
564}
565
566// getNamedRoutes returns the map where named routes are registered.
567func (r *Route) getNamedRoutes() map[string]*Route {
568 if r.parent == nil {
569 // During tests router is not always set.
570 r.parent = NewRouter()
571 }
572 return r.parent.getNamedRoutes()
573}
574
575// getRegexpGroup returns regexp definitions from this route.
576func (r *Route) getRegexpGroup() *routeRegexpGroup {
577 if r.regexp == nil {
578 if r.parent == nil {
579 // During tests router is not always set.
580 r.parent = NewRouter()
581 }
582 regexp := r.parent.getRegexpGroup()
583 if regexp == nil {
584 r.regexp = new(routeRegexpGroup)
585 } else {
586 // Copy.
587 r.regexp = &routeRegexpGroup{
588 host: regexp.host,
589 path: regexp.path,
590 queries: regexp.queries,
591 }
592 }
593 }
594 return r.regexp
595}