diff --git a/Gopkg.lock b/Gopkg.lock index 39b44c65dc84e..7c54448e741f1 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -417,37 +417,6 @@ pruneopts = "NUT" revision = "5f1c01d9f64b941dd9582c638279d046eda6ca31" -[[projects]] - digest = "1:c01767916c59f084bb7c41a7d5877c0f3099b1595cfa066e84ec6ad6b084dd89" - name = "github.com/gorilla/context" - packages = ["."] - pruneopts = "NUT" - revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" - version = "v1.1.1" - -[[projects]] - digest = "1:9ad9280c98033812aec525d43d4e8137021642dc942bf271b4710f9ac93d0d0b" - name = "github.com/gorilla/mux" - packages = ["."] - pruneopts = "NUT" - revision = "757bef944d0f21880861c2dd9c871ca543023cba" - -[[projects]] - digest = "1:0faa8131e5822f3420f82426667a29c5c425c3cb7e0fcf0c5d1c718d6e6ba19b" - name = "github.com/gorilla/securecookie" - packages = ["."] - pruneopts = "NUT" - revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983" - version = "v1.1.1" - -[[projects]] - digest = "1:ee5531f1e32c0082a6da68a605bc60284711d99b15d38dfba335a1ec52a58c20" - name = "github.com/gorilla/sessions" - packages = ["."] - pruneopts = "NUT" - revision = "ca9ada44574153444b00d3fd9c8559e4cc95f896" - version = "v1.1" - [[projects]] digest = "1:18231f2a4af6633fbcd94baab40320d16e826a7f732094ba3420ab547206949b" name = "github.com/issue9/identicon" @@ -951,7 +920,6 @@ "github.com/go-xorm/xorm", "github.com/gogits/chardet", "github.com/gogits/cron", - "github.com/gorilla/context", "github.com/issue9/identicon", "github.com/jaytaylor/html2text", "github.com/kballard/go-shellquote", diff --git a/Gopkg.toml b/Gopkg.toml index 3089b7fd4d23b..e11a743e912be 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -39,14 +39,6 @@ ignored = ["google.golang.org/appengine*"] name = "github.com/go-sql-driver/mysql" revision = "d523deb1b23d913de5bdada721a6071e71283618" -[[override]] - name = "github.com/gorilla/mux" - revision = "757bef944d0f21880861c2dd9c871ca543023cba" - -[[constraint]] - name = "github.com/gorilla/context" - version = "1.1.1" - [[constraint]] name = "github.com/lafriks/xormstore" version = "1.0.0" diff --git a/cmd/web.go b/cmd/web.go index 49917212116d4..dc8df8b59f291 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -21,7 +21,6 @@ import ( "code.gitea.io/gitea/routers/routes" "github.com/Unknwon/com" - context2 "github.com/gorilla/context" "github.com/urfave/cli" "golang.org/x/crypto/acme/autocert" ini "gopkg.in/ini.v1" @@ -66,7 +65,7 @@ func runHTTPRedirector() { http.Redirect(w, r, target, http.StatusTemporaryRedirect) }) - var err = runHTTP(source, context2.ClearHandler(handler)) + var err = runHTTP(source, handler) if err != nil { log.Fatal(4, "Failed to start port redirection: %v", err) @@ -170,23 +169,23 @@ func runWeb(ctx *cli.Context) error { var err error switch setting.Protocol { case setting.HTTP: - err = runHTTP(listenAddr, context2.ClearHandler(m)) + err = runHTTP(listenAddr, m) case setting.HTTPS: if setting.EnableLetsEncrypt { - err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m)) + err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, m) break } if setting.RedirectOtherPort { go runHTTPRedirector() } - err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m)) + err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, m) case setting.FCGI: listener, err := net.Listen("tcp", listenAddr) if err != nil { log.Fatal(4, "Failed to bind %s", listenAddr, err) } defer listener.Close() - err = fcgi.Serve(listener, context2.ClearHandler(m)) + err = fcgi.Serve(listener, m) case setting.UnixSocket: if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) { log.Fatal(4, "Failed to remove unix socket directory %s: %v", listenAddr, err) @@ -202,7 +201,7 @@ func runWeb(ctx *cli.Context) error { if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil { log.Fatal(4, "Failed to set permission of unix socket: %v", err) } - err = http.Serve(listener, context2.ClearHandler(m)) + err = http.Serve(listener, m) default: log.Fatal(4, "Invalid protocol: %s", setting.Protocol) } diff --git a/contrib/autoboot.sh b/contrib/autoboot.sh deleted file mode 100755 index eb16d58170f52..0000000000000 --- a/contrib/autoboot.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -su git -c "/home/git/gogs/scripts/gogs_supervisord.sh restart" diff --git a/contrib/mysql.sql b/contrib/mysql.sql deleted file mode 100644 index aad8beddfa72a..0000000000000 --- a/contrib/mysql.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP DATABASE IF EXISTS gitea; -CREATE DATABASE IF NOT EXISTS gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; diff --git a/vendor/github.com/gorilla/context/LICENSE b/vendor/github.com/gorilla/context/LICENSE deleted file mode 100644 index 0e5fb872800da..0000000000000 --- a/vendor/github.com/gorilla/context/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/context/context.go b/vendor/github.com/gorilla/context/context.go deleted file mode 100644 index 81cb128b19cad..0000000000000 --- a/vendor/github.com/gorilla/context/context.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package context - -import ( - "net/http" - "sync" - "time" -) - -var ( - mutex sync.RWMutex - data = make(map[*http.Request]map[interface{}]interface{}) - datat = make(map[*http.Request]int64) -) - -// Set stores a value for a given key in a given request. -func Set(r *http.Request, key, val interface{}) { - mutex.Lock() - if data[r] == nil { - data[r] = make(map[interface{}]interface{}) - datat[r] = time.Now().Unix() - } - data[r][key] = val - mutex.Unlock() -} - -// Get returns a value stored for a given key in a given request. -func Get(r *http.Request, key interface{}) interface{} { - mutex.RLock() - if ctx := data[r]; ctx != nil { - value := ctx[key] - mutex.RUnlock() - return value - } - mutex.RUnlock() - return nil -} - -// GetOk returns stored value and presence state like multi-value return of map access. -func GetOk(r *http.Request, key interface{}) (interface{}, bool) { - mutex.RLock() - if _, ok := data[r]; ok { - value, ok := data[r][key] - mutex.RUnlock() - return value, ok - } - mutex.RUnlock() - return nil, false -} - -// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests. -func GetAll(r *http.Request) map[interface{}]interface{} { - mutex.RLock() - if context, ok := data[r]; ok { - result := make(map[interface{}]interface{}, len(context)) - for k, v := range context { - result[k] = v - } - mutex.RUnlock() - return result - } - mutex.RUnlock() - return nil -} - -// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if -// the request was registered. -func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { - mutex.RLock() - context, ok := data[r] - result := make(map[interface{}]interface{}, len(context)) - for k, v := range context { - result[k] = v - } - mutex.RUnlock() - return result, ok -} - -// Delete removes a value stored for a given key in a given request. -func Delete(r *http.Request, key interface{}) { - mutex.Lock() - if data[r] != nil { - delete(data[r], key) - } - mutex.Unlock() -} - -// Clear removes all values stored for a given request. -// -// This is usually called by a handler wrapper to clean up request -// variables at the end of a request lifetime. See ClearHandler(). -func Clear(r *http.Request) { - mutex.Lock() - clear(r) - mutex.Unlock() -} - -// clear is Clear without the lock. -func clear(r *http.Request) { - delete(data, r) - delete(datat, r) -} - -// Purge removes request data stored for longer than maxAge, in seconds. -// It returns the amount of requests removed. -// -// If maxAge <= 0, all request data is removed. -// -// This is only used for sanity check: in case context cleaning was not -// properly set some request data can be kept forever, consuming an increasing -// amount of memory. In case this is detected, Purge() must be called -// periodically until the problem is fixed. -func Purge(maxAge int) int { - mutex.Lock() - count := 0 - if maxAge <= 0 { - count = len(data) - data = make(map[*http.Request]map[interface{}]interface{}) - datat = make(map[*http.Request]int64) - } else { - min := time.Now().Unix() - int64(maxAge) - for r := range data { - if datat[r] < min { - clear(r) - count++ - } - } - } - mutex.Unlock() - return count -} - -// ClearHandler wraps an http.Handler and clears request values at the end -// of a request lifetime. -func ClearHandler(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - defer Clear(r) - h.ServeHTTP(w, r) - }) -} diff --git a/vendor/github.com/gorilla/context/doc.go b/vendor/github.com/gorilla/context/doc.go deleted file mode 100644 index 448d1bfcac6e1..0000000000000 --- a/vendor/github.com/gorilla/context/doc.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package context stores values shared during a request lifetime. - -Note: gorilla/context, having been born well before `context.Context` existed, -does not play well > with the shallow copying of the request that -[`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) -(added to net/http Go 1.7 onwards) performs. You should either use *just* -gorilla/context, or moving forward, the new `http.Request.Context()`. - -For example, a router can set variables extracted from the URL and later -application handlers can access those values, or it can be used to store -sessions values to be saved at the end of a request. There are several -others common uses. - -The idea was posted by Brad Fitzpatrick to the go-nuts mailing list: - - http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53 - -Here's the basic usage: first define the keys that you will need. The key -type is interface{} so a key can be of any type that supports equality. -Here we define a key using a custom int type to avoid name collisions: - - package foo - - import ( - "github.com/gorilla/context" - ) - - type key int - - const MyKey key = 0 - -Then set a variable. Variables are bound to an http.Request object, so you -need a request instance to set a value: - - context.Set(r, MyKey, "bar") - -The application can later access the variable using the same key you provided: - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // val is "bar". - val := context.Get(r, foo.MyKey) - - // returns ("bar", true) - val, ok := context.GetOk(r, foo.MyKey) - // ... - } - -And that's all about the basic usage. We discuss some other ideas below. - -Any type can be stored in the context. To enforce a given type, make the key -private and wrap Get() and Set() to accept and return values of a specific -type: - - type key int - - const mykey key = 0 - - // GetMyKey returns a value for this package from the request values. - func GetMyKey(r *http.Request) SomeType { - if rv := context.Get(r, mykey); rv != nil { - return rv.(SomeType) - } - return nil - } - - // SetMyKey sets a value for this package in the request values. - func SetMyKey(r *http.Request, val SomeType) { - context.Set(r, mykey, val) - } - -Variables must be cleared at the end of a request, to remove all values -that were stored. This can be done in an http.Handler, after a request was -served. Just call Clear() passing the request: - - context.Clear(r) - -...or use ClearHandler(), which conveniently wraps an http.Handler to clear -variables at the end of a request lifetime. - -The Routers from the packages gorilla/mux and gorilla/pat call Clear() -so if you are using either of them you don't need to clear the context manually. -*/ -package context diff --git a/vendor/github.com/gorilla/mux/LICENSE b/vendor/github.com/gorilla/mux/LICENSE deleted file mode 100644 index 0e5fb872800da..0000000000000 --- a/vendor/github.com/gorilla/mux/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/mux/context_gorilla.go b/vendor/github.com/gorilla/mux/context_gorilla.go deleted file mode 100644 index d7adaa8fad4fa..0000000000000 --- a/vendor/github.com/gorilla/mux/context_gorilla.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !go1.7 - -package mux - -import ( - "net/http" - - "github.com/gorilla/context" -) - -func contextGet(r *http.Request, key interface{}) interface{} { - return context.Get(r, key) -} - -func contextSet(r *http.Request, key, val interface{}) *http.Request { - if val == nil { - return r - } - - context.Set(r, key, val) - return r -} - -func contextClear(r *http.Request) { - context.Clear(r) -} diff --git a/vendor/github.com/gorilla/mux/context_native.go b/vendor/github.com/gorilla/mux/context_native.go deleted file mode 100644 index 209cbea7d6617..0000000000000 --- a/vendor/github.com/gorilla/mux/context_native.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build go1.7 - -package mux - -import ( - "context" - "net/http" -) - -func contextGet(r *http.Request, key interface{}) interface{} { - return r.Context().Value(key) -} - -func contextSet(r *http.Request, key, val interface{}) *http.Request { - if val == nil { - return r - } - - return r.WithContext(context.WithValue(r.Context(), key, val)) -} - -func contextClear(r *http.Request) { - return -} diff --git a/vendor/github.com/gorilla/mux/doc.go b/vendor/github.com/gorilla/mux/doc.go deleted file mode 100644 index e9573dd8ad17b..0000000000000 --- a/vendor/github.com/gorilla/mux/doc.go +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package mux implements a request router and dispatcher. - -The name mux stands for "HTTP request multiplexer". Like the standard -http.ServeMux, mux.Router matches incoming requests against a list of -registered routes and calls a handler for the route that matches the URL -or other conditions. The main features are: - - * Requests can be matched based on URL host, path, path prefix, schemes, - header and query values, HTTP methods or using custom matchers. - * URL hosts and paths can have variables with an optional regular - expression. - * Registered URLs can be built, or "reversed", which helps maintaining - references to resources. - * Routes can be used as subrouters: nested routes are only tested if the - parent route matches. This is useful to define groups of routes that - share common conditions like a host, a path prefix or other repeated - attributes. As a bonus, this optimizes request matching. - * It implements the http.Handler interface so it is compatible with the - standard http.ServeMux. - -Let's start registering a couple of URL paths and handlers: - - func main() { - r := mux.NewRouter() - r.HandleFunc("/", HomeHandler) - r.HandleFunc("/products", ProductsHandler) - r.HandleFunc("/articles", ArticlesHandler) - http.Handle("/", r) - } - -Here we register three routes mapping URL paths to handlers. This is -equivalent to how http.HandleFunc() works: if an incoming request URL matches -one of the paths, the corresponding handler is called passing -(http.ResponseWriter, *http.Request) as parameters. - -Paths can have variables. They are defined using the format {name} or -{name:pattern}. If a regular expression pattern is not defined, the matched -variable will be anything until the next slash. For example: - - r := mux.NewRouter() - r.HandleFunc("/products/{key}", ProductHandler) - r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) - -Groups can be used inside patterns, as long as they are non-capturing (?:re). For example: - - r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler) - -The names are used to create a map of route variables which can be retrieved -calling mux.Vars(): - - vars := mux.Vars(request) - category := vars["category"] - -And this is all you need to know about the basic usage. More advanced options -are explained below. - -Routes can also be restricted to a domain or subdomain. Just define a host -pattern to be matched. They can also have variables: - - r := mux.NewRouter() - // Only matches if domain is "www.example.com". - r.Host("www.example.com") - // Matches a dynamic subdomain. - r.Host("{subdomain:[a-z]+}.domain.com") - -There are several other matchers that can be added. To match path prefixes: - - r.PathPrefix("/products/") - -...or HTTP methods: - - r.Methods("GET", "POST") - -...or URL schemes: - - r.Schemes("https") - -...or header values: - - r.Headers("X-Requested-With", "XMLHttpRequest") - -...or query values: - - r.Queries("key", "value") - -...or to use a custom matcher function: - - r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { - return r.ProtoMajor == 0 - }) - -...and finally, it is possible to combine several matchers in a single route: - - r.HandleFunc("/products", ProductsHandler). - Host("www.example.com"). - Methods("GET"). - Schemes("http") - -Setting the same matching conditions again and again can be boring, so we have -a way to group several routes that share the same requirements. -We call it "subrouting". - -For example, let's say we have several URLs that should only match when the -host is "www.example.com". Create a route for that host and get a "subrouter" -from it: - - r := mux.NewRouter() - s := r.Host("www.example.com").Subrouter() - -Then register routes in the subrouter: - - s.HandleFunc("/products/", ProductsHandler) - s.HandleFunc("/products/{key}", ProductHandler) - s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) - -The three URL paths we registered above will only be tested if the domain is -"www.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. - -Subrouters can be used to create domain or path "namespaces": you define -subrouters in a central place and then parts of the app can register its -paths relatively to a given subrouter. - -There's one more thing about subroutes. When a subrouter has a path prefix, -the inner routes use it as base for their paths: - - r := mux.NewRouter() - s := r.PathPrefix("/products").Subrouter() - // "/products/" - s.HandleFunc("/", ProductsHandler) - // "/products/{key}/" - s.HandleFunc("/{key}/", ProductHandler) - // "/products/{key}/details" - s.HandleFunc("/{key}/details", ProductDetailsHandler) - -Note that the path provided to PathPrefix() represents a "wildcard": calling -PathPrefix("/static/").Handler(...) means that the handler will be passed any -request that matches "/static/*". This makes it easy to serve static files with mux: - - func main() { - var dir string - - flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir") - flag.Parse() - r := mux.NewRouter() - - // This will serve files under http://localhost:8000/static/ - r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) - - srv := &http.Server{ - Handler: r, - Addr: "127.0.0.1:8000", - // Good practice: enforce timeouts for servers you create! - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - } - - log.Fatal(srv.ListenAndServe()) - } - -Now let's see how to build registered URLs. - -Routes can be named. All routes that define a name can have their URLs built, -or "reversed". We define a name calling Name() on a route. For example: - - r := mux.NewRouter() - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). - Name("article") - -To build a URL, get the route and call the URL() method, passing a sequence of -key/value pairs for the route variables. For the previous route, we would do: - - url, err := r.Get("article").URL("category", "technology", "id", "42") - -...and the result will be a url.URL with the following path: - - "/articles/technology/42" - -This also works for host variables: - - r := mux.NewRouter() - r.Host("{subdomain}.domain.com"). - Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - - // url.String() will be "http://news.domain.com/articles/technology/42" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") - -All variables defined in the route are required, and their values must -conform to the corresponding patterns. These requirements guarantee that a -generated URL will always match a registered route -- the only exception is -for explicitly defined "build-only" routes which never match. - -Regex support also exists for matching Headers within a route. For example, we could do: - - r.HeadersRegexp("Content-Type", "application/(text|json)") - -...and the route will match both requests with a Content-Type of `application/json` as well as -`application/text` - -There's also a way to build only the URL host or path for a route: -use the methods URLHost() or URLPath() instead. For the previous route, -we would do: - - // "http://news.domain.com/" - host, err := r.Get("article").URLHost("subdomain", "news") - - // "/articles/technology/42" - path, err := r.Get("article").URLPath("category", "technology", "id", "42") - -And if you use subrouters, host and path defined separately can be built -as well: - - r := mux.NewRouter() - s := r.Host("{subdomain}.domain.com").Subrouter() - s.Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - - // "http://news.domain.com/articles/technology/42" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") -*/ -package mux diff --git a/vendor/github.com/gorilla/mux/mux.go b/vendor/github.com/gorilla/mux/mux.go deleted file mode 100644 index d66ec38415fd3..0000000000000 --- a/vendor/github.com/gorilla/mux/mux.go +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mux - -import ( - "errors" - "fmt" - "net/http" - "path" - "regexp" - "strings" -) - -// NewRouter returns a new router instance. -func NewRouter() *Router { - return &Router{namedRoutes: make(map[string]*Route), KeepContext: false} -} - -// Router registers routes to be matched and dispatches a handler. -// -// It implements the http.Handler interface, so it can be registered to serve -// requests: -// -// var router = mux.NewRouter() -// -// func main() { -// http.Handle("/", router) -// } -// -// Or, for Google App Engine, register it in a init() function: -// -// func init() { -// http.Handle("/", router) -// } -// -// This will send all incoming requests to the router. -type Router struct { - // Configurable Handler to be used when no route matches. - NotFoundHandler http.Handler - // Parent route, if this is a subrouter. - parent parentRoute - // Routes to be matched, in order. - routes []*Route - // Routes by name for URL building. - namedRoutes map[string]*Route - // See Router.StrictSlash(). This defines the flag for new routes. - strictSlash bool - // See Router.SkipClean(). This defines the flag for new routes. - skipClean bool - // If true, do not clear the request context after handling the request. - // This has no effect when go1.7+ is used, since the context is stored - // on the request itself. - KeepContext bool - // see Router.UseEncodedPath(). This defines a flag for all routes. - useEncodedPath bool -} - -// Match matches registered routes against the request. -func (r *Router) Match(req *http.Request, match *RouteMatch) bool { - for _, route := range r.routes { - if route.Match(req, match) { - return true - } - } - - // Closest match for a router (includes sub-routers) - if r.NotFoundHandler != nil { - match.Handler = r.NotFoundHandler - return true - } - return false -} - -// ServeHTTP dispatches the handler registered in the matched route. -// -// When there is a match, the route variables can be retrieved calling -// mux.Vars(request). -func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { - if !r.skipClean { - path := req.URL.Path - if r.useEncodedPath { - path = getPath(req) - } - // Clean path to canonical form and redirect. - if p := cleanPath(path); p != path { - - // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query. - // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: - // http://code.google.com/p/go/issues/detail?id=5252 - url := *req.URL - url.Path = p - p = url.String() - - w.Header().Set("Location", p) - w.WriteHeader(http.StatusMovedPermanently) - return - } - } - var match RouteMatch - var handler http.Handler - if r.Match(req, &match) { - handler = match.Handler - req = setVars(req, match.Vars) - req = setCurrentRoute(req, match.Route) - } - if handler == nil { - handler = http.NotFoundHandler() - } - if !r.KeepContext { - defer contextClear(req) - } - handler.ServeHTTP(w, req) -} - -// Get returns a route registered with the given name. -func (r *Router) Get(name string) *Route { - return r.getNamedRoutes()[name] -} - -// GetRoute returns a route registered with the given name. This method -// was renamed to Get() and remains here for backwards compatibility. -func (r *Router) GetRoute(name string) *Route { - return r.getNamedRoutes()[name] -} - -// StrictSlash defines the trailing slash behavior for new routes. The initial -// value is false. -// -// When true, if the route path is "/path/", accessing "/path" will redirect -// to the former and vice versa. In other words, your application will always -// see the path as specified in the route. -// -// When false, if the route path is "/path", accessing "/path/" will not match -// this route and vice versa. -// -// Special case: when a route sets a path prefix using the PathPrefix() method, -// strict slash is ignored for that route because the redirect behavior can't -// be determined from a prefix alone. However, any subrouters created from that -// route inherit the original StrictSlash setting. -func (r *Router) StrictSlash(value bool) *Router { - r.strictSlash = value - return r -} - -// SkipClean defines the path cleaning behaviour for new routes. The initial -// value is false. Users should be careful about which routes are not cleaned -// -// When true, if the route path is "/path//to", it will remain with the double -// slash. This is helpful if you have a route like: /fetch/http://xkcd.com/534/ -// -// When false, the path will be cleaned, so /fetch/http://xkcd.com/534/ will -// become /fetch/http/xkcd.com/534 -func (r *Router) SkipClean(value bool) *Router { - r.skipClean = value - return r -} - -// UseEncodedPath tells the router to match the encoded original path -// to the routes. -// For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to". -// This behavior has the drawback of needing to match routes against -// r.RequestURI instead of r.URL.Path. Any modifications (such as http.StripPrefix) -// to r.URL.Path will not affect routing when this flag is on and thus may -// induce unintended behavior. -// -// If not called, the router will match the unencoded path to the routes. -// For eg. "/path/foo%2Fbar/to" will match the path "/path/foo/bar/to" -func (r *Router) UseEncodedPath() *Router { - r.useEncodedPath = true - return r -} - -// ---------------------------------------------------------------------------- -// parentRoute -// ---------------------------------------------------------------------------- - -// getNamedRoutes returns the map where named routes are registered. -func (r *Router) getNamedRoutes() map[string]*Route { - if r.namedRoutes == nil { - if r.parent != nil { - r.namedRoutes = r.parent.getNamedRoutes() - } else { - r.namedRoutes = make(map[string]*Route) - } - } - return r.namedRoutes -} - -// getRegexpGroup returns regexp definitions from the parent route, if any. -func (r *Router) getRegexpGroup() *routeRegexpGroup { - if r.parent != nil { - return r.parent.getRegexpGroup() - } - return nil -} - -func (r *Router) buildVars(m map[string]string) map[string]string { - if r.parent != nil { - m = r.parent.buildVars(m) - } - return m -} - -// ---------------------------------------------------------------------------- -// Route factories -// ---------------------------------------------------------------------------- - -// NewRoute registers an empty route. -func (r *Router) NewRoute() *Route { - route := &Route{parent: r, strictSlash: r.strictSlash, skipClean: r.skipClean, useEncodedPath: r.useEncodedPath} - r.routes = append(r.routes, route) - return route -} - -// Handle registers a new route with a matcher for the URL path. -// See Route.Path() and Route.Handler(). -func (r *Router) Handle(path string, handler http.Handler) *Route { - return r.NewRoute().Path(path).Handler(handler) -} - -// HandleFunc registers a new route with a matcher for the URL path. -// See Route.Path() and Route.HandlerFunc(). -func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, - *http.Request)) *Route { - return r.NewRoute().Path(path).HandlerFunc(f) -} - -// Headers registers a new route with a matcher for request header values. -// See Route.Headers(). -func (r *Router) Headers(pairs ...string) *Route { - return r.NewRoute().Headers(pairs...) -} - -// Host registers a new route with a matcher for the URL host. -// See Route.Host(). -func (r *Router) Host(tpl string) *Route { - return r.NewRoute().Host(tpl) -} - -// MatcherFunc registers a new route with a custom matcher function. -// See Route.MatcherFunc(). -func (r *Router) MatcherFunc(f MatcherFunc) *Route { - return r.NewRoute().MatcherFunc(f) -} - -// Methods registers a new route with a matcher for HTTP methods. -// See Route.Methods(). -func (r *Router) Methods(methods ...string) *Route { - return r.NewRoute().Methods(methods...) -} - -// Path registers a new route with a matcher for the URL path. -// See Route.Path(). -func (r *Router) Path(tpl string) *Route { - return r.NewRoute().Path(tpl) -} - -// PathPrefix registers a new route with a matcher for the URL path prefix. -// See Route.PathPrefix(). -func (r *Router) PathPrefix(tpl string) *Route { - return r.NewRoute().PathPrefix(tpl) -} - -// Queries registers a new route with a matcher for URL query values. -// See Route.Queries(). -func (r *Router) Queries(pairs ...string) *Route { - return r.NewRoute().Queries(pairs...) -} - -// Schemes registers a new route with a matcher for URL schemes. -// See Route.Schemes(). -func (r *Router) Schemes(schemes ...string) *Route { - return r.NewRoute().Schemes(schemes...) -} - -// BuildVarsFunc registers a new route with a custom function for modifying -// route variables before building a URL. -func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route { - return r.NewRoute().BuildVarsFunc(f) -} - -// Walk walks the router and all its sub-routers, calling walkFn for each route -// in the tree. The routes are walked in the order they were added. Sub-routers -// are explored depth-first. -func (r *Router) Walk(walkFn WalkFunc) error { - return r.walk(walkFn, []*Route{}) -} - -// SkipRouter is used as a return value from WalkFuncs to indicate that the -// router that walk is about to descend down to should be skipped. -var SkipRouter = errors.New("skip this router") - -// WalkFunc is the type of the function called for each route visited by Walk. -// At every invocation, it is given the current route, and the current router, -// and a list of ancestor routes that lead to the current route. -type WalkFunc func(route *Route, router *Router, ancestors []*Route) error - -func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error { - for _, t := range r.routes { - if t.regexp == nil || t.regexp.path == nil || t.regexp.path.template == "" { - continue - } - - err := walkFn(t, r, ancestors) - if err == SkipRouter { - continue - } - if err != nil { - return err - } - for _, sr := range t.matchers { - if h, ok := sr.(*Router); ok { - err := h.walk(walkFn, ancestors) - if err != nil { - return err - } - } - } - if h, ok := t.handler.(*Router); ok { - ancestors = append(ancestors, t) - err := h.walk(walkFn, ancestors) - if err != nil { - return err - } - ancestors = ancestors[:len(ancestors)-1] - } - } - return nil -} - -// ---------------------------------------------------------------------------- -// Context -// ---------------------------------------------------------------------------- - -// RouteMatch stores information about a matched route. -type RouteMatch struct { - Route *Route - Handler http.Handler - Vars map[string]string -} - -type contextKey int - -const ( - varsKey contextKey = iota - routeKey -) - -// Vars returns the route variables for the current request, if any. -func Vars(r *http.Request) map[string]string { - if rv := contextGet(r, varsKey); rv != nil { - return rv.(map[string]string) - } - return nil -} - -// CurrentRoute returns the matched route for the current request, if any. -// This only works when called inside the handler of the matched route -// because the matched route is stored in the request context which is cleared -// after the handler returns, unless the KeepContext option is set on the -// Router. -func CurrentRoute(r *http.Request) *Route { - if rv := contextGet(r, routeKey); rv != nil { - return rv.(*Route) - } - return nil -} - -func setVars(r *http.Request, val interface{}) *http.Request { - return contextSet(r, varsKey, val) -} - -func setCurrentRoute(r *http.Request, val interface{}) *http.Request { - return contextSet(r, routeKey, val) -} - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -// getPath returns the escaped path if possible; doing what URL.EscapedPath() -// which was added in go1.5 does -func getPath(req *http.Request) string { - if req.RequestURI != "" { - // Extract the path from RequestURI (which is escaped unlike URL.Path) - // as detailed here as detailed in https://golang.org/pkg/net/url/#URL - // for < 1.5 server side workaround - // http://localhost/path/here?v=1 -> /path/here - path := req.RequestURI - path = strings.TrimPrefix(path, req.URL.Scheme+`://`) - path = strings.TrimPrefix(path, req.URL.Host) - if i := strings.LastIndex(path, "?"); i > -1 { - path = path[:i] - } - if i := strings.LastIndex(path, "#"); i > -1 { - path = path[:i] - } - return path - } - return req.URL.Path -} - -// cleanPath returns the canonical path for p, eliminating . and .. elements. -// Borrowed from the net/http package. -func cleanPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root; - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - np += "/" - } - - return np -} - -// uniqueVars returns an error if two slices contain duplicated strings. -func uniqueVars(s1, s2 []string) error { - for _, v1 := range s1 { - for _, v2 := range s2 { - if v1 == v2 { - return fmt.Errorf("mux: duplicated route variable %q", v2) - } - } - } - return nil -} - -// checkPairs returns the count of strings passed in, and an error if -// the count is not an even number. -func checkPairs(pairs ...string) (int, error) { - length := len(pairs) - if length%2 != 0 { - return length, fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - } - return length, nil -} - -// mapFromPairsToString converts variadic string parameters to a -// string to string map. -func mapFromPairsToString(pairs ...string) (map[string]string, error) { - length, err := checkPairs(pairs...) - if err != nil { - return nil, err - } - m := make(map[string]string, length/2) - for i := 0; i < length; i += 2 { - m[pairs[i]] = pairs[i+1] - } - return m, nil -} - -// mapFromPairsToRegex converts variadic string paramers to a -// string to regex map. -func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) { - length, err := checkPairs(pairs...) - if err != nil { - return nil, err - } - m := make(map[string]*regexp.Regexp, length/2) - for i := 0; i < length; i += 2 { - regex, err := regexp.Compile(pairs[i+1]) - if err != nil { - return nil, err - } - m[pairs[i]] = regex - } - return m, nil -} - -// matchInArray returns true if the given string value is in the array. -func matchInArray(arr []string, value string) bool { - for _, v := range arr { - if v == value { - return true - } - } - return false -} - -// matchMapWithString returns true if the given key/value pairs exist in a given map. -func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool { - for k, v := range toCheck { - // Check if key exists. - if canonicalKey { - k = http.CanonicalHeaderKey(k) - } - if values := toMatch[k]; values == nil { - return false - } else if v != "" { - // If value was defined as an empty string we only check that the - // key exists. Otherwise we also check for equality. - valueExists := false - for _, value := range values { - if v == value { - valueExists = true - break - } - } - if !valueExists { - return false - } - } - } - return true -} - -// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against -// the given regex -func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool { - for k, v := range toCheck { - // Check if key exists. - if canonicalKey { - k = http.CanonicalHeaderKey(k) - } - if values := toMatch[k]; values == nil { - return false - } else if v != nil { - // If value was defined as an empty string we only check that the - // key exists. Otherwise we also check for equality. - valueExists := false - for _, value := range values { - if v.MatchString(value) { - valueExists = true - break - } - } - if !valueExists { - return false - } - } - } - return true -} diff --git a/vendor/github.com/gorilla/mux/regexp.go b/vendor/github.com/gorilla/mux/regexp.go deleted file mode 100644 index fd8fe39560b22..0000000000000 --- a/vendor/github.com/gorilla/mux/regexp.go +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mux - -import ( - "bytes" - "fmt" - "net/http" - "net/url" - "regexp" - "strconv" - "strings" -) - -// newRouteRegexp parses a route template and returns a routeRegexp, -// used to match a host, a path or a query string. -// -// It will extract named variables, assemble a regexp to be matched, create -// a "reverse" template to build URLs and compile regexps to validate variable -// values used in URL building. -// -// Previously we accepted only Python-like identifiers for variable -// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that -// name and pattern can't be empty, and names can't contain a colon. -func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash, useEncodedPath bool) (*routeRegexp, error) { - // Check if it is well-formed. - idxs, errBraces := braceIndices(tpl) - if errBraces != nil { - return nil, errBraces - } - // Backup the original. - template := tpl - // Now let's parse it. - defaultPattern := "[^/]+" - if matchQuery { - defaultPattern = "[^?&]*" - } else if matchHost { - defaultPattern = "[^.]+" - matchPrefix = false - } - // Only match strict slash if not matching - if matchPrefix || matchHost || matchQuery { - strictSlash = false - } - // Set a flag for strictSlash. - endSlash := false - if strictSlash && strings.HasSuffix(tpl, "/") { - tpl = tpl[:len(tpl)-1] - endSlash = true - } - varsN := make([]string, len(idxs)/2) - varsR := make([]*regexp.Regexp, len(idxs)/2) - pattern := bytes.NewBufferString("") - pattern.WriteByte('^') - reverse := bytes.NewBufferString("") - var end int - var err error - for i := 0; i < len(idxs); i += 2 { - // Set all values we are interested in. - raw := tpl[end:idxs[i]] - end = idxs[i+1] - parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2) - name := parts[0] - patt := defaultPattern - if len(parts) == 2 { - patt = parts[1] - } - // Name or pattern can't be empty. - if name == "" || patt == "" { - return nil, fmt.Errorf("mux: missing name or pattern in %q", - tpl[idxs[i]:end]) - } - // Build the regexp pattern. - fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt) - - // Build the reverse template. - fmt.Fprintf(reverse, "%s%%s", raw) - - // Append variable name and compiled pattern. - varsN[i/2] = name - varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) - if err != nil { - return nil, err - } - } - // Add the remaining. - raw := tpl[end:] - pattern.WriteString(regexp.QuoteMeta(raw)) - if strictSlash { - pattern.WriteString("[/]?") - } - if matchQuery { - // Add the default pattern if the query value is empty - if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" { - pattern.WriteString(defaultPattern) - } - } - if !matchPrefix { - pattern.WriteByte('$') - } - reverse.WriteString(raw) - if endSlash { - reverse.WriteByte('/') - } - // Compile full regexp. - reg, errCompile := regexp.Compile(pattern.String()) - if errCompile != nil { - return nil, errCompile - } - // Done! - return &routeRegexp{ - template: template, - matchHost: matchHost, - matchQuery: matchQuery, - strictSlash: strictSlash, - useEncodedPath: useEncodedPath, - regexp: reg, - reverse: reverse.String(), - varsN: varsN, - varsR: varsR, - }, nil -} - -// routeRegexp stores a regexp to match a host or path and information to -// collect and validate route variables. -type routeRegexp struct { - // The unmodified template. - template string - // True for host match, false for path or query string match. - matchHost bool - // True for query string match, false for path and host match. - matchQuery bool - // The strictSlash value defined on the route, but disabled if PathPrefix was used. - strictSlash bool - // Determines whether to use encoded path from getPath function or unencoded - // req.URL.Path for path matching - useEncodedPath bool - // Expanded regexp. - regexp *regexp.Regexp - // Reverse template. - reverse string - // Variable names. - varsN []string - // Variable regexps (validators). - varsR []*regexp.Regexp -} - -// Match matches the regexp against the URL host or path. -func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { - if !r.matchHost { - if r.matchQuery { - return r.matchQueryString(req) - } - path := req.URL.Path - if r.useEncodedPath { - path = getPath(req) - } - return r.regexp.MatchString(path) - } - - return r.regexp.MatchString(getHost(req)) -} - -// url builds a URL part using the given values. -func (r *routeRegexp) url(values map[string]string) (string, error) { - urlValues := make([]interface{}, len(r.varsN)) - for k, v := range r.varsN { - value, ok := values[v] - if !ok { - return "", fmt.Errorf("mux: missing route variable %q", v) - } - urlValues[k] = value - } - rv := fmt.Sprintf(r.reverse, urlValues...) - if !r.regexp.MatchString(rv) { - // The URL is checked against the full regexp, instead of checking - // individual variables. This is faster but to provide a good error - // message, we check individual regexps if the URL doesn't match. - for k, v := range r.varsN { - if !r.varsR[k].MatchString(values[v]) { - return "", fmt.Errorf( - "mux: variable %q doesn't match, expected %q", values[v], - r.varsR[k].String()) - } - } - } - return rv, nil -} - -// getURLQuery returns a single query parameter from a request URL. -// For a URL with foo=bar&baz=ding, we return only the relevant key -// value pair for the routeRegexp. -func (r *routeRegexp) getURLQuery(req *http.Request) string { - if !r.matchQuery { - return "" - } - templateKey := strings.SplitN(r.template, "=", 2)[0] - for key, vals := range req.URL.Query() { - if key == templateKey && len(vals) > 0 { - return key + "=" + vals[0] - } - } - return "" -} - -func (r *routeRegexp) matchQueryString(req *http.Request) bool { - return r.regexp.MatchString(r.getURLQuery(req)) -} - -// braceIndices returns the first level curly brace indices from a string. -// It returns an error in case of unbalanced braces. -func braceIndices(s string) ([]int, error) { - var level, idx int - var idxs []int - for i := 0; i < len(s); i++ { - switch s[i] { - case '{': - if level++; level == 1 { - idx = i - } - case '}': - if level--; level == 0 { - idxs = append(idxs, idx, i+1) - } else if level < 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - } - } - if level != 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - return idxs, nil -} - -// varGroupName builds a capturing group name for the indexed variable. -func varGroupName(idx int) string { - return "v" + strconv.Itoa(idx) -} - -// ---------------------------------------------------------------------------- -// routeRegexpGroup -// ---------------------------------------------------------------------------- - -// routeRegexpGroup groups the route matchers that carry variables. -type routeRegexpGroup struct { - host *routeRegexp - path *routeRegexp - queries []*routeRegexp -} - -// setMatch extracts the variables from the URL once a route matches. -func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) { - // Store host variables. - if v.host != nil { - host := getHost(req) - matches := v.host.regexp.FindStringSubmatchIndex(host) - if len(matches) > 0 { - extractVars(host, matches, v.host.varsN, m.Vars) - } - } - path := req.URL.Path - if r.useEncodedPath { - path = getPath(req) - } - // Store path variables. - if v.path != nil { - matches := v.path.regexp.FindStringSubmatchIndex(path) - if len(matches) > 0 { - extractVars(path, matches, v.path.varsN, m.Vars) - // Check if we should redirect. - if v.path.strictSlash { - p1 := strings.HasSuffix(path, "/") - p2 := strings.HasSuffix(v.path.template, "/") - if p1 != p2 { - u, _ := url.Parse(req.URL.String()) - if p1 { - u.Path = u.Path[:len(u.Path)-1] - } else { - u.Path += "/" - } - m.Handler = http.RedirectHandler(u.String(), 301) - } - } - } - } - // Store query string variables. - for _, q := range v.queries { - queryURL := q.getURLQuery(req) - matches := q.regexp.FindStringSubmatchIndex(queryURL) - if len(matches) > 0 { - extractVars(queryURL, matches, q.varsN, m.Vars) - } - } -} - -// getHost tries its best to return the request host. -func getHost(r *http.Request) string { - if r.URL.IsAbs() { - return r.URL.Host - } - host := r.Host - // Slice off any port information. - if i := strings.Index(host, ":"); i != -1 { - host = host[:i] - } - return host - -} - -func extractVars(input string, matches []int, names []string, output map[string]string) { - for i, name := range names { - output[name] = input[matches[2*i+2]:matches[2*i+3]] - } -} diff --git a/vendor/github.com/gorilla/mux/route.go b/vendor/github.com/gorilla/mux/route.go deleted file mode 100644 index 293b6d49386f3..0000000000000 --- a/vendor/github.com/gorilla/mux/route.go +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mux - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "regexp" - "strings" -) - -// Route stores information to match a request and build URLs. -type Route struct { - // Parent where the route was registered (a Router). - parent parentRoute - // Request handler for the route. - handler http.Handler - // List of matchers. - matchers []matcher - // Manager for the variables from host and path. - regexp *routeRegexpGroup - // If true, when the path pattern is "/path/", accessing "/path" will - // redirect to the former and vice versa. - strictSlash bool - // If true, when the path pattern is "/path//to", accessing "/path//to" - // will not redirect - skipClean bool - // If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to" - useEncodedPath bool - // If true, this route never matches: it is only used to build URLs. - buildOnly bool - // The name used to build URLs. - name string - // Error resulted from building a route. - err error - - buildVarsFunc BuildVarsFunc -} - -func (r *Route) SkipClean() bool { - return r.skipClean -} - -// Match matches the route against the request. -func (r *Route) Match(req *http.Request, match *RouteMatch) bool { - if r.buildOnly || r.err != nil { - return false - } - // Match everything. - for _, m := range r.matchers { - if matched := m.Match(req, match); !matched { - return false - } - } - // Yay, we have a match. Let's collect some info about it. - if match.Route == nil { - match.Route = r - } - if match.Handler == nil { - match.Handler = r.handler - } - if match.Vars == nil { - match.Vars = make(map[string]string) - } - // Set variables. - if r.regexp != nil { - r.regexp.setMatch(req, match, r) - } - return true -} - -// ---------------------------------------------------------------------------- -// Route attributes -// ---------------------------------------------------------------------------- - -// GetError returns an error resulted from building the route, if any. -func (r *Route) GetError() error { - return r.err -} - -// BuildOnly sets the route to never match: it is only used to build URLs. -func (r *Route) BuildOnly() *Route { - r.buildOnly = true - return r -} - -// Handler -------------------------------------------------------------------- - -// Handler sets a handler for the route. -func (r *Route) Handler(handler http.Handler) *Route { - if r.err == nil { - r.handler = handler - } - return r -} - -// HandlerFunc sets a handler function for the route. -func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route { - return r.Handler(http.HandlerFunc(f)) -} - -// GetHandler returns the handler for the route, if any. -func (r *Route) GetHandler() http.Handler { - return r.handler -} - -// Name ----------------------------------------------------------------------- - -// Name sets the name for the route, used to build URLs. -// If the name was registered already it will be overwritten. -func (r *Route) Name(name string) *Route { - if r.name != "" { - r.err = fmt.Errorf("mux: route already has name %q, can't set %q", - r.name, name) - } - if r.err == nil { - r.name = name - r.getNamedRoutes()[name] = r - } - return r -} - -// GetName returns the name for the route, if any. -func (r *Route) GetName() string { - return r.name -} - -// ---------------------------------------------------------------------------- -// Matchers -// ---------------------------------------------------------------------------- - -// matcher types try to match a request. -type matcher interface { - Match(*http.Request, *RouteMatch) bool -} - -// addMatcher adds a matcher to the route. -func (r *Route) addMatcher(m matcher) *Route { - if r.err == nil { - r.matchers = append(r.matchers, m) - } - return r -} - -// addRegexpMatcher adds a host or path matcher and builder to a route. -func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error { - if r.err != nil { - return r.err - } - r.regexp = r.getRegexpGroup() - if !matchHost && !matchQuery { - if len(tpl) == 0 || tpl[0] != '/' { - return fmt.Errorf("mux: path must start with a slash, got %q", tpl) - } - if r.regexp.path != nil { - tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl - } - } - rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash, r.useEncodedPath) - if err != nil { - return err - } - for _, q := range r.regexp.queries { - if err = uniqueVars(rr.varsN, q.varsN); err != nil { - return err - } - } - if matchHost { - if r.regexp.path != nil { - if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil { - return err - } - } - r.regexp.host = rr - } else { - if r.regexp.host != nil { - if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil { - return err - } - } - if matchQuery { - r.regexp.queries = append(r.regexp.queries, rr) - } else { - r.regexp.path = rr - } - } - r.addMatcher(rr) - return nil -} - -// Headers -------------------------------------------------------------------- - -// headerMatcher matches the request against header values. -type headerMatcher map[string]string - -func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchMapWithString(m, r.Header, true) -} - -// Headers adds a matcher for request header values. -// It accepts a sequence of key/value pairs to be matched. For example: -// -// r := mux.NewRouter() -// r.Headers("Content-Type", "application/json", -// "X-Requested-With", "XMLHttpRequest") -// -// The above route will only match if both request header values match. -// If the value is an empty string, it will match any value if the key is set. -func (r *Route) Headers(pairs ...string) *Route { - if r.err == nil { - var headers map[string]string - headers, r.err = mapFromPairsToString(pairs...) - return r.addMatcher(headerMatcher(headers)) - } - return r -} - -// headerRegexMatcher matches the request against the route given a regex for the header -type headerRegexMatcher map[string]*regexp.Regexp - -func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchMapWithRegex(m, r.Header, true) -} - -// HeadersRegexp accepts a sequence of key/value pairs, where the value has regex -// support. For example: -// -// r := mux.NewRouter() -// r.HeadersRegexp("Content-Type", "application/(text|json)", -// "X-Requested-With", "XMLHttpRequest") -// -// The above route will only match if both the request header matches both regular expressions. -// It the value is an empty string, it will match any value if the key is set. -func (r *Route) HeadersRegexp(pairs ...string) *Route { - if r.err == nil { - var headers map[string]*regexp.Regexp - headers, r.err = mapFromPairsToRegex(pairs...) - return r.addMatcher(headerRegexMatcher(headers)) - } - return r -} - -// Host ----------------------------------------------------------------------- - -// Host adds a matcher for the URL host. -// It accepts a template with zero or more URL variables enclosed by {}. -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next dot. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter() -// r.Host("www.example.com") -// r.Host("{subdomain}.domain.com") -// r.Host("{subdomain:[a-z]+}.domain.com") -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Host(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, true, false, false) - return r -} - -// MatcherFunc ---------------------------------------------------------------- - -// MatcherFunc is the function signature used by custom matchers. -type MatcherFunc func(*http.Request, *RouteMatch) bool - -// Match returns the match for a given request. -func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool { - return m(r, match) -} - -// MatcherFunc adds a custom function to be used as request matcher. -func (r *Route) MatcherFunc(f MatcherFunc) *Route { - return r.addMatcher(f) -} - -// Methods -------------------------------------------------------------------- - -// methodMatcher matches the request against HTTP methods. -type methodMatcher []string - -func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchInArray(m, r.Method) -} - -// Methods adds a matcher for HTTP methods. -// It accepts a sequence of one or more methods to be matched, e.g.: -// "GET", "POST", "PUT". -func (r *Route) Methods(methods ...string) *Route { - for k, v := range methods { - methods[k] = strings.ToUpper(v) - } - return r.addMatcher(methodMatcher(methods)) -} - -// Path ----------------------------------------------------------------------- - -// Path adds a matcher for the URL path. -// It accepts a template with zero or more URL variables enclosed by {}. The -// template must start with a "/". -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter() -// r.Path("/products/").Handler(ProductsHandler) -// r.Path("/products/{key}").Handler(ProductsHandler) -// r.Path("/articles/{category}/{id:[0-9]+}"). -// Handler(ArticleHandler) -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Path(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, false, false, false) - return r -} - -// PathPrefix ----------------------------------------------------------------- - -// PathPrefix adds a matcher for the URL path prefix. This matches if the given -// template is a prefix of the full URL path. See Route.Path() for details on -// the tpl argument. -// -// Note that it does not treat slashes specially ("/foobar/" will be matched by -// the prefix "/foo") so you may want to use a trailing slash here. -// -// Also note that the setting of Router.StrictSlash() has no effect on routes -// with a PathPrefix matcher. -func (r *Route) PathPrefix(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, false, true, false) - return r -} - -// Query ---------------------------------------------------------------------- - -// Queries adds a matcher for URL query values. -// It accepts a sequence of key/value pairs. Values may define variables. -// For example: -// -// r := mux.NewRouter() -// r.Queries("foo", "bar", "id", "{id:[0-9]+}") -// -// The above route will only match if the URL contains the defined queries -// values, e.g.: ?foo=bar&id=42. -// -// It the value is an empty string, it will match any value if the key is set. -// -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -func (r *Route) Queries(pairs ...string) *Route { - length := len(pairs) - if length%2 != 0 { - r.err = fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - return nil - } - for i := 0; i < length; i += 2 { - if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil { - return r - } - } - - return r -} - -// Schemes -------------------------------------------------------------------- - -// schemeMatcher matches the request against URL schemes. -type schemeMatcher []string - -func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchInArray(m, r.URL.Scheme) -} - -// Schemes adds a matcher for URL schemes. -// It accepts a sequence of schemes to be matched, e.g.: "http", "https". -func (r *Route) Schemes(schemes ...string) *Route { - for k, v := range schemes { - schemes[k] = strings.ToLower(v) - } - return r.addMatcher(schemeMatcher(schemes)) -} - -// BuildVarsFunc -------------------------------------------------------------- - -// BuildVarsFunc is the function signature used by custom build variable -// functions (which can modify route variables before a route's URL is built). -type BuildVarsFunc func(map[string]string) map[string]string - -// BuildVarsFunc adds a custom function to be used to modify build variables -// before a route's URL is built. -func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { - r.buildVarsFunc = f - return r -} - -// Subrouter ------------------------------------------------------------------ - -// Subrouter creates a subrouter for the route. -// -// It will test the inner routes only if the parent route matched. For example: -// -// r := mux.NewRouter() -// s := r.Host("www.example.com").Subrouter() -// s.HandleFunc("/products/", ProductsHandler) -// s.HandleFunc("/products/{key}", ProductHandler) -// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) -// -// Here, the routes registered in the subrouter won't be tested if the host -// doesn't match. -func (r *Route) Subrouter() *Router { - router := &Router{parent: r, strictSlash: r.strictSlash} - r.addMatcher(router) - return router -} - -// ---------------------------------------------------------------------------- -// URL building -// ---------------------------------------------------------------------------- - -// URL builds a URL for the route. -// -// It accepts a sequence of key/value pairs for the route variables. For -// example, given this route: -// -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") -// -// ...a URL for it can be built using: -// -// url, err := r.Get("article").URL("category", "technology", "id", "42") -// -// ...which will return an url.URL with the following path: -// -// "/articles/technology/42" -// -// This also works for host variables: -// -// r := mux.NewRouter() -// r.Host("{subdomain}.domain.com"). -// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") -// -// // url.String() will be "http://news.domain.com/articles/technology/42" -// url, err := r.Get("article").URL("subdomain", "news", -// "category", "technology", -// "id", "42") -// -// All variables defined in the route are required, and their values must -// conform to the corresponding patterns. -func (r *Route) URL(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil { - return nil, errors.New("mux: route doesn't have a host or path") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - var scheme, host, path string - if r.regexp.host != nil { - // Set a default scheme. - scheme = "http" - if host, err = r.regexp.host.url(values); err != nil { - return nil, err - } - } - if r.regexp.path != nil { - if path, err = r.regexp.path.url(values); err != nil { - return nil, err - } - } - return &url.URL{ - Scheme: scheme, - Host: host, - Path: path, - }, nil -} - -// URLHost builds the host part of the URL for a route. See Route.URL(). -// -// The route must have a host defined. -func (r *Route) URLHost(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil || r.regexp.host == nil { - return nil, errors.New("mux: route doesn't have a host") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - host, err := r.regexp.host.url(values) - if err != nil { - return nil, err - } - return &url.URL{ - Scheme: "http", - Host: host, - }, nil -} - -// URLPath builds the path part of the URL for a route. See Route.URL(). -// -// The route must have a path defined. -func (r *Route) URLPath(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil || r.regexp.path == nil { - return nil, errors.New("mux: route doesn't have a path") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - path, err := r.regexp.path.url(values) - if err != nil { - return nil, err - } - return &url.URL{ - Path: path, - }, nil -} - -// GetPathTemplate returns the template used to build the -// route match. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define a path. -func (r *Route) GetPathTemplate() (string, error) { - if r.err != nil { - return "", r.err - } - if r.regexp == nil || r.regexp.path == nil { - return "", errors.New("mux: route doesn't have a path") - } - return r.regexp.path.template, nil -} - -// GetHostTemplate returns the template used to build the -// route match. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define a host. -func (r *Route) GetHostTemplate() (string, error) { - if r.err != nil { - return "", r.err - } - if r.regexp == nil || r.regexp.host == nil { - return "", errors.New("mux: route doesn't have a host") - } - return r.regexp.host.template, nil -} - -// prepareVars converts the route variable pairs into a map. If the route has a -// BuildVarsFunc, it is invoked. -func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { - m, err := mapFromPairsToString(pairs...) - if err != nil { - return nil, err - } - return r.buildVars(m), nil -} - -func (r *Route) buildVars(m map[string]string) map[string]string { - if r.parent != nil { - m = r.parent.buildVars(m) - } - if r.buildVarsFunc != nil { - m = r.buildVarsFunc(m) - } - return m -} - -// ---------------------------------------------------------------------------- -// parentRoute -// ---------------------------------------------------------------------------- - -// parentRoute allows routes to know about parent host and path definitions. -type parentRoute interface { - getNamedRoutes() map[string]*Route - getRegexpGroup() *routeRegexpGroup - buildVars(map[string]string) map[string]string -} - -// getNamedRoutes returns the map where named routes are registered. -func (r *Route) getNamedRoutes() map[string]*Route { - if r.parent == nil { - // During tests router is not always set. - r.parent = NewRouter() - } - return r.parent.getNamedRoutes() -} - -// getRegexpGroup returns regexp definitions from this route. -func (r *Route) getRegexpGroup() *routeRegexpGroup { - if r.regexp == nil { - if r.parent == nil { - // During tests router is not always set. - r.parent = NewRouter() - } - regexp := r.parent.getRegexpGroup() - if regexp == nil { - r.regexp = new(routeRegexpGroup) - } else { - // Copy. - r.regexp = &routeRegexpGroup{ - host: regexp.host, - path: regexp.path, - queries: regexp.queries, - } - } - } - return r.regexp -} diff --git a/vendor/github.com/gorilla/securecookie/LICENSE b/vendor/github.com/gorilla/securecookie/LICENSE deleted file mode 100644 index 0e5fb872800da..0000000000000 --- a/vendor/github.com/gorilla/securecookie/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/securecookie/doc.go b/vendor/github.com/gorilla/securecookie/doc.go deleted file mode 100644 index ae89408d9d564..0000000000000 --- a/vendor/github.com/gorilla/securecookie/doc.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package securecookie encodes and decodes authenticated and optionally -encrypted cookie values. - -Secure cookies can't be forged, because their values are validated using HMAC. -When encrypted, the content is also inaccessible to malicious eyes. - -To use it, first create a new SecureCookie instance: - - var hashKey = []byte("very-secret") - var blockKey = []byte("a-lot-secret") - var s = securecookie.New(hashKey, blockKey) - -The hashKey is required, used to authenticate the cookie value using HMAC. -It is recommended to use a key with 32 or 64 bytes. - -The blockKey is optional, used to encrypt the cookie value -- set it to nil -to not use encryption. If set, the length must correspond to the block size -of the encryption algorithm. For AES, used by default, valid lengths are -16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. - -Strong keys can be created using the convenience function GenerateRandomKey(). - -Once a SecureCookie instance is set, use it to encode a cookie value: - - func SetCookieHandler(w http.ResponseWriter, r *http.Request) { - value := map[string]string{ - "foo": "bar", - } - if encoded, err := s.Encode("cookie-name", value); err == nil { - cookie := &http.Cookie{ - Name: "cookie-name", - Value: encoded, - Path: "/", - } - http.SetCookie(w, cookie) - } - } - -Later, use the same SecureCookie instance to decode and validate a cookie -value: - - func ReadCookieHandler(w http.ResponseWriter, r *http.Request) { - if cookie, err := r.Cookie("cookie-name"); err == nil { - value := make(map[string]string) - if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil { - fmt.Fprintf(w, "The value of foo is %q", value["foo"]) - } - } - } - -We stored a map[string]string, but secure cookies can hold any value that -can be encoded using encoding/gob. To store custom types, they must be -registered first using gob.Register(). For basic types this is not needed; -it works out of the box. -*/ -package securecookie diff --git a/vendor/github.com/gorilla/securecookie/fuzz.go b/vendor/github.com/gorilla/securecookie/fuzz.go deleted file mode 100644 index e4d0534e41bfd..0000000000000 --- a/vendor/github.com/gorilla/securecookie/fuzz.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build gofuzz - -package securecookie - -var hashKey = []byte("very-secret12345") -var blockKey = []byte("a-lot-secret1234") -var s = New(hashKey, blockKey) - -type Cookie struct { - B bool - I int - S string -} - -func Fuzz(data []byte) int { - datas := string(data) - var c Cookie - if err := s.Decode("fuzz", datas, &c); err != nil { - return 0 - } - if _, err := s.Encode("fuzz", c); err != nil { - panic(err) - } - return 1 -} diff --git a/vendor/github.com/gorilla/securecookie/securecookie.go b/vendor/github.com/gorilla/securecookie/securecookie.go deleted file mode 100644 index cd4e0976d6639..0000000000000 --- a/vendor/github.com/gorilla/securecookie/securecookie.go +++ /dev/null @@ -1,646 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package securecookie - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "crypto/subtle" - "encoding/base64" - "encoding/gob" - "encoding/json" - "fmt" - "hash" - "io" - "strconv" - "strings" - "time" -) - -// Error is the interface of all errors returned by functions in this library. -type Error interface { - error - - // IsUsage returns true for errors indicating the client code probably - // uses this library incorrectly. For example, the client may have - // failed to provide a valid hash key, or may have failed to configure - // the Serializer adequately for encoding value. - IsUsage() bool - - // IsDecode returns true for errors indicating that a cookie could not - // be decoded and validated. Since cookies are usually untrusted - // user-provided input, errors of this type should be expected. - // Usually, the proper action is simply to reject the request. - IsDecode() bool - - // IsInternal returns true for unexpected errors occurring in the - // securecookie implementation. - IsInternal() bool - - // Cause, if it returns a non-nil value, indicates that this error was - // propagated from some underlying library. If this method returns nil, - // this error was raised directly by this library. - // - // Cause is provided principally for debugging/logging purposes; it is - // rare that application logic should perform meaningfully different - // logic based on Cause. See, for example, the caveats described on - // (MultiError).Cause(). - Cause() error -} - -// errorType is a bitmask giving the error type(s) of an cookieError value. -type errorType int - -const ( - usageError = errorType(1 << iota) - decodeError - internalError -) - -type cookieError struct { - typ errorType - msg string - cause error -} - -func (e cookieError) IsUsage() bool { return (e.typ & usageError) != 0 } -func (e cookieError) IsDecode() bool { return (e.typ & decodeError) != 0 } -func (e cookieError) IsInternal() bool { return (e.typ & internalError) != 0 } - -func (e cookieError) Cause() error { return e.cause } - -func (e cookieError) Error() string { - parts := []string{"securecookie: "} - if e.msg == "" { - parts = append(parts, "error") - } else { - parts = append(parts, e.msg) - } - if c := e.Cause(); c != nil { - parts = append(parts, " - caused by: ", c.Error()) - } - return strings.Join(parts, "") -} - -var ( - errGeneratingIV = cookieError{typ: internalError, msg: "failed to generate random iv"} - - errNoCodecs = cookieError{typ: usageError, msg: "no codecs provided"} - errHashKeyNotSet = cookieError{typ: usageError, msg: "hash key is not set"} - errBlockKeyNotSet = cookieError{typ: usageError, msg: "block key is not set"} - errEncodedValueTooLong = cookieError{typ: usageError, msg: "the value is too long"} - - errValueToDecodeTooLong = cookieError{typ: decodeError, msg: "the value is too long"} - errTimestampInvalid = cookieError{typ: decodeError, msg: "invalid timestamp"} - errTimestampTooNew = cookieError{typ: decodeError, msg: "timestamp is too new"} - errTimestampExpired = cookieError{typ: decodeError, msg: "expired timestamp"} - errDecryptionFailed = cookieError{typ: decodeError, msg: "the value could not be decrypted"} - errValueNotByte = cookieError{typ: decodeError, msg: "value not a []byte."} - errValueNotBytePtr = cookieError{typ: decodeError, msg: "value not a pointer to []byte."} - - // ErrMacInvalid indicates that cookie decoding failed because the HMAC - // could not be extracted and verified. Direct use of this error - // variable is deprecated; it is public only for legacy compatibility, - // and may be privatized in the future, as it is rarely useful to - // distinguish between this error and other Error implementations. - ErrMacInvalid = cookieError{typ: decodeError, msg: "the value is not valid"} -) - -// Codec defines an interface to encode and decode cookie values. -type Codec interface { - Encode(name string, value interface{}) (string, error) - Decode(name, value string, dst interface{}) error -} - -// New returns a new SecureCookie. -// -// hashKey is required, used to authenticate values using HMAC. Create it using -// GenerateRandomKey(). It is recommended to use a key with 32 or 64 bytes. -// -// blockKey is optional, used to encrypt values. Create it using -// GenerateRandomKey(). The key length must correspond to the block size -// of the encryption algorithm. For AES, used by default, valid lengths are -// 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. -// The default encoder used for cookie serialization is encoding/gob. -// -// Note that keys created using GenerateRandomKey() are not automatically -// persisted. New keys will be created when the application is restarted, and -// previously issued cookies will not be able to be decoded. -func New(hashKey, blockKey []byte) *SecureCookie { - s := &SecureCookie{ - hashKey: hashKey, - blockKey: blockKey, - hashFunc: sha256.New, - maxAge: 86400 * 30, - maxLength: 4096, - sz: GobEncoder{}, - } - if hashKey == nil { - s.err = errHashKeyNotSet - } - if blockKey != nil { - s.BlockFunc(aes.NewCipher) - } - return s -} - -// SecureCookie encodes and decodes authenticated and optionally encrypted -// cookie values. -type SecureCookie struct { - hashKey []byte - hashFunc func() hash.Hash - blockKey []byte - block cipher.Block - maxLength int - maxAge int64 - minAge int64 - err error - sz Serializer - // For testing purposes, the function that returns the current timestamp. - // If not set, it will use time.Now().UTC().Unix(). - timeFunc func() int64 -} - -// Serializer provides an interface for providing custom serializers for cookie -// values. -type Serializer interface { - Serialize(src interface{}) ([]byte, error) - Deserialize(src []byte, dst interface{}) error -} - -// GobEncoder encodes cookie values using encoding/gob. This is the simplest -// encoder and can handle complex types via gob.Register. -type GobEncoder struct{} - -// JSONEncoder encodes cookie values using encoding/json. Users who wish to -// encode complex types need to satisfy the json.Marshaller and -// json.Unmarshaller interfaces. -type JSONEncoder struct{} - -// NopEncoder does not encode cookie values, and instead simply accepts a []byte -// (as an interface{}) and returns a []byte. This is particularly useful when -// you encoding an object upstream and do not wish to re-encode it. -type NopEncoder struct{} - -// MaxLength restricts the maximum length, in bytes, for the cookie value. -// -// Default is 4096, which is the maximum value accepted by Internet Explorer. -func (s *SecureCookie) MaxLength(value int) *SecureCookie { - s.maxLength = value - return s -} - -// MaxAge restricts the maximum age, in seconds, for the cookie value. -// -// Default is 86400 * 30. Set it to 0 for no restriction. -func (s *SecureCookie) MaxAge(value int) *SecureCookie { - s.maxAge = int64(value) - return s -} - -// MinAge restricts the minimum age, in seconds, for the cookie value. -// -// Default is 0 (no restriction). -func (s *SecureCookie) MinAge(value int) *SecureCookie { - s.minAge = int64(value) - return s -} - -// HashFunc sets the hash function used to create HMAC. -// -// Default is crypto/sha256.New. -func (s *SecureCookie) HashFunc(f func() hash.Hash) *SecureCookie { - s.hashFunc = f - return s -} - -// BlockFunc sets the encryption function used to create a cipher.Block. -// -// Default is crypto/aes.New. -func (s *SecureCookie) BlockFunc(f func([]byte) (cipher.Block, error)) *SecureCookie { - if s.blockKey == nil { - s.err = errBlockKeyNotSet - } else if block, err := f(s.blockKey); err == nil { - s.block = block - } else { - s.err = cookieError{cause: err, typ: usageError} - } - return s -} - -// Encoding sets the encoding/serialization method for cookies. -// -// Default is encoding/gob. To encode special structures using encoding/gob, -// they must be registered first using gob.Register(). -func (s *SecureCookie) SetSerializer(sz Serializer) *SecureCookie { - s.sz = sz - - return s -} - -// Encode encodes a cookie value. -// -// It serializes, optionally encrypts, signs with a message authentication code, -// and finally encodes the value. -// -// The name argument is the cookie name. It is stored with the encoded value. -// The value argument is the value to be encoded. It can be any value that can -// be encoded using the currently selected serializer; see SetSerializer(). -// -// It is the client's responsibility to ensure that value, when encoded using -// the current serialization/encryption settings on s and then base64-encoded, -// is shorter than the maximum permissible length. -func (s *SecureCookie) Encode(name string, value interface{}) (string, error) { - if s.err != nil { - return "", s.err - } - if s.hashKey == nil { - s.err = errHashKeyNotSet - return "", s.err - } - var err error - var b []byte - // 1. Serialize. - if b, err = s.sz.Serialize(value); err != nil { - return "", cookieError{cause: err, typ: usageError} - } - // 2. Encrypt (optional). - if s.block != nil { - if b, err = encrypt(s.block, b); err != nil { - return "", cookieError{cause: err, typ: usageError} - } - } - b = encode(b) - // 3. Create MAC for "name|date|value". Extra pipe to be used later. - b = []byte(fmt.Sprintf("%s|%d|%s|", name, s.timestamp(), b)) - mac := createMac(hmac.New(s.hashFunc, s.hashKey), b[:len(b)-1]) - // Append mac, remove name. - b = append(b, mac...)[len(name)+1:] - // 4. Encode to base64. - b = encode(b) - // 5. Check length. - if s.maxLength != 0 && len(b) > s.maxLength { - return "", errEncodedValueTooLong - } - // Done. - return string(b), nil -} - -// Decode decodes a cookie value. -// -// It decodes, verifies a message authentication code, optionally decrypts and -// finally deserializes the value. -// -// The name argument is the cookie name. It must be the same name used when -// it was stored. The value argument is the encoded cookie value. The dst -// argument is where the cookie will be decoded. It must be a pointer. -func (s *SecureCookie) Decode(name, value string, dst interface{}) error { - if s.err != nil { - return s.err - } - if s.hashKey == nil { - s.err = errHashKeyNotSet - return s.err - } - // 1. Check length. - if s.maxLength != 0 && len(value) > s.maxLength { - return errValueToDecodeTooLong - } - // 2. Decode from base64. - b, err := decode([]byte(value)) - if err != nil { - return err - } - // 3. Verify MAC. Value is "date|value|mac". - parts := bytes.SplitN(b, []byte("|"), 3) - if len(parts) != 3 { - return ErrMacInvalid - } - h := hmac.New(s.hashFunc, s.hashKey) - b = append([]byte(name+"|"), b[:len(b)-len(parts[2])-1]...) - if err = verifyMac(h, b, parts[2]); err != nil { - return err - } - // 4. Verify date ranges. - var t1 int64 - if t1, err = strconv.ParseInt(string(parts[0]), 10, 64); err != nil { - return errTimestampInvalid - } - t2 := s.timestamp() - if s.minAge != 0 && t1 > t2-s.minAge { - return errTimestampTooNew - } - if s.maxAge != 0 && t1 < t2-s.maxAge { - return errTimestampExpired - } - // 5. Decrypt (optional). - b, err = decode(parts[1]) - if err != nil { - return err - } - if s.block != nil { - if b, err = decrypt(s.block, b); err != nil { - return err - } - } - // 6. Deserialize. - if err = s.sz.Deserialize(b, dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - // Done. - return nil -} - -// timestamp returns the current timestamp, in seconds. -// -// For testing purposes, the function that generates the timestamp can be -// overridden. If not set, it will return time.Now().UTC().Unix(). -func (s *SecureCookie) timestamp() int64 { - if s.timeFunc == nil { - return time.Now().UTC().Unix() - } - return s.timeFunc() -} - -// Authentication ------------------------------------------------------------- - -// createMac creates a message authentication code (MAC). -func createMac(h hash.Hash, value []byte) []byte { - h.Write(value) - return h.Sum(nil) -} - -// verifyMac verifies that a message authentication code (MAC) is valid. -func verifyMac(h hash.Hash, value []byte, mac []byte) error { - mac2 := createMac(h, value) - // Check that both MACs are of equal length, as subtle.ConstantTimeCompare - // does not do this prior to Go 1.4. - if len(mac) == len(mac2) && subtle.ConstantTimeCompare(mac, mac2) == 1 { - return nil - } - return ErrMacInvalid -} - -// Encryption ----------------------------------------------------------------- - -// encrypt encrypts a value using the given block in counter mode. -// -// A random initialization vector (http://goo.gl/zF67k) with the length of the -// block size is prepended to the resulting ciphertext. -func encrypt(block cipher.Block, value []byte) ([]byte, error) { - iv := GenerateRandomKey(block.BlockSize()) - if iv == nil { - return nil, errGeneratingIV - } - // Encrypt it. - stream := cipher.NewCTR(block, iv) - stream.XORKeyStream(value, value) - // Return iv + ciphertext. - return append(iv, value...), nil -} - -// decrypt decrypts a value using the given block in counter mode. -// -// The value to be decrypted must be prepended by a initialization vector -// (http://goo.gl/zF67k) with the length of the block size. -func decrypt(block cipher.Block, value []byte) ([]byte, error) { - size := block.BlockSize() - if len(value) > size { - // Extract iv. - iv := value[:size] - // Extract ciphertext. - value = value[size:] - // Decrypt it. - stream := cipher.NewCTR(block, iv) - stream.XORKeyStream(value, value) - return value, nil - } - return nil, errDecryptionFailed -} - -// Serialization -------------------------------------------------------------- - -// Serialize encodes a value using gob. -func (e GobEncoder) Serialize(src interface{}) ([]byte, error) { - buf := new(bytes.Buffer) - enc := gob.NewEncoder(buf) - if err := enc.Encode(src); err != nil { - return nil, cookieError{cause: err, typ: usageError} - } - return buf.Bytes(), nil -} - -// Deserialize decodes a value using gob. -func (e GobEncoder) Deserialize(src []byte, dst interface{}) error { - dec := gob.NewDecoder(bytes.NewBuffer(src)) - if err := dec.Decode(dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - return nil -} - -// Serialize encodes a value using encoding/json. -func (e JSONEncoder) Serialize(src interface{}) ([]byte, error) { - buf := new(bytes.Buffer) - enc := json.NewEncoder(buf) - if err := enc.Encode(src); err != nil { - return nil, cookieError{cause: err, typ: usageError} - } - return buf.Bytes(), nil -} - -// Deserialize decodes a value using encoding/json. -func (e JSONEncoder) Deserialize(src []byte, dst interface{}) error { - dec := json.NewDecoder(bytes.NewReader(src)) - if err := dec.Decode(dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - return nil -} - -// Serialize passes a []byte through as-is. -func (e NopEncoder) Serialize(src interface{}) ([]byte, error) { - if b, ok := src.([]byte); ok { - return b, nil - } - - return nil, errValueNotByte -} - -// Deserialize passes a []byte through as-is. -func (e NopEncoder) Deserialize(src []byte, dst interface{}) error { - if dat, ok := dst.(*[]byte); ok { - *dat = src - return nil - } - return errValueNotBytePtr -} - -// Encoding ------------------------------------------------------------------- - -// encode encodes a value using base64. -func encode(value []byte) []byte { - encoded := make([]byte, base64.URLEncoding.EncodedLen(len(value))) - base64.URLEncoding.Encode(encoded, value) - return encoded -} - -// decode decodes a cookie using base64. -func decode(value []byte) ([]byte, error) { - decoded := make([]byte, base64.URLEncoding.DecodedLen(len(value))) - b, err := base64.URLEncoding.Decode(decoded, value) - if err != nil { - return nil, cookieError{cause: err, typ: decodeError, msg: "base64 decode failed"} - } - return decoded[:b], nil -} - -// Helpers -------------------------------------------------------------------- - -// GenerateRandomKey creates a random key with the given length in bytes. -// On failure, returns nil. -// -// Callers should explicitly check for the possibility of a nil return, treat -// it as a failure of the system random number generator, and not continue. -func GenerateRandomKey(length int) []byte { - k := make([]byte, length) - if _, err := io.ReadFull(rand.Reader, k); err != nil { - return nil - } - return k -} - -// CodecsFromPairs returns a slice of SecureCookie instances. -// -// It is a convenience function to create a list of codecs for key rotation. Note -// that the generated Codecs will have the default options applied: callers -// should iterate over each Codec and type-assert the underlying *SecureCookie to -// change these. -// -// Example: -// -// codecs := securecookie.CodecsFromPairs( -// []byte("new-hash-key"), -// []byte("new-block-key"), -// []byte("old-hash-key"), -// []byte("old-block-key"), -// ) -// -// // Modify each instance. -// for _, s := range codecs { -// if cookie, ok := s.(*securecookie.SecureCookie); ok { -// cookie.MaxAge(86400 * 7) -// cookie.SetSerializer(securecookie.JSONEncoder{}) -// cookie.HashFunc(sha512.New512_256) -// } -// } -// -func CodecsFromPairs(keyPairs ...[]byte) []Codec { - codecs := make([]Codec, len(keyPairs)/2+len(keyPairs)%2) - for i := 0; i < len(keyPairs); i += 2 { - var blockKey []byte - if i+1 < len(keyPairs) { - blockKey = keyPairs[i+1] - } - codecs[i/2] = New(keyPairs[i], blockKey) - } - return codecs -} - -// EncodeMulti encodes a cookie value using a group of codecs. -// -// The codecs are tried in order. Multiple codecs are accepted to allow -// key rotation. -// -// On error, may return a MultiError. -func EncodeMulti(name string, value interface{}, codecs ...Codec) (string, error) { - if len(codecs) == 0 { - return "", errNoCodecs - } - - var errors MultiError - for _, codec := range codecs { - encoded, err := codec.Encode(name, value) - if err == nil { - return encoded, nil - } - errors = append(errors, err) - } - return "", errors -} - -// DecodeMulti decodes a cookie value using a group of codecs. -// -// The codecs are tried in order. Multiple codecs are accepted to allow -// key rotation. -// -// On error, may return a MultiError. -func DecodeMulti(name string, value string, dst interface{}, codecs ...Codec) error { - if len(codecs) == 0 { - return errNoCodecs - } - - var errors MultiError - for _, codec := range codecs { - err := codec.Decode(name, value, dst) - if err == nil { - return nil - } - errors = append(errors, err) - } - return errors -} - -// MultiError groups multiple errors. -type MultiError []error - -func (m MultiError) IsUsage() bool { return m.any(func(e Error) bool { return e.IsUsage() }) } -func (m MultiError) IsDecode() bool { return m.any(func(e Error) bool { return e.IsDecode() }) } -func (m MultiError) IsInternal() bool { return m.any(func(e Error) bool { return e.IsInternal() }) } - -// Cause returns nil for MultiError; there is no unique underlying cause in the -// general case. -// -// Note: we could conceivably return a non-nil Cause only when there is exactly -// one child error with a Cause. However, it would be brittle for client code -// to rely on the arity of causes inside a MultiError, so we have opted not to -// provide this functionality. Clients which really wish to access the Causes -// of the underlying errors are free to iterate through the errors themselves. -func (m MultiError) Cause() error { return nil } - -func (m MultiError) Error() string { - s, n := "", 0 - for _, e := range m { - if e != nil { - if n == 0 { - s = e.Error() - } - n++ - } - } - switch n { - case 0: - return "(0 errors)" - case 1: - return s - case 2: - return s + " (and 1 other error)" - } - return fmt.Sprintf("%s (and %d other errors)", s, n-1) -} - -// any returns true if any element of m is an Error for which pred returns true. -func (m MultiError) any(pred func(Error) bool) bool { - for _, e := range m { - if ourErr, ok := e.(Error); ok && pred(ourErr) { - return true - } - } - return false -} diff --git a/vendor/github.com/gorilla/sessions/LICENSE b/vendor/github.com/gorilla/sessions/LICENSE deleted file mode 100644 index 0e5fb872800da..0000000000000 --- a/vendor/github.com/gorilla/sessions/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/sessions/doc.go b/vendor/github.com/gorilla/sessions/doc.go deleted file mode 100644 index 668e05e4555cf..0000000000000 --- a/vendor/github.com/gorilla/sessions/doc.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package sessions provides cookie and filesystem sessions and -infrastructure for custom session backends. - -The key features are: - - * Simple API: use it as an easy way to set signed (and optionally - encrypted) cookies. - * Built-in backends to store sessions in cookies or the filesystem. - * Flash messages: session values that last until read. - * Convenient way to switch session persistency (aka "remember me") and set - other attributes. - * Mechanism to rotate authentication and encryption keys. - * Multiple sessions per request, even using different backends. - * Interfaces and infrastructure for custom session backends: sessions from - different stores can be retrieved and batch-saved using a common API. - -Let's start with an example that shows the sessions API in a nutshell: - - import ( - "net/http" - "github.com/gorilla/sessions" - ) - - var store = sessions.NewCookieStore([]byte("something-very-secret")) - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // Get a session. We're ignoring the error resulted from decoding an - // existing session: Get() always returns a session, even if empty. - session, err := store.Get(r, "session-name") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Set some session values. - session.Values["foo"] = "bar" - session.Values[42] = 43 - // Save it before we write to the response/return from the handler. - session.Save(r, w) - } - -First we initialize a session store calling NewCookieStore() and passing a -secret key used to authenticate the session. Inside the handler, we call -store.Get() to retrieve an existing session or a new one. Then we set some -session values in session.Values, which is a map[interface{}]interface{}. -And finally we call session.Save() to save the session in the response. - -Note that in production code, we should check for errors when calling -session.Save(r, w), and either display an error message or otherwise handle it. - -Save must be called before writing to the response, otherwise the session -cookie will not be sent to the client. - -Important Note: If you aren't using gorilla/mux, you need to wrap your handlers -with context.ClearHandler as or else you will leak memory! An easy way to do this -is to wrap the top-level mux when calling http.ListenAndServe: - - http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux)) - -The ClearHandler function is provided by the gorilla/context package. - -That's all you need to know for the basic usage. Let's take a look at other -options, starting with flash messages. - -Flash messages are session values that last until read. The term appeared with -Ruby On Rails a few years back. When we request a flash message, it is removed -from the session. To add a flash, call session.AddFlash(), and to get all -flashes, call session.Flashes(). Here is an example: - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // Get a session. - session, err := store.Get(r, "session-name") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Get the previously flashes, if any. - if flashes := session.Flashes(); len(flashes) > 0 { - // Use the flash values. - } else { - // Set a new flash. - session.AddFlash("Hello, flash messages world!") - } - session.Save(r, w) - } - -Flash messages are useful to set information to be read after a redirection, -like after form submissions. - -There may also be cases where you want to store a complex datatype within a -session, such as a struct. Sessions are serialised using the encoding/gob package, -so it is easy to register new datatypes for storage in sessions: - - import( - "encoding/gob" - "github.com/gorilla/sessions" - ) - - type Person struct { - FirstName string - LastName string - Email string - Age int - } - - type M map[string]interface{} - - func init() { - - gob.Register(&Person{}) - gob.Register(&M{}) - } - -As it's not possible to pass a raw type as a parameter to a function, gob.Register() -relies on us passing it a value of the desired type. In the example above we've passed -it a pointer to a struct and a pointer to a custom type representing a -map[string]interface. (We could have passed non-pointer values if we wished.) This will -then allow us to serialise/deserialise values of those types to and from our sessions. - -Note that because session values are stored in a map[string]interface{}, there's -a need to type-assert data when retrieving it. We'll use the Person struct we registered above: - - func MyHandler(w http.ResponseWriter, r *http.Request) { - session, err := store.Get(r, "session-name") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Retrieve our struct and type-assert it - val := session.Values["person"] - var person = &Person{} - if person, ok := val.(*Person); !ok { - // Handle the case that it's not an expected type - } - - // Now we can use our person object - } - -By default, session cookies last for a month. This is probably too long for -some cases, but it is easy to change this and other attributes during -runtime. Sessions can be configured individually or the store can be -configured and then all sessions saved using it will use that configuration. -We access session.Options or store.Options to set a new configuration. The -fields are basically a subset of http.Cookie fields. Let's change the -maximum age of a session to one week: - - session.Options = &sessions.Options{ - Path: "/", - MaxAge: 86400 * 7, - HttpOnly: true, - } - -Sometimes we may want to change authentication and/or encryption keys without -breaking existing sessions. The CookieStore supports key rotation, and to use -it you just need to set multiple authentication and encryption keys, in pairs, -to be tested in order: - - var store = sessions.NewCookieStore( - []byte("new-authentication-key"), - []byte("new-encryption-key"), - []byte("old-authentication-key"), - []byte("old-encryption-key"), - ) - -New sessions will be saved using the first pair. Old sessions can still be -read because the first pair will fail, and the second will be tested. This -makes it easy to "rotate" secret keys and still be able to validate existing -sessions. Note: for all pairs the encryption key is optional; set it to nil -or omit it and and encryption won't be used. - -Multiple sessions can be used in the same request, even with different -session backends. When this happens, calling Save() on each session -individually would be cumbersome, so we have a way to save all sessions -at once: it's sessions.Save(). Here's an example: - - var store = sessions.NewCookieStore([]byte("something-very-secret")) - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // Get a session and set a value. - session1, _ := store.Get(r, "session-one") - session1.Values["foo"] = "bar" - // Get another session and set another value. - session2, _ := store.Get(r, "session-two") - session2.Values[42] = 43 - // Save all sessions. - sessions.Save(r, w) - } - -This is possible because when we call Get() from a session store, it adds the -session to a common registry. Save() uses it to save all registered sessions. -*/ -package sessions diff --git a/vendor/github.com/gorilla/sessions/lex.go b/vendor/github.com/gorilla/sessions/lex.go deleted file mode 100644 index 4bbbe1096de07..0000000000000 --- a/vendor/github.com/gorilla/sessions/lex.go +++ /dev/null @@ -1,102 +0,0 @@ -// This file contains code adapted from the Go standard library -// https://github.com/golang/go/blob/39ad0fd0789872f9469167be7fe9578625ff246e/src/net/http/lex.go - -package sessions - -import "strings" - -var isTokenTable = [127]bool{ - '!': true, - '#': true, - '$': true, - '%': true, - '&': true, - '\'': true, - '*': true, - '+': true, - '-': true, - '.': true, - '0': true, - '1': true, - '2': true, - '3': true, - '4': true, - '5': true, - '6': true, - '7': true, - '8': true, - '9': true, - 'A': true, - 'B': true, - 'C': true, - 'D': true, - 'E': true, - 'F': true, - 'G': true, - 'H': true, - 'I': true, - 'J': true, - 'K': true, - 'L': true, - 'M': true, - 'N': true, - 'O': true, - 'P': true, - 'Q': true, - 'R': true, - 'S': true, - 'T': true, - 'U': true, - 'W': true, - 'V': true, - 'X': true, - 'Y': true, - 'Z': true, - '^': true, - '_': true, - '`': true, - 'a': true, - 'b': true, - 'c': true, - 'd': true, - 'e': true, - 'f': true, - 'g': true, - 'h': true, - 'i': true, - 'j': true, - 'k': true, - 'l': true, - 'm': true, - 'n': true, - 'o': true, - 'p': true, - 'q': true, - 'r': true, - 's': true, - 't': true, - 'u': true, - 'v': true, - 'w': true, - 'x': true, - 'y': true, - 'z': true, - '|': true, - '~': true, -} - -func isToken(r rune) bool { - i := int(r) - return i < len(isTokenTable) && isTokenTable[i] -} - -func isNotToken(r rune) bool { - return !isToken(r) -} - -func isCookieNameValid(raw string) bool { - if raw == "" { - return false - } - return strings.IndexFunc(raw, isNotToken) < 0 -} diff --git a/vendor/github.com/gorilla/sessions/sessions.go b/vendor/github.com/gorilla/sessions/sessions.go deleted file mode 100644 index fe0d2bc8fa4a3..0000000000000 --- a/vendor/github.com/gorilla/sessions/sessions.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sessions - -import ( - "encoding/gob" - "fmt" - "net/http" - "time" - - "github.com/gorilla/context" -) - -// Default flashes key. -const flashesKey = "_flash" - -// Options -------------------------------------------------------------------- - -// Options stores configuration for a session or session store. -// -// Fields are a subset of http.Cookie fields. -type Options struct { - Path string - Domain string - // MaxAge=0 means no 'Max-Age' attribute specified. - // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'. - // MaxAge>0 means Max-Age attribute present and given in seconds. - MaxAge int - Secure bool - HttpOnly bool -} - -// Session -------------------------------------------------------------------- - -// NewSession is called by session stores to create a new session instance. -func NewSession(store Store, name string) *Session { - return &Session{ - Values: make(map[interface{}]interface{}), - store: store, - name: name, - } -} - -// Session stores the values and optional configuration for a session. -type Session struct { - // The ID of the session, generated by stores. It should not be used for - // user data. - ID string - // Values contains the user-data for the session. - Values map[interface{}]interface{} - Options *Options - IsNew bool - store Store - name string -} - -// Flashes returns a slice of flash messages from the session. -// -// A single variadic argument is accepted, and it is optional: it defines -// the flash key. If not defined "_flash" is used by default. -func (s *Session) Flashes(vars ...string) []interface{} { - var flashes []interface{} - key := flashesKey - if len(vars) > 0 { - key = vars[0] - } - if v, ok := s.Values[key]; ok { - // Drop the flashes and return it. - delete(s.Values, key) - flashes = v.([]interface{}) - } - return flashes -} - -// AddFlash adds a flash message to the session. -// -// A single variadic argument is accepted, and it is optional: it defines -// the flash key. If not defined "_flash" is used by default. -func (s *Session) AddFlash(value interface{}, vars ...string) { - key := flashesKey - if len(vars) > 0 { - key = vars[0] - } - var flashes []interface{} - if v, ok := s.Values[key]; ok { - flashes = v.([]interface{}) - } - s.Values[key] = append(flashes, value) -} - -// Save is a convenience method to save this session. It is the same as calling -// store.Save(request, response, session). You should call Save before writing to -// the response or returning from the handler. -func (s *Session) Save(r *http.Request, w http.ResponseWriter) error { - return s.store.Save(r, w, s) -} - -// Name returns the name used to register the session. -func (s *Session) Name() string { - return s.name -} - -// Store returns the session store used to register the session. -func (s *Session) Store() Store { - return s.store -} - -// Registry ------------------------------------------------------------------- - -// sessionInfo stores a session tracked by the registry. -type sessionInfo struct { - s *Session - e error -} - -// contextKey is the type used to store the registry in the context. -type contextKey int - -// registryKey is the key used to store the registry in the context. -const registryKey contextKey = 0 - -// GetRegistry returns a registry instance for the current request. -func GetRegistry(r *http.Request) *Registry { - registry := context.Get(r, registryKey) - if registry != nil { - return registry.(*Registry) - } - newRegistry := &Registry{ - request: r, - sessions: make(map[string]sessionInfo), - } - context.Set(r, registryKey, newRegistry) - return newRegistry -} - -// Registry stores sessions used during a request. -type Registry struct { - request *http.Request - sessions map[string]sessionInfo -} - -// Get registers and returns a session for the given name and session store. -// -// It returns a new session if there are no sessions registered for the name. -func (s *Registry) Get(store Store, name string) (session *Session, err error) { - if !isCookieNameValid(name) { - return nil, fmt.Errorf("sessions: invalid character in cookie name: %s", name) - } - if info, ok := s.sessions[name]; ok { - session, err = info.s, info.e - } else { - session, err = store.New(s.request, name) - session.name = name - s.sessions[name] = sessionInfo{s: session, e: err} - } - session.store = store - return -} - -// Save saves all sessions registered for the current request. -func (s *Registry) Save(w http.ResponseWriter) error { - var errMulti MultiError - for name, info := range s.sessions { - session := info.s - if session.store == nil { - errMulti = append(errMulti, fmt.Errorf( - "sessions: missing store for session %q", name)) - } else if err := session.store.Save(s.request, w, session); err != nil { - errMulti = append(errMulti, fmt.Errorf( - "sessions: error saving session %q -- %v", name, err)) - } - } - if errMulti != nil { - return errMulti - } - return nil -} - -// Helpers -------------------------------------------------------------------- - -func init() { - gob.Register([]interface{}{}) -} - -// Save saves all sessions used during the current request. -func Save(r *http.Request, w http.ResponseWriter) error { - return GetRegistry(r).Save(w) -} - -// NewCookie returns an http.Cookie with the options set. It also sets -// the Expires field calculated based on the MaxAge value, for Internet -// Explorer compatibility. -func NewCookie(name, value string, options *Options) *http.Cookie { - cookie := &http.Cookie{ - Name: name, - Value: value, - Path: options.Path, - Domain: options.Domain, - MaxAge: options.MaxAge, - Secure: options.Secure, - HttpOnly: options.HttpOnly, - } - if options.MaxAge > 0 { - d := time.Duration(options.MaxAge) * time.Second - cookie.Expires = time.Now().Add(d) - } else if options.MaxAge < 0 { - // Set it to the past to expire now. - cookie.Expires = time.Unix(1, 0) - } - return cookie -} - -// Error ---------------------------------------------------------------------- - -// MultiError stores multiple errors. -// -// Borrowed from the App Engine SDK. -type MultiError []error - -func (m MultiError) Error() string { - s, n := "", 0 - for _, e := range m { - if e != nil { - if n == 0 { - s = e.Error() - } - n++ - } - } - switch n { - case 0: - return "(0 errors)" - case 1: - return s - case 2: - return s + " (and 1 other error)" - } - return fmt.Sprintf("%s (and %d other errors)", s, n-1) -} diff --git a/vendor/github.com/gorilla/sessions/store.go b/vendor/github.com/gorilla/sessions/store.go deleted file mode 100644 index 4ff6b6c322c17..0000000000000 --- a/vendor/github.com/gorilla/sessions/store.go +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sessions - -import ( - "encoding/base32" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/gorilla/securecookie" -) - -// Store is an interface for custom session stores. -// -// See CookieStore and FilesystemStore for examples. -type Store interface { - // Get should return a cached session. - Get(r *http.Request, name string) (*Session, error) - - // New should create and return a new session. - // - // Note that New should never return a nil session, even in the case of - // an error if using the Registry infrastructure to cache the session. - New(r *http.Request, name string) (*Session, error) - - // Save should persist session to the underlying store implementation. - Save(r *http.Request, w http.ResponseWriter, s *Session) error -} - -// CookieStore ---------------------------------------------------------------- - -// NewCookieStore returns a new CookieStore. -// -// Keys are defined in pairs to allow key rotation, but the common case is -// to set a single authentication key and optionally an encryption key. -// -// The first key in a pair is used for authentication and the second for -// encryption. The encryption key can be set to nil or omitted in the last -// pair, but the authentication key is required in all pairs. -// -// It is recommended to use an authentication key with 32 or 64 bytes. -// The encryption key, if set, must be either 16, 24, or 32 bytes to select -// AES-128, AES-192, or AES-256 modes. -// -// Use the convenience function securecookie.GenerateRandomKey() to create -// strong keys. -func NewCookieStore(keyPairs ...[]byte) *CookieStore { - cs := &CookieStore{ - Codecs: securecookie.CodecsFromPairs(keyPairs...), - Options: &Options{ - Path: "/", - MaxAge: 86400 * 30, - }, - } - - cs.MaxAge(cs.Options.MaxAge) - return cs -} - -// CookieStore stores sessions using secure cookies. -type CookieStore struct { - Codecs []securecookie.Codec - Options *Options // default configuration -} - -// Get returns a session for the given name after adding it to the registry. -// -// It returns a new session if the sessions doesn't exist. Access IsNew on -// the session to check if it is an existing session or a new one. -// -// It returns a new session and an error if the session exists but could -// not be decoded. -func (s *CookieStore) Get(r *http.Request, name string) (*Session, error) { - return GetRegistry(r).Get(s, name) -} - -// New returns a session for the given name without adding it to the registry. -// -// The difference between New() and Get() is that calling New() twice will -// decode the session data twice, while Get() registers and reuses the same -// decoded session after the first call. -func (s *CookieStore) New(r *http.Request, name string) (*Session, error) { - session := NewSession(s, name) - opts := *s.Options - session.Options = &opts - session.IsNew = true - var err error - if c, errCookie := r.Cookie(name); errCookie == nil { - err = securecookie.DecodeMulti(name, c.Value, &session.Values, - s.Codecs...) - if err == nil { - session.IsNew = false - } - } - return session, err -} - -// Save adds a single session to the response. -func (s *CookieStore) Save(r *http.Request, w http.ResponseWriter, - session *Session) error { - encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, - s.Codecs...) - if err != nil { - return err - } - http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options)) - return nil -} - -// MaxAge sets the maximum age for the store and the underlying cookie -// implementation. Individual sessions can be deleted by setting Options.MaxAge -// = -1 for that session. -func (s *CookieStore) MaxAge(age int) { - s.Options.MaxAge = age - - // Set the maxAge for each securecookie instance. - for _, codec := range s.Codecs { - if sc, ok := codec.(*securecookie.SecureCookie); ok { - sc.MaxAge(age) - } - } -} - -// FilesystemStore ------------------------------------------------------------ - -var fileMutex sync.RWMutex - -// NewFilesystemStore returns a new FilesystemStore. -// -// The path argument is the directory where sessions will be saved. If empty -// it will use os.TempDir(). -// -// See NewCookieStore() for a description of the other parameters. -func NewFilesystemStore(path string, keyPairs ...[]byte) *FilesystemStore { - if path == "" { - path = os.TempDir() - } - fs := &FilesystemStore{ - Codecs: securecookie.CodecsFromPairs(keyPairs...), - Options: &Options{ - Path: "/", - MaxAge: 86400 * 30, - }, - path: path, - } - - fs.MaxAge(fs.Options.MaxAge) - return fs -} - -// FilesystemStore stores sessions in the filesystem. -// -// It also serves as a reference for custom stores. -// -// This store is still experimental and not well tested. Feedback is welcome. -type FilesystemStore struct { - Codecs []securecookie.Codec - Options *Options // default configuration - path string -} - -// MaxLength restricts the maximum length of new sessions to l. -// If l is 0 there is no limit to the size of a session, use with caution. -// The default for a new FilesystemStore is 4096. -func (s *FilesystemStore) MaxLength(l int) { - for _, c := range s.Codecs { - if codec, ok := c.(*securecookie.SecureCookie); ok { - codec.MaxLength(l) - } - } -} - -// Get returns a session for the given name after adding it to the registry. -// -// See CookieStore.Get(). -func (s *FilesystemStore) Get(r *http.Request, name string) (*Session, error) { - return GetRegistry(r).Get(s, name) -} - -// New returns a session for the given name without adding it to the registry. -// -// See CookieStore.New(). -func (s *FilesystemStore) New(r *http.Request, name string) (*Session, error) { - session := NewSession(s, name) - opts := *s.Options - session.Options = &opts - session.IsNew = true - var err error - if c, errCookie := r.Cookie(name); errCookie == nil { - err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...) - if err == nil { - err = s.load(session) - if err == nil { - session.IsNew = false - } - } - } - return session, err -} - -// Save adds a single session to the response. -// -// If the Options.MaxAge of the session is <= 0 then the session file will be -// deleted from the store path. With this process it enforces the properly -// session cookie handling so no need to trust in the cookie management in the -// web browser. -func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter, - session *Session) error { - // Delete if max-age is <= 0 - if session.Options.MaxAge <= 0 { - if err := s.erase(session); err != nil { - return err - } - http.SetCookie(w, NewCookie(session.Name(), "", session.Options)) - return nil - } - - if session.ID == "" { - // Because the ID is used in the filename, encode it to - // use alphanumeric characters only. - session.ID = strings.TrimRight( - base32.StdEncoding.EncodeToString( - securecookie.GenerateRandomKey(32)), "=") - } - if err := s.save(session); err != nil { - return err - } - encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, - s.Codecs...) - if err != nil { - return err - } - http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options)) - return nil -} - -// MaxAge sets the maximum age for the store and the underlying cookie -// implementation. Individual sessions can be deleted by setting Options.MaxAge -// = -1 for that session. -func (s *FilesystemStore) MaxAge(age int) { - s.Options.MaxAge = age - - // Set the maxAge for each securecookie instance. - for _, codec := range s.Codecs { - if sc, ok := codec.(*securecookie.SecureCookie); ok { - sc.MaxAge(age) - } - } -} - -// save writes encoded session.Values to a file. -func (s *FilesystemStore) save(session *Session) error { - encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, - s.Codecs...) - if err != nil { - return err - } - filename := filepath.Join(s.path, "session_"+session.ID) - fileMutex.Lock() - defer fileMutex.Unlock() - return ioutil.WriteFile(filename, []byte(encoded), 0600) -} - -// load reads a file and decodes its content into session.Values. -func (s *FilesystemStore) load(session *Session) error { - filename := filepath.Join(s.path, "session_"+session.ID) - fileMutex.RLock() - defer fileMutex.RUnlock() - fdata, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - if err = securecookie.DecodeMulti(session.Name(), string(fdata), - &session.Values, s.Codecs...); err != nil { - return err - } - return nil -} - -// delete session file -func (s *FilesystemStore) erase(session *Session) error { - filename := filepath.Join(s.path, "session_"+session.ID) - - fileMutex.RLock() - defer fileMutex.RUnlock() - - err := os.Remove(filename) - return err -}