http: require json bodies to be an object.

This commit is contained in:
Christopher Jeffrey 2017-08-07 15:56:15 -07:00
parent e268e00adb
commit 7de854ce3f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 52 additions and 16 deletions

View File

@ -329,6 +329,8 @@ HTTPBase.prototype.parseBody = async function parseBody(req, options) {
switch (type) {
case 'json':
body = JSON.parse(data);
if (!body || typeof body !== 'object' || Array.isArray(body))
throw new Error('JSON body must be an object.');
break;
case 'form':
body = parsePairs(data, options.keyLimit);

View File

@ -202,16 +202,16 @@ RequestOptions.prototype.isExpected = function isExpected(type) {
return this.expect === type;
};
RequestOptions.prototype.isOverflow = function isOverflow(length) {
if (!length)
RequestOptions.prototype.isOverflow = function isOverflow(hdr) {
if (!hdr)
return false;
if (!this.buffer)
return false;
length = parseInt(length, 10);
const length = parseInt(hdr, 10);
if (length !== length)
if (!isFinite(length))
return true;
return length > this.limit;
@ -293,9 +293,10 @@ function Request(options) {
this.total = 0;
this.decoder = null;
this.body = null;
this.buffer = null;
}
Request.prototype.__proto__ = Stream.prototype;
Object.setPrototypeOf(Request.prototype, Stream.prototype);
Request.prototype.startTimeout = function startTimeout() {
if (!this.options.timeout)
@ -395,27 +396,58 @@ Request.prototype.finish = function finish(err) {
this.cleanup();
if (this.options.buffer && this.body) {
if (this.options.buffer) {
assert(this.buffer != null);
switch (this.type) {
case 'bin':
this.body = Buffer.concat(this.body);
case 'bin': {
this.body = Buffer.concat(this.buffer);
this.buffer = null;
break;
case 'json':
}
case 'json': {
const buffer = this.buffer.trim();
this.buffer = null;
if (buffer.length === 0)
break;
let body;
try {
this.body = JSON.parse(this.body);
body = JSON.parse(buffer);
} catch (e) {
this.emit('error', e);
return;
}
if (!body || typeof body !== 'object') {
this.emit('error', new Error('JSON body is a non-object.'));
return;
}
this.body = body;
break;
case 'form':
}
case 'form': {
const buffer = this.buffer;
this.buffer = null;
try {
this.body = qs.parse(this.body);
this.body = qs.parse(buffer);
} catch (e) {
this.emit('error', e);
return;
}
break;
}
default: {
this.body = this.buffer;
this.buffer = null;
break;
}
}
}
@ -469,9 +501,9 @@ Request.prototype._onResponse = function _onResponse(response) {
if (this.options.buffer) {
if (this.type !== 'bin') {
this.decoder = new StringDecoder('utf8');
this.body = '';
this.buffer = '';
} else {
this.body = [];
this.buffer = [];
}
}
};
@ -488,11 +520,13 @@ Request.prototype._onData = function _onData(data) {
return;
}
}
if (this.decoder) {
this.body += this.decoder.write(data);
this.buffer += this.decoder.write(data);
return;
}
this.body.push(data);
this.buffer.push(data);
}
};