X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fdingus.js;h=1098ea7dc54041f57a6987bfad6b9560a149ae94;hb=4ec136ae8257a1a9f40d83ad61c57954226e79e0;hp=84c1d14b6a38e4d9050e76eaf7095588f501196d;hpb=93ad1b3d6b0fbe384f8f8fcd7c09d285060fa65f;p=squeep-api-dingus diff --git a/lib/dingus.js b/lib/dingus.js index 84c1d14..1098ea7 100644 --- a/lib/dingus.js +++ b/lib/dingus.js @@ -226,11 +226,13 @@ class Dingus { /** * Intercept writes for head requests, do not send to client, * but send length, and make body available in context. + * N.B. If persisted, ctx.responseBody will be a raw buffer, be aware when logging. * @param {http.ClientRequest} req * @param {http.ServerResponse} res * @param {object} ctx + * @param {Boolean} persistResponseBody */ - static setHeadHandler(req, res, ctx) { + static setHeadHandler(req, res, ctx, persistResponseBody = false) { if (req.method === 'HEAD') { const origEnd = res.end.bind(res); const chunks = []; @@ -240,8 +242,11 @@ class Dingus { }; res.end = function (data, encoding, ...rest) { Dingus.pushBufChunk(chunks, data, encoding); - ctx.responseBody = Buffer.concat(chunks); - res.setHeader(Enum.Header.ContentLength, Buffer.byteLength(ctx.responseBody)); + const responseBody = Buffer.concat(chunks); + res.setHeader(Enum.Header.ContentLength, Buffer.byteLength(responseBody)); + if (persistResponseBody) { + ctx.responseBody = responseBody; + } return origEnd(undefined, encoding, ...rest); }; } @@ -337,12 +342,21 @@ class Dingus { /** * Return all body data from a request. * @param {http.ClientRequest} req + * @param {Number=} maximumBodySize */ - async bodyData(req) { + async bodyData(req, maximumBodySize) { const _scope = _fileScope('bodyData'); return new Promise((resolve, reject) => { const body = []; - req.on('data', (chunk) => body.push(chunk)); + let length = 0; + req.on('data', (chunk) => { + body.push(chunk); + length += Buffer.byteLength(chunk); + if (maximumBodySize && length > maximumBodySize) { + this.logger.debug(_scope, 'body data exceeded limit', { length, maximumBodySize }); + reject(new ResponseError(Enum.ErrorResponse.RequestEntityTooLarge)); + } + }); req.on('end', () => resolve(Buffer.concat(body).toString())); req.on('error', (e) => { this.logger.error(_scope, 'failed', { error: e });