aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go')
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/gorilla/mux/route.go595
1 files changed, 0 insertions, 595 deletions
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}