Permalink
Browse files

Add utils.bufferStream

utils.bufferStream safely concatenates the contents of streams that
may contain multi-byte characters. All functions that need to buffer
the contents of a stream should use it.
  • Loading branch information...
1 parent 38cf901 commit 4b13827640a3970ab70b70d971b7e22546009c06 @mjackson committed Dec 22, 2012
Showing with 37 additions and 47 deletions.
  1. +5 −0 CHANGES
  2. +11 −29 lib/request.js
  3. +13 −0 lib/utils.js
  4. +3 −8 test/index-test.js
  5. +5 −10 test/mock-test.js
View
5 CHANGES
@@ -1,3 +1,8 @@
+= HEAD
+
+ * Added utils.bufferStream which safely concatenate the contents of streams
+ that may contain multi-byte characters.
+
= 0.19.3 / 2012-12-21
* Fixed a bug with decoding session cookies when they contained a double
View
40 lib/request.js
@@ -431,20 +431,15 @@ Request.prototype.body = function (callback) {
var input = env.input;
if (this.mediaType === 'application/json') {
- var buffer = '';
-
- input.on('data', function (chunk) {
- buffer += chunk.toString();
- });
-
- input.on('end', function () {
+ utils.bufferStream(input, function (err, buffer) {
try {
- var body = JSON.parse(buffer);
- env.strataBody = body;
- callback(null, body);
+ env.strataBody = JSON.parse(buffer.toString());
} catch (e) {
callback(new strata.Error('Invalid JSON', e), {});
+ return;
}
+
+ callback(err, env.strataBody);
});
} else if (this.parseableData) {
var contentType = this.contentType || '';
@@ -498,28 +493,15 @@ Request.prototype.body = function (callback) {
}
});
} else {
- var buffer = '';
-
- input.on('data', function (chunk) {
- buffer += chunk.toString('utf8');
- });
-
- input.on('end', function () {
- var body = qs.parse(buffer);
- env.strataBody = body;
- callback(null, body);
+ utils.bufferStream(input, function (err, buffer) {
+ env.strataBody = qs.parse(buffer.toString());
+ callback(err, env.strataBody);
});
}
} else {
- var body = '';
-
- input.on('data', function (chunk) {
- body += chunk.toString();
- });
-
- input.on('end', function () {
- env.strataBody = body;
- callback(null, body);
+ utils.bufferStream(input, function (err, buffer) {
+ env.strataBody = buffer.toString();
+ callback(err, env.strataBody);
});
}
View
13 lib/utils.js
@@ -1,5 +1,18 @@
var http = require('http');
+exports.bufferStream = bufferStream;
+function bufferStream(stream, callback) {
+ var buffers = [];
+
+ stream.on('data', function (chunk) {
+ buffers.push(Buffer.isBuffer(chunk) ? chunk : new Buffer(chunk));
+ });
+
+ stream.on('end', function () {
+ callback(null, Buffer.concat(buffers));
+ });
+}
+
// A map of HTTP status codes to their messages.
var STATUS_CODES = {};
exports.STATUS_CODES = STATUS_CODES;
View
11 test/index-test.js
@@ -81,16 +81,11 @@ describe('strata', function () {
describe('when read', function () {
var input;
beforeEach(function (callback) {
- input = '';
-
env.input.resume();
- env.input.on('data', function (chunk) {
- input += chunk.toString();
- });
-
- env.input.on('end', function () {
- callback(null);
+ utils.bufferStream(env.input, function (err, buffer) {
+ input = buffer.toString();
+ callback(err);
});
});
View
15 test/mock-test.js
@@ -87,19 +87,14 @@ describe('mock', function () {
});
describe('when given a params object in a POST request', function () {
- var env, input;
+ var input;
beforeEach(function (callback) {
- env = mock.env({ requestMethod: 'POST', params: { a: 'a', b: 'b' } });
- input = '';
-
+ var env = mock.env({ requestMethod: 'POST', params: { a: 'a', b: 'b' } });
env.input.resume();
- env.input.on('data', function (chunk) {
- input += chunk.toString('utf8');
- });
-
- env.input.on('end', function () {
- callback(null);
+ utils.bufferStream(env.input, function (err, buffer) {
+ input = buffer.toString();
+ callback(err);
});
});

0 comments on commit 4b13827

Please sign in to comment.