@@ -18,6 +18,7 @@ export default defineEventHandler((event) => {
1818 try {
1919 const target = joinURL ( options . apiHost , 'api/event' )
2020 const clientIP = resolveClientIP ( event )
21+
2122 return proxyRequest ( event , target , {
2223 headers : {
2324 ...( clientIP ? { 'X-Forwarded-For' : clientIP } : { } ) ,
@@ -35,25 +36,11 @@ export default defineEventHandler((event) => {
3536} )
3637
3738/**
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.
39+ * Reads `x-forwarded-for` before falling back to `getRequestIP`, because
40+ * H3 v1 checks `event.context.clientAddress` first – which may resolve to
41+ * an internal IP (e.g. Docker network) instead of the real client IP.
4442 */
4543function resolveClientIP ( event : H3Event ) {
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)
5744 const xForwardedFor = getRequestHeader ( event , 'x-forwarded-for' )
5845 if ( xForwardedFor ) {
5946 const firstIp = xForwardedFor . split ( ',' ) [ 0 ] ?. trim ( )
0 commit comments