diff --git a/pkg/api/ipaddr.go b/pkg/api/ipaddr.go new file mode 100644 index 000000000..05b3b113d --- /dev/null +++ b/pkg/api/ipaddr.go @@ -0,0 +1,29 @@ +package api + +import ( + "context" + "net/http" +) + +// Key to use when setting the request ID. +type ctxKeyRemoteAddr int + +// RemoteAddrKey is the key that holds th unique request ID in a request context. +const remoteAddrKey ctxKeyRemoteAddr = 0 + +// Packs remote address to context +func remoteAddrToContext(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + next.ServeHTTP(w, req.WithContext(context.WithValue(req.Context(), remoteAddrKey, req.RemoteAddr))) + }) +} + +// RemoteAddrFromContext returns remote IP address from context +func RemoteAddrFromContext(ctx context.Context) string { + v := ctx.Value(remoteAddrKey) + if str, ok := v.(string); ok { + return str + } + + return "" +} diff --git a/pkg/api/logger.go b/pkg/api/logger.go index b9cd727cd..692e0c069 100644 --- a/pkg/api/logger.go +++ b/pkg/api/logger.go @@ -14,7 +14,7 @@ import ( // contextLogger middleware binds logger to request's context. // // This allows us to use logger from context (with requestID) -// inside our (generated) handers and controllers +// inside our (generated) handlers and controllers func contextLogger(log *zap.Logger) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { diff --git a/pkg/api/middleware.go b/pkg/api/middleware.go index 73f8b6557..9b3f2471f 100644 --- a/pkg/api/middleware.go +++ b/pkg/api/middleware.go @@ -17,6 +17,7 @@ func BaseMiddleware(log *zap.Logger) []func(http.Handler) http.Handler { return []func(http.Handler) http.Handler{ handleCORS, middleware.RealIP, + remoteAddrToContext, middleware.RequestID, contextLogger(log), }