From 5169db7b1d2c9979e534b2c27912f5be398bcbca Mon Sep 17 00:00:00 2001 From: William Blankenship Date: Mon, 19 Jun 2017 13:47:10 -0700 Subject: [PATCH] fix(audit): use public APIs for accessing response headers - `res._headers` has been deprecated and accessing it in `auditResponseSerializer` generates exception (RangeError: Maximum call stack size exceeded) - `res.getHeaders` returns an object that does not inherit from `Object`, so is unsuitable for use here - falls back to `res._headers` if public APIs (introduced in v7.7.0) do not exist - see https://nodejs.org/api/deprecations.html#deprecations_dep0066_outgoingmessage_headers_outgoingmessage_headernames - see https://nodejs.org/api/http.html#http_response_getheaders --- lib/plugins/audit.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/plugins/audit.js b/lib/plugins/audit.js index bda5b3a3d..5f347ccfb 100644 --- a/lib/plugins/audit.js +++ b/lib/plugins/audit.js @@ -7,6 +7,28 @@ var bunyan = require('bunyan'); var HttpError = require('restify-errors').HttpError; var VError = require('verror'); +/** + * Utility to get response headers from a given response. + * Manually generates a POJO from `res.getHeaderNames` and `res.getHeader`, + * if available, falling back to deprecated `res._headers`, otherwise. + * Intentionally does not use `res.getHeaders` to avoid deserialization + * issues with object returned by that method. + * @param {http.ServerResponse} res the OutgoingMessage + * @private + * @function getResponseHeaders + * @returns {object} map from header name to header value + * @see https://github.com/restify/node-restify/issues/1370 + */ +function getResponseHeaders(res) { + if (res.getHeaderNames && res.getHeader) { + return res.getHeaderNames().reduce(function (prev, curr) { + var header = {}; + header[curr] = res.getHeader(curr); + return Object.assign({}, prev, header); + }, {}); + } + return res._headers; +} ///--- API @@ -99,7 +121,7 @@ function auditLogger(opts) { return ({ statusCode: res.statusCode, - headers: res._headers, + headers: getResponseHeaders(res), trailer: res._trailer || false, body: body });