Skip to content

Commit c6f6bfa

Browse files
committed
Initial implementation; copy of express logic
0 parents  commit c6f6bfa

File tree

9 files changed

+227
-0
lines changed

9 files changed

+227
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test/
2+
.travis.yml

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: node_js
2+
node_js:
3+
- "0.8"
4+
- "0.10"
5+
- "0.11"
6+
matrix:
7+
allow_failures:
8+
- node_js: "0.11"
9+
fast_finish: true

History.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
HEAD
2+
====
3+
4+
* Initial release

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2014 Douglas Christopher Wilson
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# proxy-addr [![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr) [![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr)
2+
3+
Determine address of proxied request
4+
5+
## Install
6+
7+
npm install proxy-addr
8+
9+
## API
10+
11+
var proxyaddr = require('proxy-addr');
12+
13+
### proxyaddr(req)
14+
15+
Return the address of the request. This returns the furthest-away
16+
address.
17+
18+
### proxyaddr.all(req)
19+
20+
Return all the addresses of the request. This array is ordered from
21+
closest to furthest (i.e. `arr[0] === req.connection.remoteAddress`).
22+
23+
## License
24+
25+
[MIT](LICENSE)

index.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*!
2+
* proxy-addr
3+
* Copyright(c) 2014 Douglas Christopher Wilson
4+
* MIT Licensed
5+
*/
6+
7+
/**
8+
* Module exports.
9+
*/
10+
11+
module.exports = proxyaddr;
12+
module.exports.all = proxyaddrs;
13+
14+
/**
15+
* Determine IP of proxied request.
16+
*
17+
* @param {Object} request
18+
* @api public
19+
*/
20+
21+
function proxyaddr(req) {
22+
var addrs = proxyaddrs(req);
23+
24+
return addrs[addrs.length - 1];
25+
}
26+
27+
/**
28+
* Get all addresses in the request.
29+
*
30+
* @param {Object} request
31+
* @api public
32+
*/
33+
34+
function proxyaddrs(req) {
35+
if (!req) throw new TypeError('req argument is required');
36+
37+
var proxyAddrs = (req.headers['x-forwarded-for'] || '')
38+
.split(/ *, */)
39+
.filter(isTruthy)
40+
.reverse();
41+
var socketAddr = req.connection.remoteAddress;
42+
43+
return [socketAddr].concat(proxyAddrs);
44+
}
45+
46+
function isTruthy(val) {
47+
return Boolean(val);
48+
}

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "proxy-addr",
3+
"description": "Determine address of proxied request",
4+
"version": "0.0.0",
5+
"author": "Douglas Christopher Wilson <[email protected]>",
6+
"license": "MIT",
7+
"keywords": [
8+
"ip",
9+
"proxy",
10+
"x-forwarded-for"
11+
],
12+
"repository": {
13+
"type": "git",
14+
"url": "https://github.com/expressjs/proxy-ip.git"
15+
},
16+
"bugs": {
17+
"url": "https://github.com/expressjs/proxy-ip/issues"
18+
},
19+
"dependencies": {},
20+
"devDependencies": {
21+
"mocha": "~1.18.2",
22+
"should": "~3.3.1"
23+
},
24+
"engines": {
25+
"node": ">= 0.8.0"
26+
},
27+
"scripts": {
28+
"test": "mocha --reporter spec test/"
29+
}
30+
}

test/test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
var proxyaddr = require('..');
3+
var should = require('should');
4+
5+
describe('proxyaddr(req)', function () {
6+
describe('arguments', function () {
7+
describe('req', function () {
8+
it('should be required', function () {
9+
proxyaddr.bind().should.throw(/req.*required/);
10+
});
11+
});
12+
});
13+
14+
describe('with no headers', function () {
15+
it('should return socket address', function () {
16+
var req = createReq('127.0.0.1');
17+
proxyaddr(req).should.equal('127.0.0.1');
18+
});
19+
});
20+
21+
describe('with x-forwarded-for header', function () {
22+
describe('single', function () {
23+
it('should return x-forwarded-for', function () {
24+
var req = createReq('127.0.0.1', {
25+
'x-forwarded-for': '10.0.0.1'
26+
});
27+
proxyaddr(req).should.equal('10.0.0.1');
28+
});
29+
});
30+
31+
describe('multiple', function () {
32+
it('should return left-most', function () {
33+
var req = createReq('127.0.0.1', {
34+
'x-forwarded-for': '10.0.0.1, 10.0.0.2'
35+
});
36+
proxyaddr(req).should.equal('10.0.0.1');
37+
});
38+
});
39+
});
40+
});
41+
42+
describe('proxyaddr.all(req)', function () {
43+
describe('arguments', function () {
44+
describe('req', function () {
45+
it('should be required', function () {
46+
proxyaddr.all.bind().should.throw(/req.*required/);
47+
});
48+
});
49+
});
50+
51+
describe('with no headers', function () {
52+
it('should return socket address', function () {
53+
var req = createReq('127.0.0.1');
54+
proxyaddr.all(req).should.eql(['127.0.0.1']);
55+
});
56+
});
57+
58+
describe('with x-forwarded-for header', function () {
59+
describe('single', function () {
60+
it('should include x-forwarded-for', function () {
61+
var req = createReq('127.0.0.1', {
62+
'x-forwarded-for': '10.0.0.1'
63+
});
64+
proxyaddr.all(req).should.eql(['127.0.0.1', '10.0.0.1']);
65+
});
66+
});
67+
68+
describe('multiple', function () {
69+
it('should include x-forwarded-for', function () {
70+
var req = createReq('127.0.0.1', {
71+
'x-forwarded-for': '10.0.0.1, 10.0.0.2'
72+
});
73+
proxyaddr.all(req).should.eql(['127.0.0.1', '10.0.0.2', '10.0.0.1']);
74+
});
75+
});
76+
});
77+
});
78+
79+
function createReq(socketAddr, headers) {
80+
return {
81+
connection: {
82+
remoteAddress: socketAddr
83+
},
84+
headers: headers || {}
85+
};
86+
}

0 commit comments

Comments
 (0)