req: Cache the request IP
This commit is contained in:
parent
826ad83db6
commit
54e58d3523
4 changed files with 36 additions and 31 deletions
|
@ -158,6 +158,7 @@ module.exports = class Application extends Emitter {
|
||||||
keys: this.keys,
|
keys: this.keys,
|
||||||
secure: request.secure
|
secure: request.secure
|
||||||
});
|
});
|
||||||
|
request.ip = request.ips[0] || req.socket.remoteAddress || '';
|
||||||
context.accept = request.accept = accepts(req);
|
context.accept = request.accept = accepts(req);
|
||||||
context.state = {};
|
context.state = {};
|
||||||
return context;
|
return context;
|
||||||
|
|
|
@ -366,19 +366,6 @@ module.exports = {
|
||||||
return 'https' == this.protocol;
|
return 'https' == this.protocol;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the remote address, or when
|
|
||||||
* `app.proxy` is `true` return
|
|
||||||
* the upstream addr.
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
get ip() {
|
|
||||||
return this.ips[0] || this.socket.remoteAddress || '';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When `app.proxy` is `true`, parse
|
* When `app.proxy` is `true`, parse
|
||||||
* the "X-Forwarded-For" ip address list.
|
* the "X-Forwarded-For" ip address list.
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
const Stream = require('stream');
|
const Stream = require('stream');
|
||||||
const Koa = require('../..');
|
const Koa = require('../..');
|
||||||
|
|
||||||
module.exports = (req, res) => {
|
module.exports = (req, res, app) => {
|
||||||
const socket = new Stream.Duplex();
|
const socket = new Stream.Duplex();
|
||||||
req = req || { headers: {}, socket: socket, __proto__: Stream.Readable.prototype };
|
req = Object.assign({ headers: {}, socket }, Stream.Readable.prototype, req);
|
||||||
res = res || { _headers: {}, socket: socket, __proto__: Stream.Writable.prototype };
|
res = Object.assign({ _headers: {}, socket }, Stream.Writable.prototype, res);
|
||||||
req.socket = req.socket || socket;
|
req.socket.remoteAddress = req.socket.remoteAddress || '127.0.0.1';
|
||||||
res.socket = res.socket || socket;
|
app = app || new Koa();
|
||||||
res.getHeader = k => res._headers[k.toLowerCase()];
|
res.getHeader = k => res._headers[k.toLowerCase()];
|
||||||
res.setHeader = (k, v) => res._headers[k.toLowerCase()] = v;
|
res.setHeader = (k, v) => res._headers[k.toLowerCase()] = v;
|
||||||
res.removeHeader = (k, v) => delete res._headers[k.toLowerCase()];
|
res.removeHeader = (k, v) => delete res._headers[k.toLowerCase()];
|
||||||
return (new Koa()).createContext(req, res);
|
return app.createContext(req, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.request = (req, res) => module.exports(req, res).request;
|
module.exports.request = (req, res, app) => module.exports(req, res, app).request;
|
||||||
|
|
||||||
module.exports.response = (req, res) => module.exports(req, res).response;
|
module.exports.response = (req, res, app) => module.exports(req, res, app).response;
|
||||||
|
|
|
@ -1,32 +1,49 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const request = require('../helpers/context').request;
|
const assert = require('assert');
|
||||||
|
const Stream = require('stream');
|
||||||
|
const Koa = require('../..');
|
||||||
|
const Request = require('../helpers/context').request;
|
||||||
|
|
||||||
describe('req.ip', () => {
|
describe('req.ip', () => {
|
||||||
describe('with req.ips present', () => {
|
describe('with req.ips present', () => {
|
||||||
it('should return req.ips[0]', () => {
|
it('should return req.ips[0]', () => {
|
||||||
const req = request();
|
const app = new Koa();
|
||||||
req.app.proxy = true;
|
const req = { headers: {}, socket: new Stream.Duplex() };
|
||||||
req.header['x-forwarded-for'] = '127.0.0.1';
|
app.proxy = true;
|
||||||
|
req.headers['x-forwarded-for'] = '127.0.0.1';
|
||||||
req.socket.remoteAddress = '127.0.0.2';
|
req.socket.remoteAddress = '127.0.0.2';
|
||||||
req.ip.should.equal('127.0.0.1');
|
const request = Request(req, undefined, app);
|
||||||
|
request.ip.should.equal('127.0.0.1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with no req.ips present', () => {
|
describe('with no req.ips present', () => {
|
||||||
it('should return req.socket.remoteAddress', () => {
|
it('should return req.socket.remoteAddress', () => {
|
||||||
const req = request();
|
const req = { socket: new Stream.Duplex() };
|
||||||
req.socket.remoteAddress = '127.0.0.2';
|
req.socket.remoteAddress = '127.0.0.2';
|
||||||
req.ip.should.equal('127.0.0.2');
|
const request = Request(req);
|
||||||
|
request.ip.should.equal('127.0.0.2');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with req.socket.remoteAddress not present', () => {
|
describe('with req.socket.remoteAddress not present', () => {
|
||||||
it('should return an empty string', () => {
|
it('should return an empty string', () => {
|
||||||
const req = request();
|
const socket = new Stream.Duplex();
|
||||||
req.socket.remoteAddress = null;
|
Object.defineProperty(socket, 'remoteAddress', {
|
||||||
req.ip.should.equal('');
|
get: () => undefined, // So that the helper doesn't override it with a reasonable value
|
||||||
|
set: () => {}
|
||||||
|
});
|
||||||
|
assert.equal(Request({ socket }).ip, '');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be cached', () => {
|
||||||
|
const req = { socket: new Stream.Duplex() };
|
||||||
|
req.socket.remoteAddress = '127.0.0.2';
|
||||||
|
const request = Request(req);
|
||||||
|
req.socket.remoteAddress = '127.0.0.1';
|
||||||
|
request.ip.should.equal('127.0.0.2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue