From 54e58d352311ef49147bcc7844f98078c6e76368 Mon Sep 17 00:00:00 2001 From: PlasmaPower Date: Sun, 3 Apr 2016 20:30:06 -0600 Subject: [PATCH] req: Cache the request IP --- lib/application.js | 1 + lib/request.js | 13 ------------- test/helpers/context.js | 16 ++++++++-------- test/request/ip.js | 37 +++++++++++++++++++++++++++---------- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/lib/application.js b/lib/application.js index 83b607f..551bfab 100644 --- a/lib/application.js +++ b/lib/application.js @@ -158,6 +158,7 @@ module.exports = class Application extends Emitter { keys: this.keys, secure: request.secure }); + request.ip = request.ips[0] || req.socket.remoteAddress || ''; context.accept = request.accept = accepts(req); context.state = {}; return context; diff --git a/lib/request.js b/lib/request.js index e2dbc71..f98941a 100644 --- a/lib/request.js +++ b/lib/request.js @@ -366,19 +366,6 @@ module.exports = { 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 * the "X-Forwarded-For" ip address list. diff --git a/test/helpers/context.js b/test/helpers/context.js index 53e8737..ff54086 100644 --- a/test/helpers/context.js +++ b/test/helpers/context.js @@ -4,18 +4,18 @@ const Stream = require('stream'); const Koa = require('../..'); -module.exports = (req, res) => { +module.exports = (req, res, app) => { const socket = new Stream.Duplex(); - req = req || { headers: {}, socket: socket, __proto__: Stream.Readable.prototype }; - res = res || { _headers: {}, socket: socket, __proto__: Stream.Writable.prototype }; - req.socket = req.socket || socket; - res.socket = res.socket || socket; + req = Object.assign({ headers: {}, socket }, Stream.Readable.prototype, req); + res = Object.assign({ _headers: {}, socket }, Stream.Writable.prototype, res); + req.socket.remoteAddress = req.socket.remoteAddress || '127.0.0.1'; + app = app || new Koa(); res.getHeader = k => res._headers[k.toLowerCase()]; res.setHeader = (k, v) => res._headers[k.toLowerCase()] = v; 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; diff --git a/test/request/ip.js b/test/request/ip.js index 554c421..83f12f3 100644 --- a/test/request/ip.js +++ b/test/request/ip.js @@ -1,32 +1,49 @@ '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('with req.ips present', () => { it('should return req.ips[0]', () => { - const req = request(); - req.app.proxy = true; - req.header['x-forwarded-for'] = '127.0.0.1'; + const app = new Koa(); + const req = { headers: {}, socket: new Stream.Duplex() }; + app.proxy = true; + req.headers['x-forwarded-for'] = '127.0.0.1'; 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', () => { it('should return req.socket.remoteAddress', () => { - const req = request(); + const req = { socket: new Stream.Duplex() }; 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', () => { it('should return an empty string', () => { - const req = request(); - req.socket.remoteAddress = null; - req.ip.should.equal(''); + const socket = new Stream.Duplex(); + Object.defineProperty(socket, 'remoteAddress', { + 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'); + }); });