mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 23:48:27 +00:00
gb vendor fetch github.com/gorilla/context
This commit is contained in:
parent
9e6127d12a
commit
094345830e
6 changed files with 436 additions and 1 deletions
6
vendor/manifest
vendored
6
vendor/manifest
vendored
|
@ -59,6 +59,12 @@
|
||||||
"revision": "7db9049039a047d955fe8c19b83c8ff5abd765c7",
|
"revision": "7db9049039a047d955fe8c19b83c8ff5abd765c7",
|
||||||
"branch": "master"
|
"branch": "master"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"importpath": "github.com/gorilla/context",
|
||||||
|
"repository": "https://github.com/gorilla/context",
|
||||||
|
"revision": "08b5f424b9271eedf6f9f0ce86cb9396ed337a42",
|
||||||
|
"branch": "master"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"importpath": "github.com/gorilla/mux",
|
"importpath": "github.com/gorilla/mux",
|
||||||
"repository": "https://github.com/gorilla/mux",
|
"repository": "https://github.com/gorilla/mux",
|
||||||
|
|
27
vendor/src/github.com/gorilla/context/LICENSE
vendored
Normal file
27
vendor/src/github.com/gorilla/context/LICENSE
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
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.
|
10
vendor/src/github.com/gorilla/context/README.md
vendored
Normal file
10
vendor/src/github.com/gorilla/context/README.md
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
context
|
||||||
|
=======
|
||||||
|
[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)
|
||||||
|
|
||||||
|
gorilla/context is a general purpose registry for global request variables.
|
||||||
|
|
||||||
|
> Note: gorilla/context, having been born well before `context.Context` existed, does not play well
|
||||||
|
> with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.
|
||||||
|
|
||||||
|
Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
|
143
vendor/src/github.com/gorilla/context/context.go
vendored
Normal file
143
vendor/src/github.com/gorilla/context/context.go
vendored
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
// 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)
|
||||||
|
})
|
||||||
|
}
|
161
vendor/src/github.com/gorilla/context/context_test.go
vendored
Normal file
161
vendor/src/github.com/gorilla/context/context_test.go
vendored
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// 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"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type keyType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
key1 keyType = iota
|
||||||
|
key2
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestContext(t *testing.T) {
|
||||||
|
assertEqual := func(val interface{}, exp interface{}) {
|
||||||
|
if val != exp {
|
||||||
|
t.Errorf("Expected %v, got %v.", exp, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||||
|
emptyR, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||||
|
|
||||||
|
// Get()
|
||||||
|
assertEqual(Get(r, key1), nil)
|
||||||
|
|
||||||
|
// Set()
|
||||||
|
Set(r, key1, "1")
|
||||||
|
assertEqual(Get(r, key1), "1")
|
||||||
|
assertEqual(len(data[r]), 1)
|
||||||
|
|
||||||
|
Set(r, key2, "2")
|
||||||
|
assertEqual(Get(r, key2), "2")
|
||||||
|
assertEqual(len(data[r]), 2)
|
||||||
|
|
||||||
|
//GetOk
|
||||||
|
value, ok := GetOk(r, key1)
|
||||||
|
assertEqual(value, "1")
|
||||||
|
assertEqual(ok, true)
|
||||||
|
|
||||||
|
value, ok = GetOk(r, "not exists")
|
||||||
|
assertEqual(value, nil)
|
||||||
|
assertEqual(ok, false)
|
||||||
|
|
||||||
|
Set(r, "nil value", nil)
|
||||||
|
value, ok = GetOk(r, "nil value")
|
||||||
|
assertEqual(value, nil)
|
||||||
|
assertEqual(ok, true)
|
||||||
|
|
||||||
|
// GetAll()
|
||||||
|
values := GetAll(r)
|
||||||
|
assertEqual(len(values), 3)
|
||||||
|
|
||||||
|
// GetAll() for empty request
|
||||||
|
values = GetAll(emptyR)
|
||||||
|
if values != nil {
|
||||||
|
t.Error("GetAll didn't return nil value for invalid request")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllOk()
|
||||||
|
values, ok = GetAllOk(r)
|
||||||
|
assertEqual(len(values), 3)
|
||||||
|
assertEqual(ok, true)
|
||||||
|
|
||||||
|
// GetAllOk() for empty request
|
||||||
|
values, ok = GetAllOk(emptyR)
|
||||||
|
assertEqual(len(values), 0)
|
||||||
|
assertEqual(ok, false)
|
||||||
|
|
||||||
|
// Delete()
|
||||||
|
Delete(r, key1)
|
||||||
|
assertEqual(Get(r, key1), nil)
|
||||||
|
assertEqual(len(data[r]), 2)
|
||||||
|
|
||||||
|
Delete(r, key2)
|
||||||
|
assertEqual(Get(r, key2), nil)
|
||||||
|
assertEqual(len(data[r]), 1)
|
||||||
|
|
||||||
|
// Clear()
|
||||||
|
Clear(r)
|
||||||
|
assertEqual(len(data), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parallelReader(r *http.Request, key string, iterations int, wait, done chan struct{}) {
|
||||||
|
<-wait
|
||||||
|
for i := 0; i < iterations; i++ {
|
||||||
|
Get(r, key)
|
||||||
|
}
|
||||||
|
done <- struct{}{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func parallelWriter(r *http.Request, key, value string, iterations int, wait, done chan struct{}) {
|
||||||
|
<-wait
|
||||||
|
for i := 0; i < iterations; i++ {
|
||||||
|
Set(r, key, value)
|
||||||
|
}
|
||||||
|
done <- struct{}{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func benchmarkMutex(b *testing.B, numReaders, numWriters, iterations int) {
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
|
||||||
|
done := make(chan struct{})
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
wait := make(chan struct{})
|
||||||
|
|
||||||
|
for i := 0; i < numReaders; i++ {
|
||||||
|
go parallelReader(r, "test", iterations, wait, done)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < numWriters; i++ {
|
||||||
|
go parallelWriter(r, "test", "123", iterations, wait, done)
|
||||||
|
}
|
||||||
|
|
||||||
|
close(wait)
|
||||||
|
|
||||||
|
for i := 0; i < numReaders+numWriters; i++ {
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkMutexSameReadWrite1(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 1, 1, 32)
|
||||||
|
}
|
||||||
|
func BenchmarkMutexSameReadWrite2(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 2, 2, 32)
|
||||||
|
}
|
||||||
|
func BenchmarkMutexSameReadWrite4(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 4, 4, 32)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex1(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 2, 8, 32)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex2(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 16, 4, 64)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex3(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 1, 2, 128)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex4(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 128, 32, 256)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex5(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 1024, 2048, 64)
|
||||||
|
}
|
||||||
|
func BenchmarkMutex6(b *testing.B) {
|
||||||
|
benchmarkMutex(b, 2048, 1024, 512)
|
||||||
|
}
|
88
vendor/src/github.com/gorilla/context/doc.go
vendored
Normal file
88
vendor/src/github.com/gorilla/context/doc.go
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// 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
|
Loading…
Reference in a new issue