Skip to content

Commit a9899cb

Browse files
authored
fix: restore express prototypes so injecting doesn't break http requests (#333)
Signed-off-by: Niall Molloy <[email protected]>
1 parent ba84352 commit a9899cb

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

index.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,21 @@ function doInject (dispatchFunc, options, callback) {
7474

7575
// Express.js detection
7676
if (dispatchFunc.request && dispatchFunc.request.app === dispatchFunc) {
77-
Object.setPrototypeOf(Object.getPrototypeOf(dispatchFunc.request), RequestConstructor.prototype)
78-
Object.setPrototypeOf(Object.getPrototypeOf(dispatchFunc.response), Response.prototype)
77+
const reqProto = Object.getPrototypeOf(dispatchFunc.request)
78+
const resProto = Object.getPrototypeOf(dispatchFunc.response)
79+
const reqExpressProto = Object.getPrototypeOf(reqProto)
80+
const resExpressProto = Object.getPrototypeOf(resProto)
81+
Object.setPrototypeOf(reqProto, RequestConstructor.prototype)
82+
Object.setPrototypeOf(resProto, Response.prototype)
83+
84+
// Restore original express prototypes after dispatch is called
85+
const distpach = dispatchFunc
86+
dispatchFunc = function (req, res) {
87+
const result = distpach.call(this, req, res)
88+
Object.setPrototypeOf(reqProto, reqExpressProto)
89+
Object.setPrototypeOf(resProto, resExpressProto)
90+
return result
91+
}
7992
}
8093

8194
if (typeof callback === 'function') {

test/index.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,36 @@ test("passes payload when using express' send", (t, done) => {
21292129
})
21302130
})
21312131

2132+
test('can both inject and make HTTP requests with express', (t, done) => {
2133+
t.plan(5)
2134+
2135+
const app = express()
2136+
2137+
app.get('/hello', (_req, res) => {
2138+
res.send('some text')
2139+
})
2140+
2141+
const server = app.listen()
2142+
t.after(() => server.close())
2143+
2144+
inject(app, { method: 'GET', url: 'http://example.com:8080/hello' }, (err, res) => {
2145+
t.assert.ifError(err)
2146+
t.assert.strictEqual(res.headers['content-length'], '9')
2147+
t.assert.strictEqual(res.payload, 'some text')
2148+
2149+
fetch(`http://localhost:${server.address().port}/hello`)
2150+
.then((res) => {
2151+
t.assert.strictEqual(res.headers.get('content-length'), '9')
2152+
return res.text()
2153+
})
2154+
.then(body => {
2155+
t.assert.strictEqual(body, 'some text')
2156+
done()
2157+
})
2158+
.catch((err) => done(err))
2159+
})
2160+
})
2161+
21322162
test('request that is destroyed errors', (t, done) => {
21332163
t.plan(2)
21342164
const dispatch = function (req, res) {

0 commit comments

Comments
 (0)