gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

context.go (3583B)


      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 }