1+ import type { H3Event } from 'h3'
12import type { ModuleOptions } from '../../module'
23import { useRuntimeConfig } from '#imports'
3- import { createError , defineEventHandler , getRequestIP , proxyRequest } from 'h3'
4+ import { createError , defineEventHandler , getRequestHeader , getRequestIP , proxyRequest } from 'h3'
45import { joinURL } from 'ufo'
56
67export default defineEventHandler ( ( event ) => {
@@ -16,9 +17,10 @@ export default defineEventHandler((event) => {
1617
1718 try {
1819 const target = joinURL ( options . apiHost , 'api/event' )
20+ const clientIP = resolveClientIP ( event )
1921 return proxyRequest ( event , target , {
2022 headers : {
21- 'X-Forwarded-For' : getRequestIP ( event , { xForwardedFor : true } ) ,
23+ ... ( clientIP ? { 'X-Forwarded-For' : clientIP } : { } ) ,
2224 } ,
2325 } )
2426 }
@@ -31,3 +33,33 @@ export default defineEventHandler((event) => {
3133 } )
3234 }
3335} )
36+
37+ /**
38+ * Resolve the real client IP address from common reverse proxy and CDN headers.
39+ *
40+ * This reads headers directly instead of relying on `getRequestIP` alone,
41+ * because `getRequestIP` checks `event.context.clientAddress` first, which
42+ * may be set to an internal/proxy IP (e.g. Docker network IP) by the runtime,
43+ * causing the real client IP from proxy headers to be ignored.
44+ */
45+ function resolveClientIP ( event : H3Event ) : string | undefined {
46+ // Cloudflare
47+ const cfConnectingIp = getRequestHeader ( event , 'cf-connecting-ip' )
48+ if ( cfConnectingIp )
49+ return cfConnectingIp
50+
51+ // Common reverse proxy header (Nginx, etc.)
52+ const xRealIp = getRequestHeader ( event , 'x-real-ip' )
53+ if ( xRealIp )
54+ return xRealIp
55+
56+ // Standard proxy header (first IP is the original client)
57+ const xForwardedFor = getRequestHeader ( event , 'x-forwarded-for' )
58+ if ( xForwardedFor ) {
59+ const firstIp = xForwardedFor . split ( ',' ) [ 0 ] ?. trim ( )
60+ if ( firstIp )
61+ return firstIp
62+ }
63+
64+ return getRequestIP ( event )
65+ }
0 commit comments