...

Source file src/github.com/gorilla/context/context.go

Documentation: github.com/gorilla/context

     1  // Copyright 2012 The Gorilla Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package context
     6  
     7  import (
     8  	"net/http"
     9  	"sync"
    10  	"time"
    11  )
    12  
    13  var (
    14  	mutex sync.RWMutex
    15  	data  = make(map[*http.Request]map[interface{}]interface{})
    16  	datat = make(map[*http.Request]int64)
    17  )
    18  
    19  // Set stores a value for a given key in a given request.
    20  func Set(r *http.Request, key, val interface{}) {
    21  	mutex.Lock()
    22  	if data[r] == nil {
    23  		data[r] = make(map[interface{}]interface{})
    24  		datat[r] = time.Now().Unix()
    25  	}
    26  	data[r][key] = val
    27  	mutex.Unlock()
    28  }
    29  
    30  // Get returns a value stored for a given key in a given request.
    31  func Get(r *http.Request, key interface{}) interface{} {
    32  	mutex.RLock()
    33  	if ctx := data[r]; ctx != nil {
    34  		value := ctx[key]
    35  		mutex.RUnlock()
    36  		return value
    37  	}
    38  	mutex.RUnlock()
    39  	return nil
    40  }
    41  
    42  // GetOk returns stored value and presence state like multi-value return of map access.
    43  func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
    44  	mutex.RLock()
    45  	if _, ok := data[r]; ok {
    46  		value, ok := data[r][key]
    47  		mutex.RUnlock()
    48  		return value, ok
    49  	}
    50  	mutex.RUnlock()
    51  	return nil, false
    52  }
    53  
    54  // GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
    55  func GetAll(r *http.Request) map[interface{}]interface{} {
    56  	mutex.RLock()
    57  	if context, ok := data[r]; ok {
    58  		result := make(map[interface{}]interface{}, len(context))
    59  		for k, v := range context {
    60  			result[k] = v
    61  		}
    62  		mutex.RUnlock()
    63  		return result
    64  	}
    65  	mutex.RUnlock()
    66  	return nil
    67  }
    68  
    69  // GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
    70  // the request was registered.
    71  func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
    72  	mutex.RLock()
    73  	context, ok := data[r]
    74  	result := make(map[interface{}]interface{}, len(context))
    75  	for k, v := range context {
    76  		result[k] = v
    77  	}
    78  	mutex.RUnlock()
    79  	return result, ok
    80  }
    81  
    82  // Delete removes a value stored for a given key in a given request.
    83  func Delete(r *http.Request, key interface{}) {
    84  	mutex.Lock()
    85  	if data[r] != nil {
    86  		delete(data[r], key)
    87  	}
    88  	mutex.Unlock()
    89  }
    90  
    91  // Clear removes all values stored for a given request.
    92  //
    93  // This is usually called by a handler wrapper to clean up request
    94  // variables at the end of a request lifetime. See ClearHandler().
    95  func Clear(r *http.Request) {
    96  	mutex.Lock()
    97  	clear(r)
    98  	mutex.Unlock()
    99  }
   100  
   101  // clear is Clear without the lock.
   102  func clear(r *http.Request) {
   103  	delete(data, r)
   104  	delete(datat, r)
   105  }
   106  
   107  // Purge removes request data stored for longer than maxAge, in seconds.
   108  // It returns the amount of requests removed.
   109  //
   110  // If maxAge <= 0, all request data is removed.
   111  //
   112  // This is only used for sanity check: in case context cleaning was not
   113  // properly set some request data can be kept forever, consuming an increasing
   114  // amount of memory. In case this is detected, Purge() must be called
   115  // periodically until the problem is fixed.
   116  func Purge(maxAge int) int {
   117  	mutex.Lock()
   118  	count := 0
   119  	if maxAge <= 0 {
   120  		count = len(data)
   121  		data = make(map[*http.Request]map[interface{}]interface{})
   122  		datat = make(map[*http.Request]int64)
   123  	} else {
   124  		min := time.Now().Unix() - int64(maxAge)
   125  		for r := range data {
   126  			if datat[r] < min {
   127  				clear(r)
   128  				count++
   129  			}
   130  		}
   131  	}
   132  	mutex.Unlock()
   133  	return count
   134  }
   135  
   136  // ClearHandler wraps an http.Handler and clears request values at the end
   137  // of a request lifetime.
   138  func ClearHandler(h http.Handler) http.Handler {
   139  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   140  		defer Clear(r)
   141  		h.ServeHTTP(w, r)
   142  	})
   143  }
   144  

View as plain text