diff --git a/src/index.js b/src/index.js index 95e854f..998b733 100644 --- a/src/index.js +++ b/src/index.js @@ -49,7 +49,7 @@ function getClientIp(req) { // Server is probably behind a proxy. if (req.headers) { - + // Standard headers used by Amazon EC2, Heroku, and others. if (is.ip(req.headers['x-client-ip'])) { return req.headers['x-client-ip']; @@ -101,6 +101,14 @@ function getClientIp(req) { if (is.ip(req.headers.forwarded)) { return req.headers.forwarded; } + + // Google Cloud App Engine + // https://cloud.google.com/appengine/docs/standard/go/reference/request-response-headers + + if (is.ip(req.headers['x-appengine-user-ip'])) { + return req.headers['x-appengine-user-ip']; + } + } // Remote address checks. diff --git a/test/index.js b/test/index.js index 63ce88b..026d079 100644 --- a/test/index.js +++ b/test/index.js @@ -519,3 +519,28 @@ test('android request to AWS EBS app (x-forwarded-for)', (t) => { }); }); }); + +test('request to Google Cloud App Engine (x-appengine-user-ip)', (t) => { + t.plan(1); + const wanted = '107.77.213.113'; + const options = { + url: '', + headers: { + host: '[redacted]', + 'x-appengine-user-ip': '107.77.213.113', + }, + }; + + const server = new ServerFactory(); + server.listen(0, serverInfo.host); + server.on('listening', () => { + options.url = `http://${serverInfo.host}:${server.address().port}`; + request(options, (error, response, found) => { + if (!error && response.statusCode === 200) { + // ip address should be equal to the first "x-appengine-user-ip" value + t.equal(found, wanted); + server.close(); + } + }); + }); +});