Skip to content

Commit

Permalink
📱 Get remoteAddress from Forwarded header
Browse files Browse the repository at this point in the history
  • Loading branch information
jysperm committed Apr 24, 2020
1 parent b9811c9 commit a100dda
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 3 deletions.
33 changes: 32 additions & 1 deletion lib/utils.js
@@ -1,6 +1,9 @@
'use strict';

var crypto = require('crypto');
var parseForwarded = require('forwarded-parse');
var ipaddr = require('ipaddr.js');
var _ = require('underscore');

exports.hookNameMapping = {
beforeSave: '__before_save_for_',
Expand Down Expand Up @@ -70,9 +73,37 @@ exports.prepareResponseObject = function(res, callback) {
};

var getRemoteAddress = exports.getRemoteAddress = function(req) {
return req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress
var forwardedClient = exports.getForwardedClient(req)

if (forwardedClient) {
return forwardedClient.for
} else {
return req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress
}
};

exports.endsWith = function(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
};

exports.getForwardedClient = function getForwardedClient(req) {
if (req.headers['forwarded']) {
try {
const forwards = parseForwarded(req.headers['forwarded']).reverse()

for (var i = 0; i < forwards.length; i++) {
if (!forwards[i].for) {
return
}

var range = ipaddr.parse(forwards[i].for).range()

if (!_.include(['loopback', 'private'], range) || i === forwards.length - 1) {
return _.extend(forwards[i], {range: range})
}
}
} catch (err) {
console.error('LeanEngine: parse Forwarded header failed', req.headers['forwarded'], err.stack)
}
}
}
8 changes: 6 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -12,6 +12,8 @@
"connect-timeout": "^1.8.0",
"cookies": "^0.6.2",
"debug": "^2.6.0",
"forwarded-parse": "^2.1.0",
"ipaddr.js": "^1.9.1",
"leancloud-cors-headers": "^0.1.0",
"on-headers": "^1.0.1",
"underscore": "^1.8.3"
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/functions.js
Expand Up @@ -231,6 +231,10 @@ AV.Cloud.define('testTimeout', function(req, res) {
}, req.params.delay);
});

AV.Cloud.define('remoteAddress', function(request) {
return request.meta.remoteAddress
})

AV.Cloud.onIMMessageReceived(function(request, response) {
response.success('ok');
});
25 changes: 25 additions & 0 deletions test/function-test.js
Expand Up @@ -452,6 +452,31 @@ describe('functions', function() {
});
});

it('remoteAddress', function(done) {
request(app)
.post('/1.1/functions/remoteAddress')
.set('X-AVOSCloud-Application-Id', appId)
.set('X-AVOSCloud-Application-Key', appKey)
.set('Forwarded', 'for=1.2.3.4; proto=https, for=10.0.0.1')
.expect(200, (err, res) => {
res.body.result.should.equal('1.2.3.4')
done(err)
});
})

it('remoteAddress invalid Forwarded header', function(done) {
request(app)
.post('/1.1/functions/remoteAddress')
.set('X-AVOSCloud-Application-Id', appId)
.set('X-AVOSCloud-Application-Key', appKey)
.set('Forwarded', 'for=1.2.3.456; proto=https, for=10.0.0.1')
.set('X-Real-IP', '5.6.7.8')
.expect(200, (err, res) => {
res.body.result.should.equal('5.6.7.8')
done(err)
});
})

it('_metadatas', function(done) {
request(app)
.get('/1/functions/_ops/metadatas')
Expand Down

0 comments on commit a100dda

Please sign in to comment.