77 "net"
88 "net/http"
99 "strings"
10- "sync "
10+ "time "
1111
1212 "golang.org/x/net/context"
1313 "golang.org/x/net/websocket"
@@ -24,8 +24,6 @@ type Param struct {
2424// It is therefore safe to read values by the index.
2525type Params []Param
2626
27- type store map [string ]interface {}
28-
2927// Context is the context interface type
3028type Context interface {
3129 context.Context
@@ -35,8 +33,8 @@ type Context interface {
3533 Param (name string ) string
3634 ParseForm () error
3735 ParseMultipartForm (maxMemory int64 ) error
38- Set (key string , value interface {})
39- Get (key string ) (value interface {}, exists bool )
36+ Set (key interface {} , value interface {})
37+ Get (key interface {} ) (value interface {}, exists bool )
4038 Next ()
4139 RequestStart (w http.ResponseWriter , r * http.Request )
4240 RequestEnd ()
@@ -58,19 +56,17 @@ type Context interface {
5856
5957// Ctx encapsulates the http request, response context
6058type Ctx struct {
61- context.Context
59+ netContext context.Context
6260 request * http.Request
6361 response * Response
6462 websocket * websocket.Conn
6563 params Params
6664 handlers HandlersChain
65+ parent Context
6766 handlerName string
68- store store
6967 index int
7068 formParsed bool
7169 multipartFormParsed bool
72- parent Context
73- m * sync.RWMutex
7470}
7571
7672var _ context.Context = & Ctx {}
@@ -119,7 +115,7 @@ func (c *Ctx) RequestStart(w http.ResponseWriter, r *http.Request) {
119115 c .request = r
120116 c .response .reset (w )
121117 c .params = c .params [0 :0 ]
122- c .store = nil
118+ c .netContext = context . Background () // in go 1.7 will call r.Context(), netContext will go away and be replaced with the Request objects Context
123119 c .index = - 1
124120 c .handlers = nil
125121 c .formParsed = false
@@ -186,34 +182,19 @@ func (c *Ctx) ParseMultipartForm(maxMemory int64) error {
186182 return nil
187183}
188184
189- // Set is used to store a new key/value pair exclusivelly for thisContext.
190- // It also lazy initializes c.Keys if it was not used previously.
191- func (c * Ctx ) Set (key string , value interface {}) {
192-
193- if c .store == nil {
194-
195- if c .m == nil {
196- c .m = new (sync.RWMutex )
197- }
198-
199- c .m .Lock ()
200- c .store = make (store )
201- } else {
202- c .m .Lock ()
203- }
204-
205- c .store [key ] = value
206- c .m .Unlock ()
185+ // Set is used to store a new key/value pair using the
186+ // golang.org/x/net/context contained on this Context.
187+ // It is a shortcut for context.WithValue(..., ...)
188+ func (c * Ctx ) Set (key interface {}, value interface {}) {
189+ c .netContext = context .WithValue (c .netContext , key , value )
207190}
208191
209- // Get returns the value for the given key, ie: (value, true).
210- // If the value does not exists it returns (nil, false)
211- func (c * Ctx ) Get (key string ) (value interface {}, exists bool ) {
212- if c .store != nil {
213- c .m .RLock ()
214- value , exists = c .store [key ]
215- c .m .RUnlock ()
216- }
192+ // Get returns the value for the given key and is a shortcut
193+ // for the golang.org/x/net/context context.Value(...) ... but it
194+ // also returns if the value was found or not.
195+ func (c * Ctx ) Get (key interface {}) (value interface {}, exists bool ) {
196+ value = c .netContext .Value (key )
197+ exists = value != nil
217198 return
218199}
219200
@@ -424,3 +405,67 @@ func (c *Ctx) Inline(r io.Reader, filename string) (err error) {
424405
425406 return
426407}
408+
409+ // golang.org/x/net/context functions to comply with context.Context interface and keep context update on lars.Context object
410+
411+ // Context returns the request's context. To change the context, use
412+ // WithContext.
413+ //
414+ // The returned context is always non-nil.
415+ func (c * Ctx ) Context () context.Context {
416+ return c .netContext // TODO: in go 1.7 return c.request.Context()
417+ }
418+
419+ // WithContext updates the underlying request's context with to ctx
420+ // The provided ctx must be non-nil.
421+ func (c * Ctx ) WithContext (ctx context.Context ) {
422+ c .netContext = ctx // TODO: in go 1.7 must update Request object after calling c.request.WithContext(...)
423+ }
424+
425+ // Deadline calls the underlying golang.org/x/net/context Deadline()
426+ func (c * Ctx ) Deadline () (deadline time.Time , ok bool ) {
427+ return c .netContext .Deadline ()
428+ }
429+
430+ // Done calls the underlying golang.org/x/net/context Done()
431+ func (c * Ctx ) Done () <- chan struct {} {
432+ return c .netContext .Done ()
433+ }
434+
435+ // Err calls the underlying golang.org/x/net/context Err()
436+ func (c * Ctx ) Err () error {
437+ return c .netContext .Err ()
438+ }
439+
440+ // Value calls the underlying golang.org/x/net/context Value()
441+ func (c * Ctx ) Value (key interface {}) interface {} {
442+ return c .netContext .Value (key )
443+ }
444+
445+ // WithCancel calls golang.org/x/net/context WithCancel and automatically
446+ // updates context on the containing las.Context object.
447+ func (c * Ctx ) WithCancel () (cf context.CancelFunc ) {
448+ c .netContext , cf = context .WithCancel (c .netContext )
449+ return
450+ }
451+
452+ // WithDeadline calls golang.org/x/net/context WithDeadline and automatically
453+ // updates context on the containing las.Context object.
454+ func (c * Ctx ) WithDeadline (deadline time.Time ) (cf context.CancelFunc ) {
455+ c .netContext , cf = context .WithDeadline (c .netContext , deadline )
456+ return
457+ }
458+
459+ // WithTimeout calls golang.org/x/net/context WithTimeout and automatically
460+ // updates context on the containing las.Context object.
461+ func (c * Ctx ) WithTimeout (timeout time.Duration ) (cf context.CancelFunc ) {
462+ c .netContext , cf = context .WithTimeout (c .netContext , timeout )
463+ return
464+ }
465+
466+ // WithValue calls golang.org/x/net/context WithValue and automatically
467+ // updates context on the containing las.Context object.
468+ // Can also use Set() function on Context object (Recommended)
469+ func (c * Ctx ) WithValue (key interface {}, val interface {}) {
470+ c .netContext = context .WithValue (c .netContext , key , val )
471+ }
0 commit comments