...

Source file src/goji.io/middleware.go

Documentation: goji.io

     1  package goji
     2  
     3  import "net/http"
     4  
     5  /*
     6  Use appends a middleware to the Mux's middleware stack.
     7  
     8  Middleware are composable pieces of functionality that augment http.Handlers.
     9  Common examples of middleware include request loggers, authentication checkers,
    10  and metrics gatherers.
    11  
    12  Middleware are evaluated in the reverse order in which they were added, but the
    13  resulting http.Handlers execute in "normal" order (i.e., the http.Handler
    14  returned by the first Middleware to be added gets called first).
    15  
    16  For instance, given middleware A, B, and C, added in that order, Goji will
    17  behave similarly to this snippet:
    18  
    19  	augmentedHandler := A(B(C(yourHandler)))
    20  	augmentedHandler.ServeHTTP(w, r)
    21  
    22  Assuming each of A, B, and C look something like this:
    23  
    24  	func A(inner http.Handler) http.Handler {
    25  		log.Print("A: called")
    26  		mw := func(w http.ResponseWriter, r *http.Request) {
    27  			log.Print("A: before")
    28  			inner.ServeHTTP(w, r)
    29  			log.Print("A: after")
    30  		}
    31  		return http.HandlerFunc(mw)
    32  	}
    33  
    34  we'd expect to see the following in the log:
    35  
    36  	C: called
    37  	B: called
    38  	A: called
    39  	---
    40  	A: before
    41  	B: before
    42  	C: before
    43  	yourHandler: called
    44  	C: after
    45  	B: after
    46  	A: after
    47  
    48  Note that augmentedHandler will called many times, producing the log output
    49  below the divider, while the outer middleware functions (the log output above
    50  the divider) will only be called a handful of times at application boot.
    51  
    52  Middleware in Goji is called after routing has been performed. Therefore it is
    53  possible to examine any routing information placed into the Request context by
    54  Patterns, or to view or modify the http.Handler that will be routed to.
    55  Middleware authors should read the documentation for the "middleware" subpackage
    56  for more information about how this is done.
    57  
    58  The http.Handler returned by the given middleware must be safe for concurrent
    59  use by multiple goroutines. It is not safe to concurrently register middleware
    60  from multiple goroutines, or to register middleware concurrently with requests.
    61  */
    62  func (m *Mux) Use(middleware func(http.Handler) http.Handler) {
    63  	m.middleware = append(m.middleware, middleware)
    64  	m.buildChain()
    65  }
    66  
    67  // Pre-compile a http.Handler for us to use during dispatch. Yes, this means
    68  // that adding middleware is quadratic, but it (a) happens during configuration
    69  // time, not at "runtime", and (b) n should ~always be small.
    70  func (m *Mux) buildChain() {
    71  	m.handler = dispatch{}
    72  	for i := len(m.middleware) - 1; i >= 0; i-- {
    73  		m.handler = m.middleware[i](m.handler)
    74  	}
    75  }
    76  

View as plain text