Julien's dev blog

Gist: Go HTTP "True IP" middleware

Example of a simple HTTP "True IP" middleware implementation in Go.

Last updated on: 2024-12-29

This middleware adds the parsed IP address of the HTTP requests in its context.

package httpmux

import (
	"context"
	"net"
	"net/http"
)

type trueIPCtxType string

const trueIPCtxKey trueIPCtxType = "true-IP"

func WithTrueIP(ctx context.Context, v net.IP) context.Context {
	return context.WithValue(ctx, trueIPCtxKey, v)
}

func TrueIP(ctx context.Context) net.IP {
	v, ok := ctx.Value(trueIPCtxKey).(net.IP)
	if !ok {
		return nil
	}
	return v
}

func NewTrueIPMiddleware(trueIPHeader string) Middleware {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			remoteAddr := r.RemoteAddr
			if trueIPHeader != "" {
				remoteAddr = r.Header.Get(trueIPHeader)
			}
			host, _, _ := net.SplitHostPort(remoteAddr)
			if host == "" {
				host = remoteAddr
			}
			ipAddr := net.ParseIP(host)
			h.ServeHTTP(w, r.WithContext(WithTrueIP(r.Context(), ipAddr)))
		})
	}
}
Go code

To get the IP address from the request:

httpmux.TrueIP(r.Context())
Extract IP address from request context