Skip to content
This repository was archived by the owner on Aug 10, 2023. It is now read-only.

Commit 6c76a36

Browse files
committed
Merge pull request #7 from restify/rawBody
GH-6: exposes rawBody for all body parser plugins
2 parents 21efc46 + d634732 commit 6c76a36

10 files changed

Lines changed: 130 additions & 17 deletions

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ language: node_js
33
node_js:
44
- "0.10"
55
- "0.12"
6+
- "4"
67
notifications:
78
webhooks:
89
urls:

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 1.x.x
2+
3+
* NEW: `bodyParser` plugin now saves the raw unparsed body on req.rawBody

lib/plugins/bodyReader.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var errors = require('restify-errors');
1313

1414
var BadDigestError = errors.BadDigestError;
1515
var RequestEntityTooLargeError = errors.RequestEntityTooLargeError;
16+
var PayloadTooLargeError = errors.PayloadTooLargeError;
1617

1718
var MD5_MSG = 'Content-MD5 \'%s\' didn\'t match \'%s\'';
1819

@@ -55,7 +56,7 @@ function createBodyWriter(req) {
5556
* reads the body of the request.
5657
* @public
5758
* @function bodyReader
58-
* @throws {BadDigestError | RequestEntityTooLargeError}
59+
* @throws {BadDigestError | PayloadTooLargeError}
5960
* @param {Object} options an options object
6061
* @returns {Function}
6162
*/
@@ -88,9 +89,19 @@ function bodyReader(options) {
8889
bodyWriter.end();
8990

9091
if (maxBodySize && bytesReceived > maxBodySize) {
91-
var msg = 'Request body size exceeds ' +
92-
maxBodySize;
93-
next(new RequestEntityTooLargeError(msg));
92+
var msg = 'Request body size exceeds ' + maxBodySize;
93+
var err;
94+
95+
// Between Node 0.12 and 4 http status code messages changed
96+
// RequestEntityTooLarge was changed to PayloadTooLarge
97+
// this check is to maintain backwards compatibility
98+
if (PayloadTooLargeError !== undefined) {
99+
err = new PayloadTooLargeError(msg);
100+
} else {
101+
err = new RequestEntityTooLargeError(msg);
102+
}
103+
104+
next(err);
94105
return;
95106
}
96107

lib/plugins/fieldedTextBodyParser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ function fieldedTextParser(options) {
2323

2424
function parseFieldedText(req, res, next) {
2525

26+
// save original body on req.rawBody and req._body
27+
req.rawBody = req._body = req.body;
28+
2629
var contentType = req.getContentType();
2730

2831
if (contentType !== 'text/csv' &&

lib/plugins/formBodyParser.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ function urlEncodedBodyParser(options) {
3535
var override = opts.overrideParams;
3636

3737
function parseUrlEncodedBody(req, res, next) {
38+
// save original body on req.rawBody and req._body
39+
req.rawBody = req._body = req.body;
40+
3841
if (req.getContentType() !== MIME_TYPE || !req.body) {
3942
next();
4043
return;
@@ -55,8 +58,6 @@ function urlEncodedBodyParser(options) {
5558
});
5659
}
5760

58-
// always save the parsed params to body
59-
req.rawBody = req._body = req.body;
6061
req.body = params;
6162
} catch (e) {
6263
next(new errors.InvalidContentError(e.message));

lib/plugins/jsonBodyParser.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ function jsonBodyParser(options) {
2525
var override = opts.overrideParams;
2626

2727
function parseJson(req, res, next) {
28+
// save original body on req.rawBody and req._body
29+
req.rawBody = req._body = req.body;
30+
2831
if (req.getContentType() !== 'application/json' || !req.body) {
2932
return next();
3033
}
@@ -64,8 +67,6 @@ function jsonBodyParser(options) {
6467
// otherwise, do a wholesale stomp, no need to merge one by one.
6568
req.params = params || req.params;
6669
}
67-
} else {
68-
req._body = req.body;
6970
}
7071

7172
req.body = params;

lib/plugins/multipartBodyParser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ function multipartBodyParser(options) {
4545
var override = opts.overrideParams;
4646

4747
function parseMultipartBody(req, res, originalNext) {
48+
// save original body on req.rawBody and req._body
49+
req.rawBody = req._body = undefined;
50+
4851
var next = once(originalNext);
4952

5053
if (req.getContentType() !== 'multipart/form-data' ||

test/fieldedTextParser.test.js

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,12 @@ var OBJECT_TSV = require(path.join(__dirname, '/files/object-tsv.json'));
3434

3535
describe('fielded text parser', function () {
3636

37-
before(function (done) {
37+
beforeEach(function (done) {
3838
SERVER = restify.createServer({
3939
dtrace: helper.dtrace,
4040
log: helper.getLog('server')
4141
});
4242
SERVER.use(plugins.bodyParser());
43-
SERVER.post('/data', function respond(req, res, next) {
44-
res.send({
45-
status: 'okay',
46-
parsedReq: req.body
47-
});
48-
return next();
49-
});
5043
SERVER.listen(PORT, '127.0.0.1', function () {
5144
CLIENT = restifyClients.createClient({
5245
url: 'http://127.0.0.1:' + PORT,
@@ -57,7 +50,7 @@ describe('fielded text parser', function () {
5750
});
5851
});
5952

60-
after(function (done) {
53+
afterEach(function (done) {
6154
CLIENT.close();
6255
SERVER.close(done);
6356
});
@@ -70,6 +63,15 @@ describe('fielded text parser', function () {
7063
'Content-Type': 'text/csv'
7164
}
7265
};
66+
67+
SERVER.post('/data', function respond(req, res, next) {
68+
res.send({
69+
status: 'okay',
70+
parsedReq: req.body
71+
});
72+
return next();
73+
});
74+
7375
CLIENT.post(options, function (err, req) {
7476
assert.ifError(err);
7577
req.on('result', function (errReq, res) {
@@ -99,6 +101,15 @@ describe('fielded text parser', function () {
99101
'Content-Type': 'text/tsv'
100102
}
101103
};
104+
105+
SERVER.post('/data', function respond(req, res, next) {
106+
res.send({
107+
status: 'okay',
108+
parsedReq: req.body
109+
});
110+
return next();
111+
});
112+
102113
CLIENT.post(options, function (err, req) {
103114
assert.ifError(err);
104115
req.on('result', function (errReq, res) {
@@ -121,5 +132,35 @@ describe('fielded text parser', function () {
121132
});
122133
});
123134

135+
it('plugins-GH-6: should expose rawBody on request', function (done) {
136+
var options = {
137+
path: '/data',
138+
headers: {
139+
'Content-Type': 'text/csv'
140+
}
141+
};
142+
143+
SERVER.post('/data', function respond(req, res, next) {
144+
assert.ok(req.rawBody);
145+
res.send();
146+
return next();
147+
});
148+
149+
CLIENT.post(options, function (err, req) {
150+
assert.ifError(err);
151+
req.on('result', function (errReq, res) {
152+
assert.ifError(errReq);
153+
res.body = '';
154+
res.setEncoding('utf8');
155+
res.on('data', function (chunk) {
156+
res.body += chunk;
157+
});
158+
res.on('end', done);
159+
});
160+
req.write(DATA_TSV);
161+
req.end();
162+
});
163+
});
164+
124165
});
125166

test/formBodyParser.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,34 @@ describe('form body parser', function () {
248248
client.end();
249249
});
250250

251+
it('plugins-GH-6: should expose rawBody', function (done) {
252+
253+
var input = 'name[first]=alex&name[last]=liu';
254+
255+
SERVER.use(plugins.bodyParser());
256+
257+
SERVER.post('/bodyurl2/:id', function (req, res, next) {
258+
assert.equal(req.rawBody, input);
259+
res.send();
260+
next();
261+
});
262+
263+
var opts = {
264+
hostname: '127.0.0.1',
265+
port: PORT,
266+
path: '/bodyurl2/foo',
267+
agent: false,
268+
method: 'POST',
269+
headers: {
270+
'Content-Type': 'application/x-www-form-urlencoded'
271+
}
272+
};
273+
var client = http.request(opts, function (res) {
274+
assert.equal(res.statusCode, 200);
275+
done();
276+
});
277+
client.write(input);
278+
client.end();
279+
});
251280
});
252281

test/jsonBodyParser.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,26 @@ describe('JSON body parser', function () {
414414
client.end();
415415
});
416416

417+
418+
it('plugins-GH-6: should expose rawBody', function (done) {
419+
420+
var payload = {
421+
id: 'bar',
422+
name: 'alex'
423+
};
424+
425+
SERVER.use(plugins.jsonBodyParser());
426+
427+
SERVER.post('/body/:id', function (req, res, next) {
428+
assert.equal(req.rawBody, JSON.stringify(payload));
429+
assert.equal(req.body.id, 'bar');
430+
assert.equal(req.body.name, 'alex');
431+
res.send();
432+
next();
433+
});
434+
435+
CLIENT.post('/body/foo', payload, done);
436+
});
417437
});
418438

419439

0 commit comments

Comments
 (0)