Skip to content

Commit 0d5bf43

Browse files
brandon-leapyearmonkpow
authored andcommitted
Explicitly check assumptions to avoid hanging on already read request
1 parent e1d0cd8 commit 0d5bf43

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

lib/requestOptions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ function bodyContent(req, res, options) {
9090
function maybeParseBody(req, limit) {
9191
if (req.body) {
9292
return Promise.resolve(req.body);
93+
} else if (!req.readable) {
94+
return Promise.reject(
95+
'Tried to parse body after request body has already been read.' +
96+
' Try setting parseReqBody to false and manually specify the body you want to send in decorateProxyReqBody.'
97+
);
9398
} else {
9499
// Returns a promise
95100

test/getBody.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,70 @@ describe('when proxy request is a GET', function () {
181181
.end(done);
182182
});
183183

184+
describe('when body-parser.json() is using strict=false', function () {
185+
beforeEach(function () {
186+
localServer = createLocalApplicationServer();
187+
localServer.use(bodyParser.json({ strict: false }));
188+
});
189+
190+
var testCases = [
191+
{ value: false },
192+
{ value: null },
193+
{ value: '' },
194+
];
195+
196+
testCases.forEach(function (test) {
197+
var valueString = JSON.stringify(test.value);
198+
199+
it('errors when body is ' + valueString, function (done) {
200+
localServer.use('/proxy', proxy('http://127.0.0.1:12345'));
201+
localServer.use(function (err, req, res, next) { res.send(err); next(); });
202+
203+
request(localServer)
204+
.get('/proxy')
205+
.send(valueString)
206+
.set('Content-Type', 'application/json')
207+
.expect(function (res) {
208+
assert(
209+
res.text === (
210+
'Tried to parse body after request body has already been read.' +
211+
' Try setting parseReqBody to false and manually specify the body' +
212+
' you want to send in decorateProxyReqBody.'
213+
)
214+
);
215+
})
216+
.end(done);
217+
});
218+
219+
it(
220+
'succeeds when parseReqBody=false and proxyReqBodyDecorator explicitly returns ' + valueString,
221+
function (done) {
222+
var scope = nock('http://127.0.0.1:12345')
223+
.get('/', valueString)
224+
.matchHeader('Content-Type', 'application/json')
225+
.reply(200, valueString, {
226+
'Content-Type': 'application/json',
227+
});
228+
229+
localServer.use('/proxy', proxy('http://127.0.0.1:12345', {
230+
parseReqBody: false,
231+
proxyReqBodyDecorator: function () {
232+
return valueString;
233+
},
234+
}));
235+
236+
request(localServer)
237+
.get('/proxy')
238+
.send(valueString)
239+
.set('Content-Type', 'application/json')
240+
.expect(function (res) {
241+
assert(res.body === test.value);
242+
scope.done();
243+
})
244+
.end(done);
245+
}
246+
);
247+
});
248+
});
249+
184250
});

test/postBody.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,70 @@ describe('when proxy request is a POST', function () {
154154
.end(done);
155155
});
156156

157+
describe('when body-parser.json() is using strict=false', function () {
158+
beforeEach(function () {
159+
localServer = createLocalApplicationServer();
160+
localServer.use(bodyParser.json({ strict: false }));
161+
});
162+
163+
var testCases = [
164+
{ value: false },
165+
{ value: null },
166+
{ value: '' },
167+
];
168+
169+
testCases.forEach(function (test) {
170+
var valueString = JSON.stringify(test.value);
171+
172+
it('errors when body is ' + valueString, function (done) {
173+
localServer.use('/proxy', proxy('http://127.0.0.1:12345'));
174+
localServer.use(function (err, req, res, next) { res.send(err); next(); });
175+
176+
request(localServer)
177+
.post('/proxy')
178+
.send(valueString)
179+
.set('Content-Type', 'application/json')
180+
.expect(function (res) {
181+
assert(
182+
res.text === (
183+
'Tried to parse body after request body has already been read.' +
184+
' Try setting parseReqBody to false and manually specify the body' +
185+
' you want to send in decorateProxyReqBody.'
186+
)
187+
);
188+
})
189+
.end(done);
190+
});
191+
192+
it(
193+
'succeeds when parseReqBody=false and proxyReqBodyDecorator explicitly returns ' + valueString,
194+
function (done) {
195+
var scope = nock('http://127.0.0.1:12345')
196+
.post('/', valueString)
197+
.matchHeader('Content-Type', 'application/json')
198+
.reply(200, valueString, {
199+
'Content-Type': 'application/json',
200+
});
201+
202+
localServer.use('/proxy', proxy('http://127.0.0.1:12345', {
203+
parseReqBody: false,
204+
proxyReqBodyDecorator: function () {
205+
return valueString;
206+
},
207+
}));
208+
209+
request(localServer)
210+
.post('/proxy')
211+
.send(valueString)
212+
.set('Content-Type', 'application/json')
213+
.expect(function (res) {
214+
assert(res.body === test.value);
215+
scope.done();
216+
})
217+
.end(done);
218+
}
219+
);
220+
});
221+
});
222+
157223
});

0 commit comments

Comments
 (0)