summaryrefslogtreecommitdiffstats
path: root/internal/ratelimit/interceptor.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ratelimit/interceptor.go')
-rw-r--r--internal/ratelimit/interceptor.go17
1 files changed, 10 insertions, 7 deletions
diff --git a/internal/ratelimit/interceptor.go b/internal/ratelimit/interceptor.go
index b27fe7e..57721a7 100644
--- a/internal/ratelimit/interceptor.go
+++ b/internal/ratelimit/interceptor.go
@@ -59,14 +59,11 @@ func getIdentifier(ctx context.Context) string {
59} 59}
60 60
61// getIPAddress extracts the client IP address from the context. 61// getIPAddress extracts the client IP address from the context.
62// When behind a reverse proxy, this checks X-Forwarded-For and X-Real-IP headers first
63// to get the real client IP, then falls back to peer info (which would be the proxy IP).
62func getIPAddress(ctx context.Context) string { 64func getIPAddress(ctx context.Context) string {
63 // Try to get from peer info 65 // Check proxy headers first (X-Forwarded-For, X-Real-IP)
64 p, ok := peer.FromContext(ctx) 66 // This is critical for rate limiting behind reverse proxies like Caddy/nginx
65 if ok && p.Addr != nil {
66 return p.Addr.String()
67 }
68
69 // Try to get from metadata (X-Forwarded-For header)
70 md, ok := metadata.FromIncomingContext(ctx) 67 md, ok := metadata.FromIncomingContext(ctx)
71 if ok { 68 if ok {
72 if xff := md.Get("x-forwarded-for"); len(xff) > 0 { 69 if xff := md.Get("x-forwarded-for"); len(xff) > 0 {
@@ -77,6 +74,12 @@ func getIPAddress(ctx context.Context) string {
77 } 74 }
78 } 75 }
79 76
77 // Fall back to peer info (direct connection or proxy IP)
78 p, ok := peer.FromContext(ctx)
79 if ok && p.Addr != nil {
80 return p.Addr.String()
81 }
82
80 return "unknown" 83 return "unknown"
81} 84}
82 85