http: require json bodies to be an object.
This commit is contained in:
parent
e268e00adb
commit
7de854ce3f
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user