mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 05:08:11 +00:00 
			
		
		
		
	Migrate to dep (#3972)
* Update makefile to use dep * Migrate to dep * Fix some deps * Try to find a better version for golang.org/x/net * Try to find a better version for golang.org/x/oauth2
This commit is contained in:
		
				
					committed by
					
						
						Lauris BH
					
				
			
			
				
	
			
			
			
						parent
						
							d7fd9bf7bb
						
					
				
				
					commit
					3f3383dc0a
				
			
							
								
								
									
										10
									
								
								vendor/github.com/gorilla/context/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/gorilla/context/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,10 +0,0 @@
 | 
			
		||||
context
 | 
			
		||||
=======
 | 
			
		||||
[](https://travis-ci.org/gorilla/context)
 | 
			
		||||
 | 
			
		||||
gorilla/context is a general purpose registry for global request variables.
 | 
			
		||||
 | 
			
		||||
> Note: gorilla/context, having been born well before `context.Context` existed, does not play well
 | 
			
		||||
> with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.
 | 
			
		||||
 | 
			
		||||
Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
 | 
			
		||||
							
								
								
									
										299
									
								
								vendor/github.com/gorilla/mux/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										299
									
								
								vendor/github.com/gorilla/mux/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,299 +0,0 @@
 | 
			
		||||
gorilla/mux
 | 
			
		||||
===
 | 
			
		||||
[](https://godoc.org/github.com/gorilla/mux)
 | 
			
		||||
[](https://travis-ci.org/gorilla/mux)
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
http://www.gorillatoolkit.org/pkg/mux
 | 
			
		||||
 | 
			
		||||
Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
 | 
			
		||||
their respective handler.
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
 | 
			
		||||
* 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.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
* [Install](#install)
 | 
			
		||||
* [Examples](#examples)
 | 
			
		||||
* [Matching Routes](#matching-routes)
 | 
			
		||||
* [Static Files](#static-files)
 | 
			
		||||
* [Registered URLs](#registered-urls)
 | 
			
		||||
* [Full Example](#full-example)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Install
 | 
			
		||||
 | 
			
		||||
With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
go get -u github.com/gorilla/mux
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
Let's start registering a couple of URL paths and handlers:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r := mux.NewRouter()
 | 
			
		||||
r.HandleFunc("/products/{key}", ProductHandler)
 | 
			
		||||
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
 | 
			
		||||
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
### Matching Routes
 | 
			
		||||
 | 
			
		||||
Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r.PathPrefix("/products/")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
...or HTTP methods:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r.Methods("GET", "POST")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
...or URL schemes:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r.Schemes("https")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
...or header values:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r.Headers("X-Requested-With", "XMLHttpRequest")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
...or query values:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r.Queries("key", "value")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
...or to use a custom matcher function:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
r := mux.NewRouter()
 | 
			
		||||
s := r.Host("www.example.com").Subrouter()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then register routes in the subrouter:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Static Files
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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/<filename>
 | 
			
		||||
	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())
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Registered URLs
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// "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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Full Example
 | 
			
		||||
 | 
			
		||||
Here's a complete, runnable example of a small `mux` based server:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"log"
 | 
			
		||||
	"github.com/gorilla/mux"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func YourHandler(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	w.Write([]byte("Gorilla!\n"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	r := mux.NewRouter()
 | 
			
		||||
	// Routes consist of a path and a handler function.
 | 
			
		||||
	r.HandleFunc("/", YourHandler)
 | 
			
		||||
 | 
			
		||||
	// Bind to a port and pass our router in
 | 
			
		||||
	log.Fatal(http.ListenAndServe(":8000", r))
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
BSD licensed. See the LICENSE file for details.
 | 
			
		||||
							
								
								
									
										78
									
								
								vendor/github.com/gorilla/securecookie/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								vendor/github.com/gorilla/securecookie/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,78 +0,0 @@
 | 
			
		||||
securecookie
 | 
			
		||||
============
 | 
			
		||||
[](https://godoc.org/github.com/gorilla/securecookie) [](https://travis-ci.org/gorilla/securecookie)
 | 
			
		||||
 | 
			
		||||
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. It is still
 | 
			
		||||
recommended that sensitive data not be stored in cookies, and that HTTPS be used
 | 
			
		||||
to prevent cookie [replay attacks](https://en.wikipedia.org/wiki/Replay_attack).
 | 
			
		||||
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
To use it, first create a new SecureCookie instance:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Hash keys should be at least 32 bytes long
 | 
			
		||||
var hashKey = []byte("very-secret")
 | 
			
		||||
// Block keys should be 16 bytes (AES-128) or 32 bytes (AES-256) long.
 | 
			
		||||
// Shorter keys may weaken the encryption used.
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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:  "/",
 | 
			
		||||
			Secure: true,
 | 
			
		||||
			HttpOnly: true,
 | 
			
		||||
		}
 | 
			
		||||
		http.SetCookie(w, cookie)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Later, use the same SecureCookie instance to decode and validate a cookie
 | 
			
		||||
value:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
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. An optional JSON encoder that uses `encoding/json` is
 | 
			
		||||
available for types compatible with JSON.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
BSD licensed. See the LICENSE file for details.
 | 
			
		||||
							
								
								
									
										81
									
								
								vendor/github.com/gorilla/sessions/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/gorilla/sessions/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,81 +0,0 @@
 | 
			
		||||
sessions
 | 
			
		||||
========
 | 
			
		||||
[](https://godoc.org/github.com/gorilla/sessions) [](https://travis-ci.org/gorilla/sessions)
 | 
			
		||||
 | 
			
		||||
gorilla/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:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
	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, _ := store.Get(r, "session-name")
 | 
			
		||||
		// 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.
 | 
			
		||||
 | 
			
		||||
Important Note: If you aren't using gorilla/mux, you need to wrap your handlers
 | 
			
		||||
with
 | 
			
		||||
[`context.ClearHandler`](http://www.gorillatoolkit.org/pkg/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:
 | 
			
		||||
 | 
			
		||||
More examples are available [on the Gorilla
 | 
			
		||||
website](http://www.gorillatoolkit.org/pkg/sessions).
 | 
			
		||||
 | 
			
		||||
## Store Implementations
 | 
			
		||||
 | 
			
		||||
Other implementations of the `sessions.Store` interface:
 | 
			
		||||
 | 
			
		||||
* [github.com/starJammer/gorilla-sessions-arangodb](https://github.com/starJammer/gorilla-sessions-arangodb) - ArangoDB
 | 
			
		||||
* [github.com/yosssi/boltstore](https://github.com/yosssi/boltstore) - Bolt
 | 
			
		||||
* [github.com/srinathgs/couchbasestore](https://github.com/srinathgs/couchbasestore) - Couchbase
 | 
			
		||||
* [github.com/denizeren/dynamostore](https://github.com/denizeren/dynamostore) - Dynamodb on AWS
 | 
			
		||||
* [github.com/bradleypeabody/gorilla-sessions-memcache](https://github.com/bradleypeabody/gorilla-sessions-memcache) - Memcache
 | 
			
		||||
* [github.com/dsoprea/go-appengine-sessioncascade](https://github.com/dsoprea/go-appengine-sessioncascade) - Memcache/Datastore/Context in AppEngine
 | 
			
		||||
* [github.com/kidstuff/mongostore](https://github.com/kidstuff/mongostore) - MongoDB
 | 
			
		||||
* [github.com/srinathgs/mysqlstore](https://github.com/srinathgs/mysqlstore) - MySQL
 | 
			
		||||
* [github.com/EnumApps/clustersqlstore](https://github.com/EnumApps/clustersqlstore) - MySQL Cluster
 | 
			
		||||
* [github.com/antonlindstrom/pgstore](https://github.com/antonlindstrom/pgstore) - PostgreSQL
 | 
			
		||||
* [github.com/boj/redistore](https://github.com/boj/redistore) - Redis
 | 
			
		||||
* [github.com/boj/rethinkstore](https://github.com/boj/rethinkstore) - RethinkDB
 | 
			
		||||
* [github.com/boj/riakstore](https://github.com/boj/riakstore) - Riak
 | 
			
		||||
* [github.com/michaeljs1990/sqlitestore](https://github.com/michaeljs1990/sqlitestore) - SQLite
 | 
			
		||||
* [github.com/wader/gormstore](https://github.com/wader/gormstore) - GORM (MySQL, PostgreSQL, SQLite)
 | 
			
		||||
* [github.com/gernest/qlstore](https://github.com/gernest/qlstore) - ql
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
BSD licensed. See the LICENSE file for details.
 | 
			
		||||
		Reference in New Issue
	
	Block a user