bsed / gorilla

Automatically exported from code.google.com/p/gorilla
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

[mux] Pre and Post request hooks for timing and logging #2

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
It would be nice to have hooks to instrument and log http requests.

A more general and possibly nicer solution would be something similar (in 
design) to the Filters concept in Java servlets.

Here's a hypothetical no-op filter:
func Filter(w http.RequestWriter, r *http.Request, next http.Handler) {
    next.ServeHTTP(w,r)
}

Timing filter:
func Filter(w http.RequestWriter, r *http.Request, next http.Handler) {
    before := time.Nanoseconds()
    next.ServeHTTP(w,r)
    log.Debugf("Call took %v ms", strconv.Ftoa64(float64(time.Nanoseconds() - int64(t))/1000000, 'f', 3))
}

Basic design for implementation:
Run through all Filters and match them, building a list of Filters that 
matched. Then find the actual Handler. Call Filter on each one, with the next 
one in the chain.

This would also enable things like blanket XSRF protection for an entire 
subpath. Thoughts?

Sanjay

Original issue reported on code.google.com by balasan...@gmail.com on 7 Sep 2011 at 6:23

GoogleCodeExporter commented 9 years ago
Whoops, brain fart.

This implementation would only allow single filters, because next must be a 
http.Handler. Instead, next would have to be a slice of Filters, and it would 
have to call next[0].Filter(w,r,next[1:]). Of course, that could be wrapped 
into a function so as to allow you to say something simpler.

Original comment by balasan...@gmail.com on 7 Sep 2011 at 6:32

GoogleCodeExporter commented 9 years ago

Original comment by rodrigo.moraes on 13 Sep 2011 at 4:04

GoogleCodeExporter commented 9 years ago
I would prefer such a feature too, as it could be used for caching purposes. 
One could write memcached based pre and post hooks like:

1) pre-request: before patterns are compared, check for memcached entry with 
request.RawURL. If found, cached result would be sent back to client and 
processing would stop.
2) post-request: after template has been parsed, just before writing it to 
client, content can be stored in memcached.

Original comment by ztomic@gmail.com on 4 Dec 2011 at 1:13

GoogleCodeExporter commented 9 years ago
There's actually no need to add anything to Gorilla to support this. It's 
pretty easy to do just using the facilities of the net/http API

for example:

var router *mux.Router

func httpInterceptor(w http.RequestWriter, req *http.Request) {
    // do some stuff before... check redis, etc
    router.ServeHTTP(w, req)
    // do some stuff after... put things in to redis, etc
}

func main() {
    // set up your desired things on router here...

    http.HandleFunc("/", httpInterceptor)
}

you could even intercept the writes to the ResponseWriter by passing mux's 
ServeHTTP your own type that implements the ResponseWriter interface.

Original comment by kamil.ki...@gmail.com on 18 Sep 2012 at 1:01

GoogleCodeExporter commented 9 years ago
Super late to the party here, but if anyone else stumbles across this problem - 
check out https://github.com/jadekler/git-go-websiteskeleton for a full 
implementation of kamil's suggestion.

Original comment by jadek...@gmail.com on 26 Apr 2014 at 9:48