mirror of
				https://github.com/minio/minio.git
				synced 2025-10-29 15:55:00 -04:00 
			
		
		
		
	Merge commit '4aa2e2eaa01e04e05cfbcd765afb5059ff85b8e1' as 'third_party/src/github.com/gorilla/context'
This commit is contained in:
		
						commit
						111b2639cd
					
				
							
								
								
									
										7
									
								
								third_party/src/github.com/gorilla/context/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								third_party/src/github.com/gorilla/context/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| language: go | ||||
| 
 | ||||
| go: | ||||
|   - 1.0 | ||||
|   - 1.1 | ||||
|   - 1.2 | ||||
|   - tip | ||||
							
								
								
									
										27
									
								
								third_party/src/github.com/gorilla/context/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								third_party/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. | ||||
							
								
								
									
										7
									
								
								third_party/src/github.com/gorilla/context/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								third_party/src/github.com/gorilla/context/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| context | ||||
| ======= | ||||
| [](https://travis-ci.org/gorilla/context) | ||||
| 
 | ||||
| gorilla/context is a general purpose registry for global request variables. | ||||
| 
 | ||||
| Read the full documentation here: http://www.gorillatoolkit.org/pkg/context | ||||
							
								
								
									
										143
									
								
								third_party/src/github.com/gorilla/context/context.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								third_party/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
									
								
								third_party/src/github.com/gorilla/context/context_test.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								third_party/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(value, nil) | ||||
| 	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++ { | ||||
| 		Get(r, key) | ||||
| 	} | ||||
| 	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) | ||||
| } | ||||
							
								
								
									
										82
									
								
								third_party/src/github.com/gorilla/context/doc.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								third_party/src/github.com/gorilla/context/doc.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| // 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. | ||||
| 
 | ||||
| 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user