Example #1
0
// WithAccessLog is a middleware that logs all access requests performed on the
// sub handler using github.com/corestoreio/csfw/net/ctxlog and
// github.com/rs/xstats stored in context.
func WithAccessLog() ctxhttp.Middleware {
	return func(h ctxhttp.HandlerFunc) ctxhttp.HandlerFunc {
		return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {

			// Time request
			reqStart := time.Now()

			// Sniff the status and content size for logging
			lw := mutil.WrapWriter(w)

			err := h.ServeHTTPContext(ctx, lw, r)

			// Compute request duration
			reqDur := time.Since(reqStart)

			// Get request status
			status := ResponseStatus(ctx, lw.Status())

			// Log request stats
			sts := xstats.FromContext(ctx)
			tags := []string{
				"status:" + status,
				"status_code:" + strconv.Itoa(lw.Status()),
			}
			sts.Timing("request_time", reqDur, tags...)
			sts.Histogram("request_size", float64(lw.BytesWritten()), tags...)

			ctxlog.FromContext(ctx).Info("request",
				"error", util.Errors(err),
				"method", r.Method,
				"uri", r.URL.String(),
				"type", "access",
				"status", status,
				"status_code", lw.Status(),
				"duration", reqDur.Seconds(),
				"size", lw.BytesWritten(),
				"remote_addr", httputil.GetRemoteAddr(r).String(),
				"user_agent", r.Header.Get("User-Agent"),
				"referer", r.Header.Get("Referer"),
			)
			return err
		}
	}
}
Example #2
0
// newContextCountryByIP searches the country for an IP address and puts the country
// into a new context.
func (s *Service) newContextCountryByIP(ctx context.Context, r *http.Request) (context.Context, *IPCountry, error) {

	remoteAddr := httputil.GetRemoteAddr(r)
	if remoteAddr == nil {
		if PkgLog.IsDebug() {
			PkgLog.Debug("geoip.WithCountryByIP.GetRemoteAddr", "err", ErrCannotGetRemoteAddr, "req", r)
		}
		return ctx, nil, ErrCannotGetRemoteAddr
	}

	c, err := s.GetCountryByIP(remoteAddr)
	if err != nil {
		if PkgLog.IsDebug() {
			PkgLog.Debug("geoip.WithCountryByIP.GetCountryByIP", "err", err, "remoteAddr", remoteAddr, "req", r)
		}
		return ctx, nil, errgo.Mask(err)
	}
	c.IP = remoteAddr
	return WithContextCountry(ctx, c), c, nil
}
Example #3
0
func TestGetRemoteAddr(t *testing.T) {
	tests := []struct {
		r      *http.Request
		wantIP net.IP
	}{
		{func() *http.Request {
			r, err := http.NewRequest("GET", "http://gopher.go", nil)
			assert.NoError(t, err)
			r.Header.Set("X-Real-IP", "123.123.123.123")
			return r
		}(), net.ParseIP("123.123.123.123")},
		{func() *http.Request {
			r, err := http.NewRequest("GET", "http://gopher.go", nil)
			assert.NoError(t, err)
			r.Header.Set("X-Forwarded-For", "200.100.50.3")
			return r
		}(), net.ParseIP("200.100.50.3")},
		{func() *http.Request {
			r, err := http.NewRequest("GET", "http://gopher.go", nil)
			assert.NoError(t, err)
			r.RemoteAddr = "100.200.50.3"
			return r
		}(), net.ParseIP("100.200.50.3")},
		{func() *http.Request {
			r, err := http.NewRequest("GET", "http://gopher.go", nil)
			assert.NoError(t, err)
			r.RemoteAddr = "100.200.a.3"
			return r
		}(), nil},
	}

	for i, test := range tests {
		haveIP := httputil.GetRemoteAddr(test.r)
		assert.Exactly(t, test.wantIP, haveIP, "Index: %d", i)
	}
}