connect-prism
Version:
Record, mock, and proxy HTTP traffic.
104 lines (88 loc) • 3.06 kB
JavaScript
var _ = require('lodash');
var fs = require('fs');
var zlib = require('zlib');
var Logger = require('../services/logger');
var Mock = require('./mock');
var PrismUtils = require('../services/prism-utils');
var MockFilenameGenerator = require('../services/mock-filename-generator');
function Record(logger, prismUtils, mockFilenameGenerator, mock) {
function uncompress(res, callback) {
var contentEncoding = res.headers['content-encoding'];
var contentType = res.headers['content-type'];
var stream = res;
if (contentEncoding === 'gzip') {
stream = zlib.createGunzip();
res.pipe(stream);
} else if (contentEncoding === 'deflate') {
stream = zlib.createInflate();
res.pipe(stream);
}
var chunks = [], buffer = '', encoding, isBase64 = false;
stream.on('data', function(data) {
chunks.push(data);
}).on('end', function() {
if (chunks.length > 0 && chunks[0] instanceof Buffer) {
buffer = Buffer.concat(chunks);
if (!_.includes(contentType, 'text') && !prismUtils.isJson(contentType)) {
encoding = 'base64';
isBase64 = true;
}
buffer = buffer.toString(encoding);
} else {
buffer = chunks.join('');
}
callback(res, buffer, isBase64);
}).on('error', function(e) {
logger.error('An error occurred during decompression: ' + e);
});
}
function serializeResponse(prism, req, res, data, isBase64) {
var response = {
requestUrl: prismUtils.filterUrl(prism.config, res.req.path),
contentType: res.headers['content-type'],
method: req.method,
statusCode: res.statusCode,
data: parseJsonResponse(res, data),
isBase64: isBase64
};
if ('location' in res.headers) {
response.location = res.headers['location'];
}
var configHeaders = prism.config.recordHeaders;
if( configHeaders ) {
if(Array.isArray(configHeaders)) {
response.headers = _.pick(res.headers, configHeaders.map(function(s){return s.toLowerCase()}));
} else {
response.headers = res.headers;
}
}
var path = mockFilenameGenerator.getMockPath(prism, req);
mock.save(response, path);
logger.verboseLog('Serialized response for ' + res.req.path + ' to ' + path);
}
function parseJsonResponse(res, data) {
var contentType = res.headers['content-type'];
if (prismUtils.isJson(contentType)) {
try {
return JSON.parse(data);
} catch (e) {
logger.verboseLog('Could not parse JSON for response of ' + res.req.path);
}
}
return data;
}
this.handleResponse = function(req, res, prism) {
uncompress(res, function(res, data, isBase64) {
var doRecord = true;
if (prism.config.shouldRecord) {
doRecord = prism.config.shouldRecord(req, res);
}
if (doRecord) {
serializeResponse(prism, req, res, data, isBase64);
logger.logSuccess('Recorded', res.req, prism);
}
});
};
}
module.exports = Record;
;