Example #1
0
// EnvInit is a middleware that allocates an environment map if one does not
// already exist. This is necessary because Goji does not guarantee that Env is
// present when running middleware (it avoids forcing the map allocation). Note
// that other middleware should check Env for nil in order to maximize
// compatibility (when EnvInit is not used, or when another middleware layer
// blanks out Env), but for situations in which the user controls the middleware
// stack and knows EnvInit is present, this middleware can eliminate a lot of
// boilerplate.
func EnvInit(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			c.Env = make(map[string]interface{})
		}
		h.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}
Example #2
0
// RequestID is a middleware that injects a request ID into the context of each
// request. A request ID is a string of the form "host.example.com/random-0001",
// where "random" is a base62 random string that uniquely identifies this go
// process, and where the last number is an atomically incremented request
// counter.
func RequestID(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			c.Env = make(map[string]interface{})
		}
		myid := atomic.AddUint64(&reqid, 1)
		c.Env[RequestIDKey] = fmt.Sprintf("%s-%06d", prefix, myid)

		h.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}
Example #3
0
// RealIP is a middleware that sets a http.Request's RemoteAddr to the results
// of parsing either the X-Forwarded-For header or the X-Real-IP header (in that
// order). It places the original value of RemoteAddr in a context environment
// variable.
//
// This middleware should be inserted fairly early in the middleware stack to
// ensure that subsequent layers (e.g., request loggers) which examine the
// RemoteAddr will see the intended value.
//
// You should only use this middleware if you can trust the headers passed to
// you (in particular, the two headers this middleware uses), for example
// because you have placed a reverse proxy like HAProxy or nginx in front of
// Goji. If your reverse proxies are configured to pass along arbitrary header
// values from the client, or if you use this middleware without a reverse
// proxy, malicious clients will be able to make you very sad (or, depending on
// how you're using RemoteAddr, vulnerable to an attack of some sort).
func RealIP(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		if rip := realIP(r); rip != "" {
			if c.Env == nil {
				c.Env = make(map[string]interface{})
			}
			c.Env[OriginalRemoteAddrKey] = r.RemoteAddr
			r.RemoteAddr = rip
		}
		h.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}