Skip to content

Commit c9055b6

Browse files
committed
Fix inheritance should not overwrite the methods of http.ServerResponse and http.IncomingMessage
1 parent a46cfdc commit c9055b6

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

lib/application.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ var resolve = require('path').resolve;
2626
var once = require('once')
2727
var Router = require('router');
2828
var setPrototypeOf = require('setprototypeof')
29+
var resProto = require('./response')
30+
var reqProto = require('./request')
2931

3032
/**
3133
* Module variables.
@@ -48,6 +50,35 @@ var app = exports = module.exports = {};
4850

4951
var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default';
5052

53+
function setPrototypeUntil(obj, proto, until) {
54+
var currentProto = proto;
55+
until = until || proto;
56+
var last = Object.getPrototypeOf(until);
57+
while (currentProto && currentProto !== last) {
58+
Object.keys(currentProto).forEach((key) => {
59+
setPrototypeKey(obj, proto, key, until)
60+
});
61+
currentProto = Object.getPrototypeOf(currentProto)
62+
}
63+
}
64+
65+
function setPrototypeKey(obj, proto, key, until) {
66+
Object.defineProperty(obj, key, {
67+
configurable: true,
68+
enumerable: proto.propertyIsEnumerable(key),
69+
get: () => {
70+
var desc = Object.getOwnPropertyDescriptor(until, key)
71+
if (desc && typeof desc.get === 'function') {
72+
// property defined with defineGetter, we need to change the `this` of the getter accordingly
73+
return desc.get.call(obj)
74+
}
75+
return proto[key]
76+
},
77+
set: (v) => {
78+
proto[key] = v
79+
}
80+
})
81+
}
5182
/**
5283
* Initialize the server.
5384
*
@@ -168,8 +199,8 @@ app.handle = function handle(req, res, callback) {
168199
res.req = req;
169200

170201
// alter the prototypes
171-
setPrototypeOf(req, this.request)
172-
setPrototypeOf(res, this.response)
202+
setPrototypeUntil(req, this.request, reqProto)
203+
setPrototypeUntil(res, this.response, resProto)
173204

174205
// setup locals
175206
if (!res.locals) {
@@ -232,8 +263,8 @@ app.use = function use(fn) {
232263
router.use(path, function mounted_app(req, res, next) {
233264
var orig = req.app;
234265
fn.handle(req, res, function (err) {
235-
setPrototypeOf(req, orig.request)
236-
setPrototypeOf(res, orig.response)
266+
setPrototypeUntil(req, orig.request)
267+
setPrototypeUntil(res, orig.response)
237268
next(err);
238269
});
239270
});

0 commit comments

Comments
 (0)